diff --git a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs index 85af7d98..036ace4a 100644 --- a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs +++ b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs @@ -167,84 +167,7 @@ namespace LibMSPackSharp.Compression // TODO: These should be in a separate file #region ReadHuff Methods - private const int HUFF_MAXBITS = 16; - - /// - /// Decodes the next huffman symbol from the input bitstream into var. - /// Do not use this macro on a table unless build_decode_table() succeeded. - /// - 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; /// /// This function was originally coded by David Tritscher. diff --git a/BurnOutSharp/External/libmspack/Compression/MSZIP.cs b/BurnOutSharp/External/libmspack/Compression/MSZIP.cs index ca3411d0..1d777e8c 100644 --- a/BurnOutSharp/External/libmspack/Compression/MSZIP.cs +++ b/BurnOutSharp/External/libmspack/Compression/MSZIP.cs @@ -962,7 +962,6 @@ namespace LibMSPackSharp.Compression /// /// A clean implementation of RFC 1951 / inflate /// - // 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;