diff --git a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs index 7d922e98..85af7d98 100644 --- a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs +++ b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs @@ -36,7 +36,7 @@ namespace LibMSPackSharp.Compression /// public FileStream Output { get; set; } - public LibMSPackSharp.Error Error { get; set; } + public Error Error { get; set; } #region I/O buffering @@ -133,46 +133,11 @@ namespace LibMSPackSharp.Compression * to the bit buffer when the bit buffer already has 1 to 15 bits left. */ - public void READ_BITS_MSB(ref int val, int nbits, ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer) - { - //READ_BITS(val, nbits) - { - //ENSURE_BITS(nbits) - while (bits_left < (nbits)) - { - READ_BYTES; - } - - val = (int)(bit_buffer >> (BITBUF_WIDTH - (nbits))); - - // REMOVE_BITS(nbits); - bit_buffer <<= (nbits); - bits_left -= (nbits); - } - } - - public void READ_BITS_LSB(ref int val, int nbits, ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer) - { - //READ_BITS(val, nbits) - - //ENSURE_BITS(nbits) - while (bits_left < nbits) - { - READ_BYTES; - } - - val = (int)(bit_buffer & ((1 << (nbits)) - 1)); - - //REMOVE_BITS(nbits); - bit_buffer >>= (nbits); - bits_left -= (nbits); - } - - public LibMSPackSharp.Error ReadInput() + public Error ReadInput() { int read = Sys.Read(Input, InputBuffer, 0, (int)InputBufferSize); if (read < 0) - return Error = LibMSPackSharp.Error.MSPACK_ERR_READ; + return Error = Error.MSPACK_ERR_READ; // We might overrun the input stream by asking for bits we don't use, // so fake 2 more bytes at the end of input @@ -181,7 +146,7 @@ namespace LibMSPackSharp.Compression if (InputEnd != 0) { Console.WriteLine("out of input bytes"); - return Error = LibMSPackSharp.Error.MSPACK_ERR_READ; + return Error = Error.MSPACK_ERR_READ; } else { @@ -194,7 +159,7 @@ namespace LibMSPackSharp.Compression // Update i_ptr and i_end InputPointer = 0; InputLength = read; - return Error = LibMSPackSharp.Error.MSPACK_ERR_OK; + return Error = Error.MSPACK_ERR_OK; } #endregion @@ -216,7 +181,7 @@ namespace LibMSPackSharp.Compression READ_BYTES; } - if (Error != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (Error != Error.MSPACK_ERR_OK) return (int)Error; int peek; @@ -248,7 +213,7 @@ namespace LibMSPackSharp.Compression bits_left -= i; } - return (int)LibMSPackSharp.Error.MSPACK_ERR_OK; + 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) @@ -276,7 +241,7 @@ namespace LibMSPackSharp.Compression } while (sym >= maxsymbols); } - return (int)LibMSPackSharp.Error.MSPACK_ERR_OK; + return (int)Error.MSPACK_ERR_OK; } public abstract int HUFF_ERROR(); diff --git a/BurnOutSharp/External/libmspack/Compression/LZSS.cs b/BurnOutSharp/External/libmspack/Compression/LZSS.cs index 66def40b..082d6075 100644 --- a/BurnOutSharp/External/libmspack/Compression/LZSS.cs +++ b/BurnOutSharp/External/libmspack/Compression/LZSS.cs @@ -56,11 +56,11 @@ namespace LibMSPackSharp.Compression /// /// one of LZSSMode values /// an error code, or MSPACK_ERR_OK if successful - public static LibMSPackSharp.Error Decompress(SystemImpl system, FileStream input, FileStream output, int input_buffer_size, LZSSMode mode) + public static Error Decompress(SystemImpl system, FileStream input, FileStream output, int input_buffer_size, LZSSMode mode) { // Check parameters if (system == null || input_buffer_size < 1 || (mode != LZSSMode.LZSS_MODE_EXPAND && mode != LZSSMode.LZSS_MODE_MSHELP && mode != LZSSMode.LZSS_MODE_QBASIC)) - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; // Allocate memory byte[] window = new byte[LZSS_WINDOW_SIZE + input_buffer_size]; @@ -85,7 +85,7 @@ namespace LibMSPackSharp.Compression { read = input.Read(window, inbuf, input_buffer_size); if (read <= 0) - return (read < 0) ? LibMSPackSharp.Error.MSPACK_ERR_READ : LibMSPackSharp.Error.MSPACK_ERR_OK; + return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK; i_ptr = inbuf; i_end = read; @@ -104,7 +104,7 @@ namespace LibMSPackSharp.Compression { read = input.Read(window, inbuf, input_buffer_size); if (read <= 0) - return (read < 0) ? LibMSPackSharp.Error.MSPACK_ERR_READ : LibMSPackSharp.Error.MSPACK_ERR_OK; + return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK; i_ptr = inbuf; i_end = read; @@ -116,7 +116,7 @@ namespace LibMSPackSharp.Compression //WRITE_BYTE { try { output.Write(window, (int)pos, 1); } - catch { return LibMSPackSharp.Error.MSPACK_ERR_WRITE; } + catch { return Error.MSPACK_ERR_WRITE; } } pos++; @@ -132,7 +132,7 @@ namespace LibMSPackSharp.Compression { read = input.Read(window, inbuf, input_buffer_size); if (read <= 0) - return (read < 0) ? LibMSPackSharp.Error.MSPACK_ERR_READ : LibMSPackSharp.Error.MSPACK_ERR_OK; + return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK; i_ptr = inbuf; i_end = read; @@ -147,7 +147,7 @@ namespace LibMSPackSharp.Compression { read = input.Read(window, inbuf, input_buffer_size); if (read <= 0) - return (read < 0) ? LibMSPackSharp.Error.MSPACK_ERR_READ : LibMSPackSharp.Error.MSPACK_ERR_OK; + return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK; i_ptr = inbuf; i_end = read; @@ -164,7 +164,7 @@ namespace LibMSPackSharp.Compression //WRITE_BYTE { try { output.Write(window, (int)pos, 1); } - catch { return LibMSPackSharp.Error.MSPACK_ERR_WRITE; } + catch { return Error.MSPACK_ERR_WRITE; } } pos++; @@ -177,7 +177,7 @@ namespace LibMSPackSharp.Compression } /* not reached */ - return LibMSPackSharp.Error.MSPACK_ERR_OK; + return Error.MSPACK_ERR_OK; } } } diff --git a/BurnOutSharp/External/libmspack/Compression/LZX.cs b/BurnOutSharp/External/libmspack/Compression/LZX.cs index b9771f9b..05e54e96 100644 --- a/BurnOutSharp/External/libmspack/Compression/LZX.cs +++ b/BurnOutSharp/External/libmspack/Compression/LZX.cs @@ -322,7 +322,7 @@ namespace LibMSPackSharp.Compression ResetInterval = (uint)reset_interval, IntelFileSize = 0, IntelStarted = false, - Error = LibMSPackSharp.Error.MSPACK_ERR_OK, + Error = Error.MSPACK_ERR_OK, NumOffsets = position_slots[window_bits - 15] << 3, IsDelta = is_delta, @@ -362,33 +362,33 @@ namespace LibMSPackSharp.Compression /// than the LZX window size. /// /// an error code, or MSPACK_ERR_OK if successful - public static LibMSPackSharp.Error SetReferenceData(LZXDStream lzx, SystemImpl system, FileStream input, uint length) + public static Error SetReferenceData(LZXDStream lzx, SystemImpl system, FileStream input, uint length) { if (lzx == null) - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; if (!lzx.IsDelta) { Console.WriteLine("Only LZX DELTA streams support reference data"); - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; } if (lzx.Offset != 0) { Console.WriteLine("Too late to set reference data after decoding starts"); - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; } if (length > lzx.WindowSize) { Console.WriteLine($"Reference length ({length}) is longer than the window"); - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; } if (length > 0 && (system == null || input == null)) { Console.WriteLine("Length > 0 but no system or input"); - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; } lzx.ReferenceDataSize = length; @@ -400,11 +400,11 @@ namespace LibMSPackSharp.Compression // Length can't be more than 2^25, so no signedness problem if (bytes < (int)length) - return LibMSPackSharp.Error.MSPACK_ERR_READ; + return Error.MSPACK_ERR_READ; } lzx.ReferenceDataSize = length; - return LibMSPackSharp.Error.MSPACK_ERR_OK; + return Error.MSPACK_ERR_OK; } // See description of outputLength in lzxd_init() @@ -440,11 +440,11 @@ namespace LibMSPackSharp.Compression /// the number of bytes of data to decompress. /// an error code, or MSPACK_ERR_OK if successful // TODO: Huffman tree implementation - public static LibMSPackSharp.Error Decompress(object o, long out_bytes) + public static Error Decompress(object o, long out_bytes) { LZXDStream lzx = o as LZXDStream; if (lzx == null) - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; // Bitstream and huffman reading variables uint bit_buffer; @@ -461,9 +461,9 @@ namespace LibMSPackSharp.Compression // Easy answers if (lzx == null || (out_bytes < 0)) - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; - if (lzx.Error != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.Error != Error.MSPACK_ERR_OK) return lzx.Error; // Flush out any stored-up bytes before we begin @@ -474,7 +474,7 @@ namespace LibMSPackSharp.Compression if (i != 0) { try { lzx.Output.Write(lzx.e8_buf, lzx.OutputPointer, i); } - catch { return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_WRITE; } + catch { return lzx.Error = Error.MSPACK_ERR_WRITE; } lzx.OutputPointer += i; lzx.Offset += i; @@ -482,7 +482,7 @@ namespace LibMSPackSharp.Compression } if (out_bytes == 0) - return LibMSPackSharp.Error.MSPACK_ERR_OK; + return Error.MSPACK_ERR_OK; // Restore local state @@ -538,7 +538,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -552,7 +552,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -597,7 +597,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -611,7 +611,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -653,7 +653,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -667,7 +667,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -707,7 +707,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -721,7 +721,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -775,7 +775,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -800,7 +800,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -814,7 +814,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -854,7 +854,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -868,7 +868,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -908,7 +908,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -922,7 +922,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -972,7 +972,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -986,7 +986,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1067,7 +1067,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1081,7 +1081,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1110,7 +1110,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1129,7 +1129,7 @@ namespace LibMSPackSharp.Compression default: Console.WriteLine("Bad block type"); - return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + return lzx.Error = Error.MSPACK_ERR_DECRUNCH; } } @@ -1170,7 +1170,7 @@ namespace LibMSPackSharp.Compression if (lzx.LENGTH_empty != 0) { Console.WriteLine("LENGTH symbol needed but tree is empty"); - return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + return lzx.Error = Error.MSPACK_ERR_DECRUNCH; } READ_HUFFSYM(LENGTH, length_footer); @@ -1222,7 +1222,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1236,7 +1236,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1291,7 +1291,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1305,7 +1305,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1363,7 +1363,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1377,7 +1377,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1437,7 +1437,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1451,7 +1451,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1491,7 +1491,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1505,7 +1505,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1555,7 +1555,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1569,7 +1569,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1621,7 +1621,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1635,7 +1635,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1687,7 +1687,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1701,7 +1701,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1736,7 +1736,7 @@ namespace LibMSPackSharp.Compression if ((window_posn + match_length) > lzx.WindowSize) { Console.WriteLine("Match ran over window wrap"); - return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + return lzx.Error = Error.MSPACK_ERR_DECRUNCH; } // Copy match @@ -1749,7 +1749,7 @@ namespace LibMSPackSharp.Compression if (match_offset > lzx.Offset && (match_offset - window_posn) > lzx.ReferenceDataSize) { Console.WriteLine("Match offset beyond LZX stream"); - return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + return lzx.Error = Error.MSPACK_ERR_DECRUNCH; } // j = length from match offset to end of window @@ -1757,7 +1757,7 @@ namespace LibMSPackSharp.Compression if (j > (int)lzx.WindowSize) { Console.WriteLine("Match offset beyond window boundaries"); - return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + return lzx.Error = Error.MSPACK_ERR_DECRUNCH; } runsrc = (int)(lzx.WindowSize - j); @@ -1807,7 +1807,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1830,7 +1830,7 @@ namespace LibMSPackSharp.Compression break; default: - return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; // Might as well + return lzx.Error = Error.MSPACK_ERR_DECRUNCH; // Might as well } // Did the final match overrun our desired this_run length? @@ -1839,7 +1839,7 @@ namespace LibMSPackSharp.Compression if ((uint)(-this_run) > lzx.BlockRemaining) { Console.WriteLine($"Overrun went past end of block by {-this_run} ({lzx.BlockRemaining} remaining)"); - return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + return lzx.Error = Error.MSPACK_ERR_DECRUNCH; } lzx.BlockRemaining -= (uint)-this_run; @@ -1850,7 +1850,7 @@ namespace LibMSPackSharp.Compression if ((window_posn - lzx.FramePosition) != frame_size) { Console.WriteLine($"Decode beyond output frame limits! {window_posn - lzx.FramePosition} != {frame_size}"); - return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + return lzx.Error = Error.MSPACK_ERR_DECRUNCH; } // Re-align input bitstream @@ -1866,7 +1866,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1880,7 +1880,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -1913,7 +1913,7 @@ namespace LibMSPackSharp.Compression if (lzx.OutputPointer != lzx.OutputLength) { Console.WriteLine($"{lzx.OutputLength - lzx.OutputPointer} avail bytes, new {frame_size} frame"); - return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + return lzx.Error = Error.MSPACK_ERR_DECRUNCH; } // Does this intel block _really_ need decoding? @@ -1956,7 +1956,7 @@ namespace LibMSPackSharp.Compression // Write a frame i = (int)((out_bytes < frame_size) ? out_bytes : frame_size); try { lzx.Output.Write(lzx.e8_buf, lzx.OutputPointer, i); } - catch { return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_WRITE; } + catch { return lzx.Error = Error.MSPACK_ERR_WRITE; } } else { @@ -1966,7 +1966,7 @@ namespace LibMSPackSharp.Compression // Write a frame i = (int)((out_bytes < frame_size) ? out_bytes : frame_size); try { lzx.Output.Write(lzx.Window, lzx.OutputPointer, i); } - catch { return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_WRITE; } + catch { return lzx.Error = Error.MSPACK_ERR_WRITE; } } lzx.OutputPointer += i; @@ -1988,7 +1988,7 @@ namespace LibMSPackSharp.Compression if (out_bytes != 0) { Console.WriteLine("Bytes left to output"); - return lzx.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + return lzx.Error = Error.MSPACK_ERR_DECRUNCH; } // Store local state @@ -2006,11 +2006,11 @@ namespace LibMSPackSharp.Compression lzx.R1 = R1; lzx.R2 = R2; - return LibMSPackSharp.Error.MSPACK_ERR_OK; + return Error.MSPACK_ERR_OK; } // TODO: Huffman tree implementation - private static LibMSPackSharp.Error ReadLens(LZXDStream lzx, byte[] lens, uint first, uint last) + private static Error ReadLens(LZXDStream lzx, byte[] lens, uint first, uint last) { // Bit buffer and huffman symbol decode variables uint bit_buffer; @@ -2044,7 +2044,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -2058,7 +2058,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -2110,7 +2110,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -2124,7 +2124,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -2174,7 +2174,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -2188,7 +2188,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -2238,7 +2238,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -2252,7 +2252,7 @@ namespace LibMSPackSharp.Compression { if (i_ptr >= i_end) { - if (lzx.ReadInput() != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (lzx.ReadInput() != Error.MSPACK_ERR_OK) return lzx.Error; i_ptr = lzx.InputPointer; @@ -2313,7 +2313,7 @@ namespace LibMSPackSharp.Compression lzx.BitsLeft = bits_left; } - return LibMSPackSharp.Error.MSPACK_ERR_OK; + return Error.MSPACK_ERR_OK; } } } diff --git a/BurnOutSharp/External/libmspack/Compression/LZXDStream.cs b/BurnOutSharp/External/libmspack/Compression/LZXDStream.cs index 1959caff..a9edbba9 100644 --- a/BurnOutSharp/External/libmspack/Compression/LZXDStream.cs +++ b/BurnOutSharp/External/libmspack/Compression/LZXDStream.cs @@ -137,6 +137,6 @@ namespace LibMSPackSharp.Compression // This is used purely for doing the intel E8 transform public byte[] e8_buf { get; set; } = new byte[LZX.LZX_FRAME_SIZE]; - public override int HUFF_ERROR() => (int)(Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH); + public override int HUFF_ERROR() => (int)(Error = Error.MSPACK_ERR_DECRUNCH); } } diff --git a/BurnOutSharp/External/libmspack/Compression/MSZIPDStream.cs b/BurnOutSharp/External/libmspack/Compression/MSZIPDStream.cs index 9bffac77..7004373b 100644 --- a/BurnOutSharp/External/libmspack/Compression/MSZIPDStream.cs +++ b/BurnOutSharp/External/libmspack/Compression/MSZIPDStream.cs @@ -29,7 +29,7 @@ namespace LibMSPackSharp.Compression /// /// inflate() will call this whenever the window should be emptied. /// - public Func FlushWindow; + public Func FlushWindow; public bool RepairMode { get; set; } diff --git a/BurnOutSharp/External/libmspack/Compression/None.cs b/BurnOutSharp/External/libmspack/Compression/None.cs index 8bd1ae8a..3d26968a 100644 --- a/BurnOutSharp/External/libmspack/Compression/None.cs +++ b/BurnOutSharp/External/libmspack/Compression/None.cs @@ -25,11 +25,11 @@ namespace LibMSPackSharp.Compression }; } - public static LibMSPackSharp.Error Decompress(object s, long bytes) + public static Error Decompress(object s, long bytes) { NoneState state = (NoneState)s; if (state == null) - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; int run; while (bytes > 0) @@ -37,14 +37,14 @@ namespace LibMSPackSharp.Compression run = (bytes > state.BufferSize) ? state.BufferSize : (int)bytes; if (state.Sys.Read(state.Input, state.Buffer, 0, run) != run) - return LibMSPackSharp.Error.MSPACK_ERR_READ; + return Error.MSPACK_ERR_READ; if (state.Sys.Write(state.Output, state.Buffer, 0, run) != run) - return LibMSPackSharp.Error.MSPACK_ERR_WRITE; + return Error.MSPACK_ERR_WRITE; bytes -= run; } - return LibMSPackSharp.Error.MSPACK_ERR_OK; + return Error.MSPACK_ERR_OK; } } } diff --git a/BurnOutSharp/External/libmspack/Compression/QTM.cs b/BurnOutSharp/External/libmspack/Compression/QTM.cs index 375c4811..0a6ca78c 100644 --- a/BurnOutSharp/External/libmspack/Compression/QTM.cs +++ b/BurnOutSharp/External/libmspack/Compression/QTM.cs @@ -105,31 +105,35 @@ namespace LibMSPackSharp.Compression // Round up input buffer size to multiple of two input_buffer_size = (input_buffer_size + 1) & -2; - if (input_buffer_size < 2) return null; + if (input_buffer_size < 2) + return null; // Allocate decompression state - QTMDStream qtm = new QTMDStream(); + QTMDStream qtm = new QTMDStream() + { + // Allocate decompression window and input buffer + Window = new byte[window_size], + InputBuffer = new byte[input_buffer_size], - // Allocate decompression window and input buffer - qtm.Window = new byte[window_size]; - qtm.InputBuffer = new byte[input_buffer_size]; + // Initialise decompression state + Sys = system, + Input = input, + Output = output, + InputBufferSize = (uint)input_buffer_size, + WindowSize = window_size, + WindowPosition = 0, + FrameTODO = QTM_FRAME_SIZE, + HeaderRead = 0, + Error = Error.MSPACK_ERR_OK, - // Initialise decompression state - qtm.Sys = system; - qtm.Input = input; - qtm.Output = output; - qtm.InputBufferSize = (uint)input_buffer_size; - qtm.WindowSize = window_size; - qtm.WindowPosition = 0; - qtm.FrameTODO = QTM_FRAME_SIZE; - qtm.HeaderRead = 0; - qtm.Error = LibMSPackSharp.Error.MSPACK_ERR_OK; - - qtm.InputPointer = qtm.InputLength = 0; - qtm.OutputPointer = qtm.OutputLength = 0; - qtm.InputEnd = 0; - qtm.BitsLeft = 0; - qtm.BitBuffer = 0; + InputPointer = 0, + InputLength = 0, + OutputPointer = 0, + OutputLength = 0, + InputEnd = 0, + BitsLeft = 0, + BitBuffer = 0, + }; // Initialise arithmetic coding models // - model 4 depends on window size, ranges from 20 to 24 @@ -170,25 +174,26 @@ namespace LibMSPackSharp.Compression /// qtmd_init(). This will continue until system.read() returns 0 bytes, /// or an error. /// - public static LibMSPackSharp.Error Decompress(object o, long out_bytes) + public static Error Decompress(object o, long out_bytes) { QTMDStream qtm = o as QTMDStream; if (qtm == null) - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; - uint frame_end, match_offset, range = 0, extra = 0; - int i_ptr = 0, i_end = 0, runsrc, rundest; - int i, j, selector = 0, sym = 0, match_length; - ushort symf = 0; + uint frame_todo, frame_end, window_posn, match_offset, range; + byte[] window; + int i_ptr, i_end, runsrc, rundest; + int i, j, selector, extra, sym, match_length; + ushort H, L, C, symf; - uint bit_buffer = 0; - int bits_left = 0; + uint bit_buffer; + int bits_left; // Easy answers if (qtm == null || (out_bytes < 0)) - return LibMSPackSharp.Error.MSPACK_ERR_ARGS; + return Error.MSPACK_ERR_ARGS; - if (qtm.Error != LibMSPackSharp.Error.MSPACK_ERR_OK) + if (qtm.Error != Error.MSPACK_ERR_OK) return qtm.Error; // Flush out any stored-up bytes before we begin @@ -199,53 +204,93 @@ namespace LibMSPackSharp.Compression if (i != 0) { if (qtm.Sys.Write(qtm.Output, qtm.Window, qtm.OutputPointer, i) != i) - return qtm.Error = LibMSPackSharp.Error.MSPACK_ERR_WRITE; + return qtm.Error = Error.MSPACK_ERR_WRITE; qtm.OutputPointer += i; out_bytes -= i; } if (out_bytes == 0) - return LibMSPackSharp.Error.MSPACK_ERR_OK; + return Error.MSPACK_ERR_OK; // Restore local state //RESTORE_BITS - i_ptr = qtm.InputPointer; - i_end = qtm.InputLength; - bit_buffer = qtm.BitBuffer; - bits_left = qtm.BitsLeft; + { + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + bit_buffer = qtm.BitBuffer; + bits_left = qtm.BitsLeft; + } - byte[] window = qtm.Window; - uint window_posn = qtm.WindowPosition; - uint frame_todo = qtm.FrameTODO; + window = qtm.Window; + window_posn = qtm.WindowPosition; + frame_todo = qtm.FrameTODO; + H = qtm.High; + L = qtm.Low; + C = qtm.Current; - ushort high = qtm.High; - ushort low = qtm.Low; - ushort current = qtm.Current; - - // While we do not have enough decoded bytes in reserve: + // While we do not have enough decoded bytes in reserve while ((qtm.OutputLength - qtm.OutputPointer) < out_bytes) { // Read header if necessary. Initialises H, L and C - if (qtm.HeaderRead == 0) + if (qtm.HeaderRead != 0) { - high = 0xFFFF; - low = 0; + H = 0xFFFF; + L = 0; - //READ_BITS(i, 16) + //READ_BITS(C, 16) { //ENSURE_BITS(16) - while (bits_left < (16)) { - READ_BYTES; + while (bits_left < (16)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } } - i = (int)(bit_buffer >> (BITBUF_WIDTH - (16))); + (C) = (ushort)(bit_buffer >> (CompressionStream.BITBUF_WIDTH - (16))); //PEEK_BITS(16) - // REMOVE_BITS(16); - bit_buffer <<= (16); - bits_left -= (16); + //REMOVE_BITS(16) + { + bit_buffer <<= (16); + bits_left -= (16); + } } qtm.HeaderRead = 1; @@ -256,158 +301,896 @@ namespace LibMSPackSharp.Compression frame_end = (uint)(window_posn + (out_bytes - (qtm.OutputLength - qtm.OutputPointer))); if ((window_posn + frame_todo) < frame_end) frame_end = window_posn + frame_todo; - if (frame_end > qtm.WindowSize) frame_end = qtm.WindowSize; while (window_posn < frame_end) { - GET_SYMBOL(qtm, qtm.Model7, ref selector, ref range, ref symf, ref high, ref low, ref current, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left); + //GET_SYMBOL(qtm.Model7, var) + { + range = (uint)((H - L) & 0xFFFF) + 1; + symf = (ushort)(((((C - L + 1) * qtm.Model7.Syms[0].CumulativeFrequency) - 1) / range) & 0xFFFF); + + for (i = 1; i < qtm.Model7.Entries; i++) + { + if (qtm.Model7.Syms[i].CumulativeFrequency <= symf) + break; + } + + (selector) = qtm.Model7.Syms[i - 1].Sym; + + range = (uint)(H - L) + 1; + symf = qtm.Model7.Syms[0].CumulativeFrequency; + H = (ushort)(L + ((qtm.Model7.Syms[i - 1].CumulativeFrequency * range) / symf) - 1); + L = (ushort)(L + ((qtm.Model7.Syms[i].CumulativeFrequency * range) / symf)); + + do + { + qtm.Model7.Syms[--i].CumulativeFrequency += 8; + } while (i > 0); + + if (qtm.Model7.Syms[0].CumulativeFrequency > 3800) + UpdateModel(qtm.Model7); + + while (true) + { + if ((L & 0x8000) != (H & 0x8000)) + { + if ((L & 0x4000) != 0 && (H & 0x4000) == 0) + { + // Underflow case + C ^= 0x4000; + L &= 0x3FFF; + H |= 0x4000; + } + else + { + break; + } + } + + L <<= 1; + H = (ushort)((H << 1) | 1); + + //ENSURE_BITS(1) + { + while (bits_left < (1)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } + } + + C = (ushort)((C << 1) | (bit_buffer >> (CompressionStream.BITBUF_WIDTH - (1)))); //PEEK_BITS(1) + + //REMOVE_BITS(1) + { + bit_buffer <<= (1); + bits_left -= (1); + } + } + } + if (selector < 4) { // Literal byte QTMDModel mdl; switch (selector) { - case 0: mdl = qtm.Model0; break; - case 1: mdl = qtm.Model1; break; - case 2: mdl = qtm.Model2; break; - default: mdl = qtm.Model3; break; + case 0: + mdl = qtm.Model0; + break; + + case 1: + mdl = qtm.Model1; + break; + + case 2: + mdl = qtm.Model2; + break; + + case 3: + default: + mdl = qtm.Model3; + break; + } + + //GET_SYMBOL(mdl, sym) + { + range = (uint)((H - L) & 0xFFFF) + 1; + symf = (ushort)(((((C - L + 1) * mdl.Syms[0].CumulativeFrequency) - 1) / range) & 0xFFFF); + + for (i = 1; i < mdl.Entries; i++) + { + if (mdl.Syms[i].CumulativeFrequency <= symf) + break; + } + + (sym) = mdl.Syms[i - 1].Sym; + + range = (uint)(H - L) + 1; + symf = mdl.Syms[0].CumulativeFrequency; + H = (ushort)(L + ((mdl.Syms[i - 1].CumulativeFrequency * range) / symf) - 1); + L = (ushort)(L + ((mdl.Syms[i].CumulativeFrequency * range) / symf)); + + do + { + mdl.Syms[--i].CumulativeFrequency += 8; + } while (i > 0); + + if (mdl.Syms[0].CumulativeFrequency > 3800) + UpdateModel(mdl); + + while (true) + { + if ((L & 0x8000) != (H & 0x8000)) + { + if ((L & 0x4000) != 0 && (H & 0x4000) == 0) + { + // Underflow case + C ^= 0x4000; + L &= 0x3FFF; + H |= 0x4000; + } + else + { + break; + } + } + + L <<= 1; + H = (ushort)((H << 1) | 1); + + //ENSURE_BITS(1) + { + while (bits_left < (1)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } + } + + C = (ushort)((C << 1) | (bit_buffer >> (CompressionStream.BITBUF_WIDTH - (1)))); //PEEK_BITS(1) + + //REMOVE_BITS(1) + { + bit_buffer <<= (1); + bits_left -= (1); + } + } } - GET_SYMBOL(qtm, mdl, ref sym, ref range, ref symf, ref high, ref low, ref current, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left); window[window_posn++] = (byte)sym; frame_todo--; } else { // Match repeated string - byte needed, bitrun; switch (selector) { // Selector 4 = fixed length match (3 bytes) case 4: - GET_SYMBOL(qtm, qtm.Model4, ref sym, ref range, ref symf, ref high, ref low, ref current, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left); - - // READ_MANY_BITS(extra, extra_bits[sym]) - needed = extra_bits[sym]; - extra = 0; - while (needed > 0) + //GET_SYMBOL(qtm.Model4, sym) { - if (bits_left <= (QTMDStream.BITBUF_WIDTH - 16)) + range = (uint)((H - L) & 0xFFFF) + 1; + symf = (ushort)(((((C - L + 1) * qtm.Model4.Syms[0].CumulativeFrequency) - 1) / range) & 0xFFFF); + + for (i = 1; i < qtm.Model4.Entries; i++) { - READ_BYTES; + if (qtm.Model4.Syms[i].CumulativeFrequency <= symf) + break; } - bitrun = (byte)((bits_left < needed) ? bits_left : needed); + (sym) = qtm.Model4.Syms[i - 1].Sym; - int peek = (int)(bit_buffer >> (QTMDStream.BITBUF_WIDTH - (bitrun))); + range = (uint)(H - L) + 1; + symf = qtm.Model4.Syms[0].CumulativeFrequency; + H = (ushort)(L + ((qtm.Model4.Syms[i - 1].CumulativeFrequency * range) / symf) - 1); + L = (ushort)(L + ((qtm.Model4.Syms[i].CumulativeFrequency * range) / symf)); - extra = (uint)((extra << bitrun) | peek); + do + { + qtm.Model4.Syms[--i].CumulativeFrequency += 8; + } while (i > 0); - // REMOVE_BITS(bitrun); - bit_buffer <<= bitrun; - bits_left -= bitrun; + if (qtm.Model4.Syms[0].CumulativeFrequency > 3800) + UpdateModel(qtm.Model4); - needed -= bitrun; + while (true) + { + if ((L & 0x8000) != (H & 0x8000)) + { + if ((L & 0x4000) != 0 && (H & 0x4000) == 0) + { + // Underflow case + C ^= 0x4000; + L &= 0x3FFF; + H |= 0x4000; + } + else + { + break; + } + } + + L <<= 1; + H = (ushort)((H << 1) | 1); + + //ENSURE_BITS(1) + { + while (bits_left < (1)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } + } + + C = (ushort)((C << 1) | (bit_buffer >> (CompressionStream.BITBUF_WIDTH - (1)))); //PEEK_BITS(1) + + //REMOVE_BITS(1) + { + bit_buffer <<= (1); + bits_left -= (1); + } + } } - match_offset = position_base[sym] + extra + 1; + //READ_MANY_BITS(extra, extra_bits[sym]) + { + byte needed = (byte)(extra_bits[sym]), bitrun; + (extra) = 0; + while (needed > 0) + { + if ((bits_left) <= (CompressionStream.BITBUF_WIDTH - 16)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } + + bitrun = (byte)((bits_left < needed) ? bits_left : needed); + (extra) = (int)(((extra) << bitrun) | (bit_buffer >> (CompressionStream.BITBUF_WIDTH - (bitrun)))); //PEEK_BITS(bitrun) + + //REMOVE_BITS(bitrun) + { + bit_buffer <<= (bitrun); + bits_left -= (bitrun); + } + + needed -= bitrun; + } + } + + match_offset = (uint)(position_base[sym] + extra + 1); match_length = 3; break; // Selector 5 = fixed length match (4 bytes) case 5: - GET_SYMBOL(qtm, qtm.Model5, ref sym, ref range, ref symf, ref high, ref low, ref current, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left); - - // READ_MANY_BITS(extra, extra_bits[sym]) - needed = extra_bits[sym]; - extra = 0; - while (needed > 0) + //GET_SYMBOL(qtm.Model5, sym) { - if (bits_left <= (QTMDStream.BITBUF_WIDTH - 16)) + range = (uint)((H - L) & 0xFFFF) + 1; + symf = (ushort)(((((C - L + 1) * qtm.Model5.Syms[0].CumulativeFrequency) - 1) / range) & 0xFFFF); + + for (i = 1; i < qtm.Model5.Entries; i++) { - READ_BYTES; + if (qtm.Model5.Syms[i].CumulativeFrequency <= symf) + break; } - bitrun = (byte)((bits_left < needed) ? bits_left : needed); + (sym) = qtm.Model5.Syms[i - 1].Sym; - int peek = (int)(bit_buffer >> (QTMDStream.BITBUF_WIDTH - (bitrun))); + range = (uint)(H - L) + 1; + symf = qtm.Model5.Syms[0].CumulativeFrequency; + H = (ushort)(L + ((qtm.Model5.Syms[i - 1].CumulativeFrequency * range) / symf) - 1); + L = (ushort)(L + ((qtm.Model5.Syms[i].CumulativeFrequency * range) / symf)); - extra = (uint)((extra << bitrun) | peek); + do + { + qtm.Model5.Syms[--i].CumulativeFrequency += 8; + } while (i > 0); - // REMOVE_BITS(bitrun); - bit_buffer <<= bitrun; - bits_left -= bitrun; + if (qtm.Model5.Syms[0].CumulativeFrequency > 3800) + UpdateModel(qtm.Model5); - needed -= bitrun; + while (true) + { + if ((L & 0x8000) != (H & 0x8000)) + { + if ((L & 0x4000) != 0 && (H & 0x4000) == 0) + { + // Underflow case + C ^= 0x4000; + L &= 0x3FFF; + H |= 0x4000; + } + else + { + break; + } + } + + L <<= 1; + H = (ushort)((H << 1) | 1); + + //ENSURE_BITS(1) + { + while (bits_left < (1)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } + } + + C = (ushort)((C << 1) | (bit_buffer >> (CompressionStream.BITBUF_WIDTH - (1)))); //PEEK_BITS(1) + + //REMOVE_BITS(1) + { + bit_buffer <<= (1); + bits_left -= (1); + } + } } - match_offset = position_base[sym] + extra + 1; + //READ_MANY_BITS(extra, extra_bits[sym]) + { + byte needed = (byte)(extra_bits[sym]), bitrun; + (extra) = 0; + while (needed > 0) + { + if ((bits_left) <= (CompressionStream.BITBUF_WIDTH - 16)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } + + bitrun = (byte)((bits_left < needed) ? bits_left : needed); + (extra) = (int)(((extra) << bitrun) | (bit_buffer >> (CompressionStream.BITBUF_WIDTH - (bitrun)))); //PEEK_BITS(bitrun) + + //REMOVE_BITS(bitrun) + { + bit_buffer <<= (bitrun); + bits_left -= (bitrun); + } + + needed -= bitrun; + } + } + + match_offset = (uint)(position_base[sym] + extra + 1); match_length = 4; break; // Selector 6 = variable length match case 6: - GET_SYMBOL(qtm, qtm.Model6Len, ref sym, ref range, ref symf, ref high, ref low, ref current, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left); - - // READ_MANY_BITS(extra, length_extra[sym]) - needed = length_extra[sym]; - extra = 0; - while (needed > 0) + //GET_SYMBOL(qtm.Model6Len, sym) { - if (bits_left <= (QTMDStream.BITBUF_WIDTH - 16)) + range = (uint)((H - L) & 0xFFFF) + 1; + symf = (ushort)(((((C - L + 1) * qtm.Model6Len.Syms[0].CumulativeFrequency) - 1) / range) & 0xFFFF); + + for (i = 1; i < qtm.Model6Len.Entries; i++) { - READ_BYTES; + if (qtm.Model6Len.Syms[i].CumulativeFrequency <= symf) + break; } - bitrun = (byte)((bits_left < needed) ? bits_left : needed); + (sym) = qtm.Model6Len.Syms[i - 1].Sym; - int peek = (int)(bit_buffer >> (QTMDStream.BITBUF_WIDTH - (bitrun))); + range = (uint)(H - L) + 1; + symf = qtm.Model6Len.Syms[0].CumulativeFrequency; + H = (ushort)(L + ((qtm.Model6Len.Syms[i - 1].CumulativeFrequency * range) / symf) - 1); + L = (ushort)(L + ((qtm.Model6Len.Syms[i].CumulativeFrequency * range) / symf)); - extra = (uint)((extra << bitrun) | peek); + do + { + qtm.Model6Len.Syms[--i].CumulativeFrequency += 8; + } while (i > 0); - // REMOVE_BITS(bitrun); - bit_buffer <<= bitrun; - bits_left -= bitrun; + if (qtm.Model6Len.Syms[0].CumulativeFrequency > 3800) + UpdateModel(qtm.Model6Len); - needed -= bitrun; + while (true) + { + if ((L & 0x8000) != (H & 0x8000)) + { + if ((L & 0x4000) != 0 && (H & 0x4000) == 0) + { + // Underflow case + C ^= 0x4000; + L &= 0x3FFF; + H |= 0x4000; + } + else + { + break; + } + } + + L <<= 1; + H = (ushort)((H << 1) | 1); + + //ENSURE_BITS(1) + { + while (bits_left < (1)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } + } + + C = (ushort)((C << 1) | (bit_buffer >> (CompressionStream.BITBUF_WIDTH - (1)))); //PEEK_BITS(1) + + //REMOVE_BITS(1) + { + bit_buffer <<= (1); + bits_left -= (1); + } + } } - match_length = (int)(length_base[sym] + extra + 5); - - GET_SYMBOL(qtm, qtm.Model6, ref sym, ref range, ref symf, ref high, ref low, ref current, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left); - - // READ_MANY_BITS(extra, extra_bits[sym]) - needed = extra_bits[sym]; - extra = 0; - while (needed > 0) + //READ_MANY_BITS(extra, length_extra[sym]) { - if (bits_left <= (QTMDStream.BITBUF_WIDTH - 16)) + byte needed = (byte)(length_extra[sym]), bitrun; + (extra) = 0; + while (needed > 0) { - READ_BYTES; + if ((bits_left) <= (CompressionStream.BITBUF_WIDTH - 16)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } + + bitrun = (byte)((bits_left < needed) ? bits_left : needed); + (extra) = (int)(((extra) << bitrun) | (bit_buffer >> (CompressionStream.BITBUF_WIDTH - (bitrun)))); //PEEK_BITS(bitrun) + + //REMOVE_BITS(bitrun) + { + bit_buffer <<= (bitrun); + bits_left -= (bitrun); + } + + needed -= bitrun; + } + } + + match_length = length_base[sym] + extra + 5; + + //GET_SYMBOL(qtm.Model6, sym) + { + range = (uint)((H - L) & 0xFFFF) + 1; + symf = (ushort)(((((C - L + 1) * qtm.Model6.Syms[0].CumulativeFrequency) - 1) / range) & 0xFFFF); + + for (i = 1; i < qtm.Model6.Entries; i++) + { + if (qtm.Model6.Syms[i].CumulativeFrequency <= symf) + break; } - bitrun = (byte)((bits_left < needed) ? bits_left : needed); + (sym) = qtm.Model6.Syms[i - 1].Sym; - int peek = (int)(bit_buffer >> (QTMDStream.BITBUF_WIDTH - (bitrun))); + range = (uint)(H - L) + 1; + symf = qtm.Model6.Syms[0].CumulativeFrequency; + H = (ushort)(L + ((qtm.Model6.Syms[i - 1].CumulativeFrequency * range) / symf) - 1); + L = (ushort)(L + ((qtm.Model6.Syms[i].CumulativeFrequency * range) / symf)); - extra = (uint)((extra << bitrun) | peek); + do + { + qtm.Model6.Syms[--i].CumulativeFrequency += 8; + } while (i > 0); - // REMOVE_BITS(bitrun); - bit_buffer <<= bitrun; - bits_left -= bitrun; + if (qtm.Model6.Syms[0].CumulativeFrequency > 3800) + UpdateModel(qtm.Model6); - needed -= bitrun; + while (true) + { + if ((L & 0x8000) != (H & 0x8000)) + { + if ((L & 0x4000) != 0 && (H & 0x4000) == 0) + { + // Underflow case + C ^= 0x4000; + L &= 0x3FFF; + H |= 0x4000; + } + else + { + break; + } + } + + L <<= 1; + H = (ushort)((H << 1) | 1); + + //ENSURE_BITS(1) + { + while (bits_left < (1)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } + } + + C = (ushort)((C << 1) | (bit_buffer >> (CompressionStream.BITBUF_WIDTH - (1)))); //PEEK_BITS(1) + + //REMOVE_BITS(1) + { + bit_buffer <<= (1); + bits_left -= (1); + } + } } - match_offset = position_base[sym] + extra + 1; + //READ_MANY_BITS(extra, extra_bits[sym]) + { + byte needed = (byte)(extra_bits[sym]), bitrun; + (extra) = 0; + while (needed > 0) + { + if ((bits_left) <= (CompressionStream.BITBUF_WIDTH - 16)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } + + bitrun = (byte)((bits_left < needed) ? bits_left : needed); + (extra) = (int)(((extra) << bitrun) | (bit_buffer >> (CompressionStream.BITBUF_WIDTH - (bitrun)))); //PEEK_BITS(bitrun) + + //REMOVE_BITS(bitrun) + { + bit_buffer <<= (bitrun); + bits_left -= (bitrun); + } + + needed -= bitrun; + } + } + + match_offset = (uint)(position_base[sym] + extra + 1); break; default: // Should be impossible, model7 can only return 0-6 - Console.WriteLine("got %d from selector", selector); - return qtm.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + Console.WriteLine($"Got {selector} from selector"); + return qtm.Error = Error.MSPACK_ERR_DECRUNCH; } rundest = (int)window_posn; @@ -415,12 +1198,13 @@ namespace LibMSPackSharp.Compression // Does match destination wrap the window? This situation is possible // where the window size is less than the 32k frame size, but matches - // must not go beyond a frame boundary */ + // must not go beyond a frame boundary if ((window_posn + match_length) > qtm.WindowSize) { - /* copy first part of match, before window end */ + // Copy first part of match, before window end i = (int)(qtm.WindowSize - window_posn); j = (int)(window_posn - match_offset); + while (i-- != 0) { window[rundest++] = window[j++ & (qtm.WindowSize - 1)]; @@ -432,15 +1216,15 @@ namespace LibMSPackSharp.Compression // This should not happen, but if it does then this code // can't handle the situation (can't flush up to the end of // the window, but can't break out either because we haven't - // finished writing the match). bail out in this case */ + // finished writing the match). Bail out in this case if (i > out_bytes) { - Console.WriteLine($"during window-wrap match; {i} bytes to flush but only need {out_bytes}"); - return qtm.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + Console.WriteLine($"During window-wrap match; {i} bytes to flush but only need {out_bytes}"); + return qtm.Error = Error.MSPACK_ERR_DECRUNCH; } - if (qtm.Sys.Write(qtm.Output, qtm.Window, qtm.OutputPointer, i) != i) - return qtm.Error = LibMSPackSharp.Error.MSPACK_ERR_WRITE; + if (qtm.Sys.Write(qtm.Output, window, qtm.OutputPointer, i) != i) + return qtm.Error = Error.MSPACK_ERR_WRITE; out_bytes -= i; qtm.OutputPointer = 0; @@ -470,8 +1254,8 @@ namespace LibMSPackSharp.Compression j = (int)(match_offset - window_posn); if (j > (int)qtm.WindowSize) { - Console.WriteLine("match offset beyond window boundaries"); - return qtm.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + Console.WriteLine("Match offset beyond window boundaries"); + return qtm.Error = Error.MSPACK_ERR_DECRUNCH; } runsrc = (int)(qtm.WindowSize - j); @@ -509,11 +1293,11 @@ namespace LibMSPackSharp.Compression qtm.OutputLength = (int)window_posn; // If we subtracted too much from frame_todo, it will - // wrap around past zero and go above its max value */ + // wrap around past zero and go above its max value if (frame_todo > QTM_FRAME_SIZE) { - Console.WriteLine("overshot frame alignment"); - return qtm.Error = LibMSPackSharp.Error.MSPACK_ERR_DECRUNCH; + Console.WriteLine("Overshot frame alignment"); + return qtm.Error = Error.MSPACK_ERR_DECRUNCH; } // Another frame completed? @@ -522,29 +1306,70 @@ namespace LibMSPackSharp.Compression // Re-align input if ((bits_left & 7) != 0) { - //REMOVE_BITS(bits_left & 7); - bit_buffer <<= bits_left & 7; - bits_left -= bits_left & 7; + //REMOVE_BITS(bits_left & 7) + { + bit_buffer <<= (bits_left & 7); + bits_left -= (bits_left & 7); + } } // Special Quantum hack -- cabd.c injects a trailer byte to allow the // decompressor to realign itself. CAB Quantum blocks, unlike LZX - // blocks, can have anything from 0 to 4 trailing null bytes. */ + // blocks, can have anything from 0 to 4 trailing null bytes. do { //READ_BITS(i, 8) { //ENSURE_BITS(8) - while (bits_left < (8)) { - READ_BYTES; + while (bits_left < (8)) + { + //READ_BYTES + { + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b0 = qtm.InputBuffer[i_ptr++]; + + //READ_IF_NEEDED + { + if (i_ptr >= i_end) + { + if (qtm.ReadInput() != Error.MSPACK_ERR_OK) + return qtm.Error; + + i_ptr = qtm.InputPointer; + i_end = qtm.InputLength; + } + } + + byte b1 = qtm.InputBuffer[i_ptr++]; + + //INJECT_BITS(bitdata, 16) + { + bit_buffer |= (uint)((b0 << 8) | b1) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left); + bits_left += (16); + } + } + } } - i = (int)(bit_buffer >> (BITBUF_WIDTH - (8))); + (i) = (int)(bit_buffer >> (CompressionStream.BITBUF_WIDTH - (8))); //PEEK_BITS(8) - // REMOVE_BITS(8); - bit_buffer <<= (8); - bits_left -= (8); + //REMOVE_BITS(8) + { + bit_buffer <<= (8); + bits_left -= (8); + } } } while (i != 0xFF); @@ -563,21 +1388,23 @@ namespace LibMSPackSharp.Compression if (i >= out_bytes) break; - if (qtm.Sys.Write(qtm.Output, qtm.Window, qtm.OutputPointer, i) != i) - return qtm.Error = LibMSPackSharp.Error.MSPACK_ERR_WRITE; + if (qtm.Sys.Write(qtm.Output, window, qtm.OutputPointer, i) != i) + return qtm.Error = Error.MSPACK_ERR_WRITE; out_bytes -= i; qtm.OutputPointer = 0; qtm.OutputLength = 0; window_posn = 0; } + } if (out_bytes != 0) { i = (int)out_bytes; - if (qtm.Sys.Write(qtm.Output, qtm.Window, qtm.OutputPointer, i) != i) - return qtm.Error = LibMSPackSharp.Error.MSPACK_ERR_WRITE; + + if (qtm.Sys.Write(qtm.Output, window, qtm.OutputPointer, i) != i) + return qtm.Error = Error.MSPACK_ERR_WRITE; qtm.OutputPointer += i; } @@ -585,91 +1412,20 @@ namespace LibMSPackSharp.Compression // Store local state //STORE_BITS - qtm.InputPointer = i_ptr; - qtm.InputLength = i_end; - qtm.BitBuffer = bit_buffer; - qtm.BitsLeft = bits_left; + { + qtm.InputPointer = i_ptr; + qtm.InputLength = i_end; + qtm.BitBuffer = bit_buffer; + qtm.BitsLeft = bits_left; + } qtm.WindowPosition = window_posn; qtm.FrameTODO = frame_todo; - qtm.High = high; - qtm.Low = low; - qtm.Current = (ushort)current; + qtm.High = H; + qtm.Low = L; + qtm.Current = C; - return LibMSPackSharp.Error.MSPACK_ERR_OK; - } - - /// - /// Arithmetic decoder: - /// - /// GET_SYMBOL(model, var) fetches the next symbol from the stated model - /// and puts it in var. - /// - /// If necessary, qtmd_update_model() is called. - /// - private static void GET_SYMBOL(QTMDStream qtm, QTMDModel model, ref int var, ref uint range, ref ushort symf, ref ushort high, ref ushort low, ref ushort current, - ref int i_ptr, ref int i_end, ref uint bit_buffer, ref int bits_left) - { - range = (uint)(((high - low) & 0xFFFF) + 1); - symf = (ushort)(((((current - low + 1) * model.Syms[0].CumulativeFrequency) - 1) / range) & 0xFFFF); - - int i; - for (i = 1; i < model.Entries; i++) - { - if (model.Syms[i].CumulativeFrequency <= symf) - break; - } - - var = model.Syms[i - 1].Sym; - - range = (ushort)((high - low) + 1); - symf = model.Syms[0].CumulativeFrequency; - high = (ushort)(low + ((model.Syms[i - 1].CumulativeFrequency * range) / symf) - 1); - low = (ushort)(low + ((model.Syms[i].CumulativeFrequency * range) / symf)); - - do - { - model.Syms[--i].CumulativeFrequency += 8; - } while (i > 0); - - if (model.Syms[0].CumulativeFrequency > 3800) - UpdateModel(model); - - while (true) - { - if ((low & 0x8000) != (high & 0x8000)) - { - // Underflow case - if ((low & 0x4000) != 0 && (high & 0x4000) == 0) - { - current ^= 0x4000; - low &= 0x3FFF; - high |= 0x4000; - } - else - { - break; - } - } - - low <<= 1; - high = (ushort)((high << 1) | 1); - - // ENSURE_BITS(1) - while (bits_left < 1) - { - READ_BYTES; - } - - if (qtm.Error != LibMSPackSharp.Error.MSPACK_ERR_OK) - return; - - current = (ushort)((current << 1) | (bit_buffer >> (LZXDStream.BITBUF_WIDTH - (1)))); //PEEK_BITS(1) - - //REMOVE_BITS(1); - bit_buffer <<= (1); - bits_left -= (1); - } + return Error.MSPACK_ERR_OK; } private static void UpdateModel(QTMDModel model) @@ -681,12 +1437,10 @@ namespace LibMSPackSharp.Compression { for (i = model.Entries - 1; i >= 0; i--) { - /* -1, not -2; the 0 entry saves this */ + // -1, not -2; the 0 entry saves this model.Syms[i].CumulativeFrequency >>= 1; if (model.Syms[i].CumulativeFrequency <= model.Syms[i + 1].CumulativeFrequency) - { model.Syms[i].CumulativeFrequency = (ushort)(model.Syms[i + 1].CumulativeFrequency + 1); - } } } else diff --git a/BurnOutSharp/External/libmspack/Compression/QTMDStream.cs b/BurnOutSharp/External/libmspack/Compression/QTMDStream.cs index ee1a39c6..6132645b 100644 --- a/BurnOutSharp/External/libmspack/Compression/QTMDStream.cs +++ b/BurnOutSharp/External/libmspack/Compression/QTMDStream.cs @@ -120,6 +120,6 @@ namespace LibMSPackSharp.Compression public QTMDModelSym[] Model7Symbols { get; set; } = new QTMDModelSym[7 + 1]; - public override int HUFF_ERROR() => (int)LibMSPackSharp.Error.MSPACK_ERR_OK; + public override int HUFF_ERROR() => (int)Error.MSPACK_ERR_OK; } }