mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-08-03 14:39:22 +00:00
Huffman tree implement MSZIP (nw)
This commit is contained in:
@@ -167,84 +167,7 @@ namespace LibMSPackSharp.Compression
|
||||
// TODO: These should be in a separate file
|
||||
#region ReadHuff Methods
|
||||
|
||||
private const int HUFF_MAXBITS = 16;
|
||||
|
||||
/// <summary>
|
||||
/// Decodes the next huffman symbol from the input bitstream into var.
|
||||
/// Do not use this macro on a table unless build_decode_table() succeeded.
|
||||
/// </summary>
|
||||
public int READ_HUFFSYM(ushort[] decodingTable, ref uint var, int tablebits, byte[] lengthTable, int maxsymbols, ref int i, ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer, bool msb)
|
||||
{
|
||||
// ENSURE_BITS(HUFF_MAXBITS)
|
||||
while (bits_left < HUFF_MAXBITS)
|
||||
{
|
||||
READ_BYTES;
|
||||
}
|
||||
|
||||
if (Error != Error.MSPACK_ERR_OK)
|
||||
return (int)Error;
|
||||
|
||||
int peek;
|
||||
if (msb)
|
||||
peek = (int)(bit_buffer >> (BITBUF_WIDTH - (tablebits)));
|
||||
else
|
||||
peek = (int)(bit_buffer & ((1 << (tablebits)) - 1));
|
||||
|
||||
ushort sym = decodingTable[peek];
|
||||
if (sym >= maxsymbols)
|
||||
{
|
||||
int ret = HUFF_TRAVERSE(decodingTable, tablebits, maxsymbols, ref i, ref sym, bit_buffer, msb);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
var = sym;
|
||||
i = lengthTable[sym];
|
||||
|
||||
// REMOVE_BITS(i);
|
||||
if (msb)
|
||||
{
|
||||
bit_buffer <<= i;
|
||||
bits_left -= i;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit_buffer >>= i;
|
||||
bits_left -= i;
|
||||
}
|
||||
|
||||
return (int)Error.MSPACK_ERR_OK;
|
||||
}
|
||||
|
||||
public int HUFF_TRAVERSE(ushort[] decodingTable, int tablebits, int maxsymbols, ref int i, ref ushort sym, uint bit_buffer, bool msb)
|
||||
{
|
||||
if (msb)
|
||||
{
|
||||
i = 1 << (BITBUF_WIDTH - tablebits);
|
||||
do
|
||||
{
|
||||
if ((i >>= 1) == 0)
|
||||
return HUFF_ERROR();
|
||||
|
||||
sym = decodingTable[(sym << 1) | ((bit_buffer & i) != 0 ? 1 : 0)];
|
||||
} while (sym >= maxsymbols);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = tablebits - 1;
|
||||
do
|
||||
{
|
||||
if (i++ > HUFF_MAXBITS)
|
||||
return HUFF_ERROR();
|
||||
|
||||
try { sym = decodingTable[(sym << 1) | ((bit_buffer >> i) & 1)]; } catch { }
|
||||
} while (sym >= maxsymbols);
|
||||
}
|
||||
|
||||
return (int)Error.MSPACK_ERR_OK;
|
||||
}
|
||||
|
||||
public abstract int HUFF_ERROR();
|
||||
public const int HUFF_MAXBITS = 16;
|
||||
|
||||
/// <summary>
|
||||
/// This function was originally coded by David Tritscher.
|
||||
|
||||
111
BurnOutSharp/External/libmspack/Compression/MSZIP.cs
vendored
111
BurnOutSharp/External/libmspack/Compression/MSZIP.cs
vendored
@@ -962,7 +962,6 @@ namespace LibMSPackSharp.Compression
|
||||
/// <summary>
|
||||
/// A clean implementation of RFC 1951 / inflate
|
||||
/// </summary>
|
||||
// TODO: Huffman tree implementation
|
||||
private static Error Inflate(MSZIPDStream zip)
|
||||
{
|
||||
uint last_block, block_type, distance, length, this_run, i;
|
||||
@@ -1228,7 +1227,60 @@ namespace LibMSPackSharp.Compression
|
||||
// Decode forever until end of block code
|
||||
for (; ; )
|
||||
{
|
||||
READ_HUFFSYM(LITERAL, code);
|
||||
//READ_HUFFSYM(LITERAL, code)
|
||||
{
|
||||
//ENSURE_BITS(CompressionStream.HUFF_MAXBITS)
|
||||
{
|
||||
while (bits_left < (CompressionStream.HUFF_MAXBITS))
|
||||
{
|
||||
//READ_BYTES
|
||||
{
|
||||
//READ_IF_NEEDED
|
||||
{
|
||||
if (i_ptr >= i_end)
|
||||
{
|
||||
if (zip.ReadInput() != Error.MSPACK_ERR_OK)
|
||||
return zip.Error;
|
||||
|
||||
i_ptr = zip.InputPointer;
|
||||
i_end = zip.InputLength;
|
||||
}
|
||||
}
|
||||
|
||||
//INJECT_BITS(zip.InputBuffer[i_ptr++], 8)
|
||||
{
|
||||
bit_buffer |= (uint)((zip.InputBuffer[i_ptr++]) << bits_left);
|
||||
bits_left += (8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sym = zip.LITERAL_table[(bit_buffer & ((1 << (MSZIP_LITERAL_TABLEBITS)) - 1))]; //PEEK_BITS(TABLEBITS(LITERAL))
|
||||
if (sym >= MSZIP_LITERAL_MAXSYMBOLS)
|
||||
{
|
||||
//HUFF_TRAVERSE(LITERAL)
|
||||
{
|
||||
i = MSZIP_LITERAL_TABLEBITS - 1;
|
||||
do
|
||||
{
|
||||
if (i++ > CompressionStream.HUFF_MAXBITS)
|
||||
return Error.INF_ERR_HUFFSYM;
|
||||
|
||||
sym = zip.LITERAL_table[(sym << 1) | ((bit_buffer >> (int)i) & 1)];
|
||||
} while (sym >= MSZIP_LITERAL_MAXSYMBOLS);
|
||||
}
|
||||
}
|
||||
|
||||
(code) = sym;
|
||||
i = zip.LITERAL_len[sym];
|
||||
|
||||
//REMOVE_BITS(i)
|
||||
{
|
||||
bit_buffer >>= (int)(i);
|
||||
bits_left -= (int)(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (code < 256)
|
||||
{
|
||||
@@ -1296,7 +1348,60 @@ namespace LibMSPackSharp.Compression
|
||||
|
||||
length += lit_lengths[code];
|
||||
|
||||
READ_HUFFSYM(DISTANCE, code);
|
||||
//READ_HUFFSYM(DISTANCE, var)
|
||||
{
|
||||
//ENSURE_BITS(CompressionStream.HUFF_MAXBITS)
|
||||
{
|
||||
while (bits_left < (CompressionStream.HUFF_MAXBITS))
|
||||
{
|
||||
//READ_BYTES
|
||||
{
|
||||
//READ_IF_NEEDED
|
||||
{
|
||||
if (i_ptr >= i_end)
|
||||
{
|
||||
if (zip.ReadInput() != Error.MSPACK_ERR_OK)
|
||||
return zip.Error;
|
||||
|
||||
i_ptr = zip.InputPointer;
|
||||
i_end = zip.InputLength;
|
||||
}
|
||||
}
|
||||
|
||||
//INJECT_BITS(zip.InputBuffer[i_ptr++], 8)
|
||||
{
|
||||
bit_buffer |= (uint)((zip.InputBuffer[i_ptr++]) << bits_left);
|
||||
bits_left += (8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sym = zip.DISTANCE_table[(bit_buffer & ((1 << (MSZIP_DISTANCE_TABLEBITS)) - 1))]; //PEEK_BITS(TABLEBITS(DISTANCE))
|
||||
if (sym >= MSZIP_DISTANCE_MAXSYMBOLS)
|
||||
{
|
||||
//HUFF_TRAVERSE(DISTANCE)
|
||||
{
|
||||
i = MSZIP_DISTANCE_TABLEBITS - 1;
|
||||
do
|
||||
{
|
||||
if (i++ > CompressionStream.HUFF_MAXBITS)
|
||||
return Error.INF_ERR_HUFFSYM;
|
||||
|
||||
sym = zip.DISTANCE_table[(sym << 1) | ((bit_buffer >> (int)i) & 1)];
|
||||
} while (sym >= MSZIP_DISTANCE_MAXSYMBOLS);
|
||||
}
|
||||
}
|
||||
|
||||
(code) = sym;
|
||||
i = zip.DISTANCE_len[sym];
|
||||
|
||||
//REMOVE_BITS(i)
|
||||
{
|
||||
bit_buffer >>= (int)(i);
|
||||
bits_left -= (int)(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (code >= 30)
|
||||
return Error.INF_ERR_DISTCODE;
|
||||
|
||||
Reference in New Issue
Block a user