diff --git a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs
index b54a0910..1d01bc06 100644
--- a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs
+++ b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs
@@ -61,7 +61,6 @@ namespace LibMSPackSharp.Compression
#endregion
- // TODO: These should be in a separate file
#region ReadBits Methods
/* This header defines macros that read data streams by
@@ -369,182 +368,10 @@ namespace LibMSPackSharp.Compression
#endregion
- // TODO: These should be in a separate file
#region ReadHuff Methods
#region Common
- ///
- /// This function was originally coded by David Tritscher.
- ///
- /// It builds a fast huffman decoding table from
- /// a canonical huffman code lengths table.
- ///
- /// total number of symbols in this huffman tree.
- /// any symbols with a code length of nbits or less can be decoded in one lookup of the table.
- /// A table to get code lengths from [0 to nsyms-1]
- ///
- /// The table to fill up with decoded symbols and pointers.
- /// Should be ((1<
- /// true for OK or false for error
- /// TODO: Split into MSB and LSB variants
- public static bool MakeDecodeTable(int nsyms, int nbits, byte[] length, ushort[] table, bool msb)
- {
- ushort sym, next_symbol;
- uint leaf, fill;
- uint reverse; // Only used when !msb
- byte bit_num;
- uint pos = 0; // The current position in the decode table
- uint table_mask = (uint)1 << nbits;
- uint bit_mask = table_mask >> 1; // Don't do 0 length codes
-
- // Fill entries for codes short enough for a direct mapping
- for (bit_num = 1; bit_num <= nbits; bit_num++)
- {
- for (sym = 0; sym < nsyms; sym++)
- {
- if (length[sym] != bit_num)
- continue;
-
- if (msb)
- {
- leaf = pos;
- }
- else
- {
- // Reverse the significant bits
- fill = length[sym];
- reverse = pos >> (nbits - (byte)fill);
- leaf = 0;
-
- do
- {
- leaf <<= 1;
- leaf |= reverse & 1;
- reverse >>= 1;
- } while (--fill != 0);
- }
-
- if ((pos += bit_mask) > table_mask)
- return false; // Table overrun
-
- // Fill all possible lookups of this symbol with the symbol itself
- if (msb)
- {
- for (fill = bit_mask; fill-- > 0;)
- {
- table[leaf++] = sym;
- }
- }
- else
- {
- fill = bit_mask;
- next_symbol = (ushort)(1 << bit_num);
-
- do
- {
- table[leaf] = sym;
- leaf += next_symbol;
- } while (--fill != 0);
- }
- }
-
- bit_mask >>= 1;
- }
-
- // Exit with success if table is now complete
- if (pos == table_mask)
- return true;
-
- // Mark all remaining table entries as unused
- for (sym = (ushort)pos; sym < table_mask; sym++)
- {
- if (msb)
- {
- table[sym] = 0xFFFF;
- }
- else
- {
- reverse = sym;
- leaf = 0;
- fill = (uint)nbits;
-
- do
- {
- leaf <<= 1;
- leaf |= reverse & 1;
- reverse >>= 1;
- } while (--fill != 0);
-
- table[leaf] = 0xFFFF;
- }
- }
-
- // next_symbol = base of allocation for long codes
- next_symbol = ((table_mask >> 1) < nsyms) ? (ushort)nsyms : (ushort)(table_mask >> 1);
-
- // Give ourselves room for codes to grow by up to 16 more bits.
- // codes now start at bit nbits+16 and end at (nbits+16-codelength)
- pos <<= 16;
- table_mask <<= 16;
- bit_mask = 1 << 15;
-
- for (bit_num = (byte)(nbits + 1); bit_num <= HUFF_MAXBITS; bit_num++)
- {
- for (sym = 0; sym < nsyms; sym++)
- {
- if (length[sym] != bit_num)
- continue;
- if (pos >= table_mask)
- return false; // Table overflow
-
- if (msb)
- {
- leaf = pos >> 16;
- }
- else
- {
- // leaf = the first nbits of the code, reversed
- reverse = pos >> 16;
- leaf = 0;
- fill = (uint)nbits;
-
- do
- {
- leaf <<= 1;
- leaf |= reverse & 1;
- reverse >>= 1;
- } while (--fill != 0);
- }
-
- for (fill = 0; fill < (bit_num - nbits); fill++)
- {
- // If this path hasn't been taken yet, 'allocate' two entries
- if (table[leaf] == 0xFFFF)
- {
- table[(next_symbol << 1)] = 0xFFFF;
- table[(next_symbol << 1) + 1] = 0xFFFF;
- table[leaf] = (ushort)next_symbol++;
- }
-
- // Follow the path and select either left or right for next bit
- leaf = (uint)(table[leaf] << 1);
- if (((pos >> (15 - (int)fill)) & 1) != 0)
- leaf++;
- }
-
- table[leaf] = sym;
- pos += bit_mask;
- }
-
- bit_mask >>= 1;
- }
-
- // Full table?
- return pos == table_mask;
- }
-
///
/// Per compression error code for decoding failure
///
@@ -587,6 +414,107 @@ namespace LibMSPackSharp.Compression
} while (sym >= maxsymbols);
}
+ ///
+ /// This function was originally coded by David Tritscher.
+ ///
+ /// It builds a fast huffman decoding table from
+ /// a canonical huffman code lengths table.
+ ///
+ /// total number of symbols in this huffman tree.
+ /// any symbols with a code length of nbits or less can be decoded in one lookup of the table.
+ /// A table to get code lengths from [0 to nsyms-1]
+ ///
+ /// The table to fill up with decoded symbols and pointers.
+ /// Should be ((1<
+ /// True for OK or false for error
+ public static bool MakeDecodeTableMSB(int nsyms, int nbits, byte[] length, ushort[] table)
+ {
+ ushort sym, next_symbol;
+ uint leaf, fill;
+ byte bit_num;
+ uint pos = 0; // The current position in the decode table
+ uint table_mask = (uint)1 << nbits;
+ uint bit_mask = table_mask >> 1; // Don't do 0 length codes
+
+ // Fill entries for codes short enough for a direct mapping
+ for (bit_num = 1; bit_num <= nbits; bit_num++)
+ {
+ for (sym = 0; sym < nsyms; sym++)
+ {
+ if (length[sym] != bit_num)
+ continue;
+
+ leaf = pos;
+ if ((pos += bit_mask) > table_mask)
+ return false; // Table overrun
+
+ // Fill all possible lookups of this symbol with the symbol itself
+ for (fill = bit_mask; fill-- > 0;)
+ {
+ table[leaf++] = sym;
+ }
+ }
+
+ bit_mask >>= 1;
+ }
+
+ // Exit with success if table is now complete
+ if (pos == table_mask)
+ return true;
+
+ // Mark all remaining table entries as unused
+ for (sym = (ushort)pos; sym < table_mask; sym++)
+ {
+ table[sym] = 0xFFFF;
+ }
+
+ // next_symbol = base of allocation for long codes
+ next_symbol = ((table_mask >> 1) < nsyms) ? (ushort)nsyms : (ushort)(table_mask >> 1);
+
+ // Give ourselves room for codes to grow by up to 16 more bits.
+ // codes now start at bit nbits+16 and end at (nbits+16-codelength)
+ pos <<= 16;
+ table_mask <<= 16;
+ bit_mask = 1 << 15;
+
+ for (bit_num = (byte)(nbits + 1); bit_num <= HUFF_MAXBITS; bit_num++)
+ {
+ for (sym = 0; sym < nsyms; sym++)
+ {
+ if (length[sym] != bit_num)
+ continue;
+ if (pos >= table_mask)
+ return false; // Table overflow
+
+ leaf = pos >> 16;
+ for (fill = 0; fill < (bit_num - nbits); fill++)
+ {
+ // If this path hasn't been taken yet, 'allocate' two entries
+ if (table[leaf] == 0xFFFF)
+ {
+ table[(next_symbol << 1)] = 0xFFFF;
+ table[(next_symbol << 1) + 1] = 0xFFFF;
+ table[leaf] = next_symbol++;
+ }
+
+ // Follow the path and select either left or right for next bit
+ leaf = (uint)(table[leaf] << 1);
+ if (((pos >> (15 - (int)fill)) & 1) != 0)
+ leaf++;
+ }
+
+ table[leaf] = sym;
+ pos += bit_mask;
+ }
+
+ bit_mask >>= 1;
+ }
+
+ // Full table?
+ return pos == table_mask;
+ }
+
#endregion
#region LSB
@@ -624,6 +552,145 @@ namespace LibMSPackSharp.Compression
} while (sym >= maxsymbols);
}
+ ///
+ /// This function was originally coded by David Tritscher.
+ ///
+ /// It builds a fast huffman decoding table from
+ /// a canonical huffman code lengths table.
+ ///
+ /// total number of symbols in this huffman tree.
+ /// any symbols with a code length of nbits or less can be decoded in one lookup of the table.
+ /// A table to get code lengths from [0 to nsyms-1]
+ ///
+ /// The table to fill up with decoded symbols and pointers.
+ /// Should be ((1<
+ /// True for OK or false for error
+ public static bool MakeDecodeTableLSB(int nsyms, int nbits, byte[] length, ushort[] table)
+ {
+ ushort sym, next_symbol;
+ uint leaf, fill;
+ uint reverse;
+ byte bit_num;
+ uint pos = 0; // The current position in the decode table
+ uint table_mask = (uint)1 << nbits;
+ uint bit_mask = table_mask >> 1; // Don't do 0 length codes
+
+ // Fill entries for codes short enough for a direct mapping
+ for (bit_num = 1; bit_num <= nbits; bit_num++)
+ {
+ for (sym = 0; sym < nsyms; sym++)
+ {
+ if (length[sym] != bit_num)
+ continue;
+
+ // Reverse the significant bits
+ fill = length[sym];
+ reverse = pos >> (int)(nbits - fill);
+ leaf = 0;
+
+ do
+ {
+ leaf <<= 1;
+ leaf |= reverse & 1;
+ reverse >>= 1;
+ } while (--fill != 0);
+
+ if ((pos += bit_mask) > table_mask)
+ return false; // Table overrun
+
+ // Fill all possible lookups of this symbol with the symbol itself
+ fill = bit_mask;
+ next_symbol = (ushort)(1 << bit_num);
+
+ do
+ {
+ table[leaf] = sym;
+ leaf += next_symbol;
+ } while (--fill != 0);
+ }
+
+ bit_mask >>= 1;
+ }
+
+ // Exit with success if table is now complete
+ if (pos == table_mask)
+ return true;
+
+ // Mark all remaining table entries as unused
+ for (sym = (ushort)pos; sym < table_mask; sym++)
+ {
+ reverse = sym;
+ leaf = 0;
+ fill = (uint)nbits;
+
+ do
+ {
+ leaf <<= 1;
+ leaf |= reverse & 1;
+ reverse >>= 1;
+ } while (--fill != 0);
+
+ table[leaf] = 0xFFFF;
+ }
+
+ // next_symbol = base of allocation for long codes
+ next_symbol = ((table_mask >> 1) < nsyms) ? (ushort)nsyms : (ushort)(table_mask >> 1);
+
+ // Give ourselves room for codes to grow by up to 16 more bits.
+ // codes now start at bit nbits+16 and end at (nbits+16-codelength)
+ pos <<= 16;
+ table_mask <<= 16;
+ bit_mask = 1 << 15;
+
+ for (bit_num = (byte)(nbits + 1); bit_num <= HUFF_MAXBITS; bit_num++)
+ {
+ for (sym = 0; sym < nsyms; sym++)
+ {
+ if (length[sym] != bit_num)
+ continue;
+ if (pos >= table_mask)
+ return false; // Table overflow
+
+ // leaf = the first nbits of the code, reversed
+ reverse = pos >> 16;
+ leaf = 0;
+ fill = (uint)nbits;
+
+ do
+ {
+ leaf <<= 1;
+ leaf |= reverse & 1;
+ reverse >>= 1;
+ } while (--fill != 0);
+
+ for (fill = 0; fill < (bit_num - nbits); fill++)
+ {
+ // If this path hasn't been taken yet, 'allocate' two entries
+ if (table[leaf] == 0xFFFF)
+ {
+ table[(next_symbol << 1)] = 0xFFFF;
+ table[(next_symbol << 1) + 1] = 0xFFFF;
+ table[leaf] = (ushort)next_symbol++;
+ }
+
+ // Follow the path and select either left or right for next bit
+ leaf = (uint)(table[leaf] << 1);
+ if (((pos >> (15 - (int)fill)) & 1) != 0)
+ leaf++;
+ }
+
+ table[leaf] = sym;
+ pos += bit_mask;
+ }
+
+ bit_mask >>= 1;
+ }
+
+ // Full table?
+ return pos == table_mask;
+ }
+
#endregion
#endregion
diff --git a/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs b/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs
index 7efac2fc..b72977ea 100644
--- a/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs
+++ b/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs
@@ -152,7 +152,7 @@ namespace LibMSPackSharp.Compression
lzh.RESTORE_BITS(out i_ptr, out i_end, out bit_buffer, out bits_left);
- if (!CompressionStream.MakeDecodeTable(maxsymbols, tablebits, lengths, table, msb: true))
+ if (!CompressionStream.MakeDecodeTableMSB(maxsymbols, tablebits, lengths, table))
return Error.MSPACK_ERR_DATAFORMAT;
return Error.MSPACK_ERR_OK;
diff --git a/BurnOutSharp/External/libmspack/Compression/LZX.cs b/BurnOutSharp/External/libmspack/Compression/LZX.cs
index c5bd6e33..667a6c09 100644
--- a/BurnOutSharp/External/libmspack/Compression/LZX.cs
+++ b/BurnOutSharp/External/libmspack/Compression/LZX.cs
@@ -1039,7 +1039,7 @@ namespace LibMSPackSharp.Compression
private static Error BUILD_TABLE(LZXDStream lzx, ushort[] table, byte[] lengths, int tablebits, int maxsymbols)
{
- if (!CompressionStream.MakeDecodeTable(maxsymbols, tablebits, lengths, table, msb: true))
+ if (!CompressionStream.MakeDecodeTableMSB(maxsymbols, tablebits, lengths, table))
{
Console.WriteLine($"Failed to build table");
return lzx.Error = Error.MSPACK_ERR_DECRUNCH;
@@ -1051,7 +1051,7 @@ namespace LibMSPackSharp.Compression
private static Error BUILD_TABLE_MAYBE_EMPTY(LZXDStream lzx)
{
lzx.LENGTH_empty = 0;
- if (!CompressionStream.MakeDecodeTable(LZX_LENGTH_MAXSYMBOLS, LZX_LENGTH_TABLEBITS, lzx.LENGTH_len, lzx.LENGTH_table, msb: true))
+ if (!CompressionStream.MakeDecodeTableMSB(LZX_LENGTH_MAXSYMBOLS, LZX_LENGTH_TABLEBITS, lzx.LENGTH_len, lzx.LENGTH_table))
{
for (int i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++)
{
diff --git a/BurnOutSharp/External/libmspack/Compression/MSZIP.cs b/BurnOutSharp/External/libmspack/Compression/MSZIP.cs
index 5ef4e4ec..6009411d 100644
--- a/BurnOutSharp/External/libmspack/Compression/MSZIP.cs
+++ b/BurnOutSharp/External/libmspack/Compression/MSZIP.cs
@@ -360,7 +360,7 @@ namespace LibMSPackSharp.Compression
}
// Create decoding table with an immediate lookup
- if (!CompressionStream.MakeDecodeTable(19, 7, bl_len, bl_table, msb: false))
+ if (!CompressionStream.MakeDecodeTableLSB(19, 7, bl_len, bl_table))
return Error.INF_ERR_BITLENTBL;
// Read literal / distance code lengths
@@ -565,10 +565,10 @@ namespace LibMSPackSharp.Compression
// Now huffman lengths are read for either kind of block,
// create huffman decoding tables
- if (!CompressionStream.MakeDecodeTable(MSZIP_LITERAL_MAXSYMBOLS, MSZIP_LITERAL_TABLEBITS, zip.LITERAL_len, zip.LITERAL_table, msb: false))
+ if (!CompressionStream.MakeDecodeTableLSB(MSZIP_LITERAL_MAXSYMBOLS, MSZIP_LITERAL_TABLEBITS, zip.LITERAL_len, zip.LITERAL_table))
return Error.INF_ERR_LITERALTBL;
- if (!CompressionStream.MakeDecodeTable(MSZIP_DISTANCE_MAXSYMBOLS, MSZIP_DISTANCE_TABLEBITS, zip.DISTANCE_len, zip.DISTANCE_table, msb: false))
+ if (!CompressionStream.MakeDecodeTableLSB(MSZIP_DISTANCE_MAXSYMBOLS, MSZIP_DISTANCE_TABLEBITS, zip.DISTANCE_len, zip.DISTANCE_table))
return Error.INF_ERR_DISTANCETBL;
// Decode forever until end of block code