(DscDecoder): tweaked huffman decompression.

This commit is contained in:
morkt 2015-12-27 18:37:18 +04:00
parent ddbc68d941
commit 583b2f60b3

View File

@ -213,24 +213,23 @@ namespace GameRes.Formats.BGI
class HuffmanNode class HuffmanNode
{ {
public bool IsParent; public bool IsParent;
public uint Code; public int Code;
public uint LeftChildIndex; public int LeftChildIndex;
public uint RightChildIndex; public int RightChildIndex;
} }
static void CreateHuffmanTree (HuffmanNode[] hnodes, HuffmanCode[] hcode, int node_count) static void CreateHuffmanTree (HuffmanNode[] hnodes, HuffmanCode[] hcode, int node_count)
{ {
uint[,] nodes_index = new uint[2,512]; var nodes_index = new int[2,512];
uint next_node_index = 1; int next_node_index = 1;
int depth_nodes = 1; int depth_nodes = 1;
uint depth = 0; int depth = 0;
int switch_flag = 0; int child_index = 0;
nodes_index[0,0] = 0; nodes_index[0,0] = 0;
for (int n = 0; n < node_count; ) for (int n = 0; n < node_count; )
{ {
int huffman_nodes_index = switch_flag; int huffman_nodes_index = child_index;
switch_flag ^= 1; child_index ^= 1;
int child_index = switch_flag;
int depth_existed_nodes = 0; int depth_existed_nodes = 0;
while (n < hcode.Length && hcode[n].Depth == depth) while (n < hcode.Length && hcode[n].Depth == depth)
@ -252,13 +251,13 @@ namespace GameRes.Formats.BGI
} }
} }
uint HuffmanDecompress (HuffmanNode[] hnodes, uint dec_count) int HuffmanDecompress (HuffmanNode[] hnodes, uint dec_count)
{ {
uint dst_ptr = 0; int dst_ptr = 0;
for (uint k = 0; k < dec_count; k++) for (uint k = 0; k < dec_count; k++)
{ {
uint node_index = 0; int node_index = 0;
do do
{ {
int bit = GetNextBit(); int bit = GetNextBit();
@ -271,20 +270,16 @@ namespace GameRes.Formats.BGI
} }
while (hnodes[node_index].IsParent); while (hnodes[node_index].IsParent);
uint code = hnodes[node_index].Code; int code = hnodes[node_index].Code;
if (code >= 256) if (code >= 256)
{ {
int win_pos = GetBits (12); int offset = GetBits (12);
if (-1 == win_pos) if (-1 == offset)
break; break;
int count = (code & 0xff) + 2;
uint copy_bytes = (code & 0xff) + 2; offset += 2;
win_pos += 2; Binary.CopyOverlapped (m_output, dst_ptr - offset, dst_ptr, count);
for (uint i = 0; i < copy_bytes; i++) dst_ptr += count;
{
m_output[dst_ptr] = m_output[dst_ptr - win_pos];
dst_ptr++;
}
} else } else
m_output[dst_ptr++] = (byte)code; m_output[dst_ptr++] = (byte)code;
} }