Continue demacroification (nw)

This commit is contained in:
Matt Nadareski
2022-05-20 22:29:43 -07:00
parent 08c97d291e
commit f34b1ba5cf
10 changed files with 2083 additions and 758 deletions

View File

@@ -19,7 +19,7 @@ namespace LibMSPackSharp.Compression
{
private const int CHAR_BIT = 8;
private const int BITBUF_WIDTH = 4 * CHAR_BIT;
public const int BITBUF_WIDTH = 4 * CHAR_BIT;
/// <summary>
/// I/O routines
@@ -132,150 +132,39 @@ namespace LibMSPackSharp.Compression
* to the bit buffer when the bit buffer already has 1 to 15 bits left.
*/
public void INIT_BITS()
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)
{
InputPointer = 0;
InputLength = 0;
BitBuffer = 0;
BitsLeft = 0;
InputEnd = 0;
}
public void STORE_BITS(int inputPointer, int inputLength, uint bit_buffer, int bits_left)
{
InputPointer = inputPointer;
InputLength = inputLength;
BitBuffer = bit_buffer;
BitsLeft = bits_left;
}
public void RESTORE_BITS(ref int inputPointer, ref int inputLength, ref uint bit_buffer, ref int bits_left)
{
inputPointer = InputPointer;
inputLength = InputLength;
bit_buffer = BitBuffer;
bits_left = BitsLeft;
}
public void ENSURE_BITS(int nbits, ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer, bool msb)
{
while (bits_left < nbits)
//READ_BITS(val, nbits)
{
READ_BYTES(ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb);
if (Error != Error.MSPACK_ERR_OK)
return;
}
Error = Error.MSPACK_ERR_OK;
}
public void READ_BITS(ref int val, int nbits, ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer, bool msb)
{
ENSURE_BITS(nbits, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb);
if (Error != Error.MSPACK_ERR_OK)
return;
val = PEEK_BITS(nbits, bit_buffer, msb);
REMOVE_BITS(nbits, ref bits_left, ref bit_buffer, msb);
Error = Error.MSPACK_ERR_OK;
}
public void READ_MANY_BITS(ref uint val, byte bits, ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer, bool msb)
{
byte needed = bits, bitrun;
val = 0;
while (needed > 0)
{
if (bits_left <= (BITBUF_WIDTH - 16))
//ENSURE_BITS(nbits)
while (bits_left < (nbits))
{
READ_BYTES(ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb);
if (Error != Error.MSPACK_ERR_OK)
return;
READ_BYTES;
}
bitrun = (byte)((bits_left < needed) ? bits_left : needed);
val = (uint)((val << bitrun) | PEEK_BITS(bitrun, bit_buffer, msb));
REMOVE_BITS(bitrun, ref bits_left, ref bit_buffer, msb);
needed -= bitrun;
val = (int)(bit_buffer >> (BITBUF_WIDTH - (nbits)));
// REMOVE_BITS(nbits);
bit_buffer <<= (nbits);
bits_left -= (nbits);
}
Error = Error.MSPACK_ERR_OK;
}
public int PEEK_BITS(int nbits, uint bit_buffer, bool msb)
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)
{
if (msb)
return (int)(bit_buffer >> (BITBUF_WIDTH - (nbits)));
else
return (int)(bit_buffer & ((1 << (nbits)) - 1));
}
//READ_BITS(val, nbits)
public void REMOVE_BITS(int nbits, ref int bits_left, ref uint bit_buffer, bool msb)
{
if (msb)
//ENSURE_BITS(nbits)
while (bits_left < nbits)
{
bit_buffer <<= nbits;
bits_left -= nbits;
}
else
{
bit_buffer >>= nbits;
bits_left -= nbits;
}
}
public void INJECT_BITS(uint bitdata, int nbits, ref int bits_left, ref uint bit_buffer, bool msb)
{
if (msb)
{
bit_buffer |= bitdata << (int)bits_left;
bits_left += nbits;
}
else
{
bit_buffer |= bitdata << (int)bits_left;
bits_left += nbits;
}
}
public abstract void READ_BYTES(ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer, bool msb);
// lsb_bit_mask[n] = (1 << n) - 1 */
private static readonly ushort[] lsb_bit_mask = new ushort[17]
{
0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
};
public int PEEK_BITS_T(int nbits)
{
return (int)(BitBuffer & lsb_bit_mask[nbits]);
}
public void READ_BITS_T(ref int val, int nbits, ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer, bool msb)
{
ENSURE_BITS(nbits, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb);
if (Error != Error.MSPACK_ERR_OK)
return;
val = PEEK_BITS_T(nbits);
REMOVE_BITS(nbits, ref bits_left, ref bit_buffer, msb);
Error = Error.MSPACK_ERR_OK;
}
public void READ_IF_NEEDED(ref int i_ptr, ref int i_end)
{
if (i_ptr >= i_end)
{
ReadInput();
if (Error != Error.MSPACK_ERR_OK)
return;
i_ptr = InputPointer;
i_end = InputLength;
READ_BYTES;
}
Error = Error.MSPACK_ERR_OK;
val = (int)(bit_buffer & ((1 << (nbits)) - 1));
//REMOVE_BITS(nbits);
bit_buffer >>= (nbits);
bits_left -= (nbits);
}
public Error ReadInput()
@@ -319,11 +208,22 @@ namespace LibMSPackSharp.Compression
/// </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, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb);
// ENSURE_BITS(HUFF_MAXBITS)
while (bits_left < HUFF_MAXBITS)
{
READ_BYTES;
}
if (Error != Error.MSPACK_ERR_OK)
return (int)Error;
ushort sym = decodingTable[PEEK_BITS(tablebits, bit_buffer, msb)];
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);
@@ -333,7 +233,19 @@ namespace LibMSPackSharp.Compression
var = sym;
i = lengthTable[sym];
REMOVE_BITS(i, ref bits_left, ref bit_buffer, msb);
// REMOVE_BITS(i);
if (msb)
{
bit_buffer <<= i;
bits_left -= i;
}
else
{
bit_buffer >>= i;
bits_left -= i;
}
return (int)Error.MSPACK_ERR_OK;
}

View File

@@ -56,115 +56,116 @@ namespace LibMSPackSharp.Compression
/// </param>
/// <param name="mode">one of LZSSMode values</param>
/// <returns>an error code, or MSPACK_ERR_OK if successful</returns>
public static Error Decompress(SystemImpl system, FileStream input, FileStream output, int inputBufferSize, LZSSMode mode)
public static Error Decompress(SystemImpl system, FileStream input, FileStream output, int input_buffer_size, LZSSMode mode)
{
uint i, c, mpos, len;
int read;
// Check parameters
if (system == null
|| inputBufferSize < 1
|| (mode != LZSSMode.LZSS_MODE_EXPAND && mode != LZSSMode.LZSS_MODE_MSHELP && mode != LZSSMode.LZSS_MODE_QBASIC))
{
if (system == null || input_buffer_size < 1 || (mode != LZSSMode.LZSS_MODE_EXPAND && mode != LZSSMode.LZSS_MODE_MSHELP && mode != LZSSMode.LZSS_MODE_QBASIC))
return Error.MSPACK_ERR_ARGS;
}
// Allocate memory
byte[] window = new byte[LZSS_WINDOW_SIZE + inputBufferSize];
byte[] window = new byte[LZSS_WINDOW_SIZE + input_buffer_size];
// Initialise decompression
int inbuf = LZSS_WINDOW_SIZE;
for (i = 0; i < LZSS_WINDOW_SIZE; i++)
for (int j = inbuf; j < window.Length; j++)
{
window[i] = LZSS_WINDOW_FILL;
window[j] = LZSS_WINDOW_FILL;
}
uint pos = LZSS_WINDOW_SIZE - (uint)((mode == LZSSMode.LZSS_MODE_QBASIC) ? 18 : 16);
uint invert = (uint)((mode == LZSSMode.LZSS_MODE_MSHELP) ? ~0 : 0);
int i_ptr = 0, i_end = 0;
int i_ptr = 0, i_end = 0, read;
// Loop forever; exit condition is in ENSURE_BYTES macro
for (; ; )
{
//ENSURE_BYTES
if (i_ptr >= i_end)
{
read = system.Read(input, window, inbuf, inputBufferSize);
if (read <= 0)
return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK;
if (i_ptr >= i_end)
{
read = input.Read(window, inbuf, input_buffer_size);
if (read <= 0)
return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK;
i_ptr = 0;
i_end = read;
i_ptr = inbuf;
i_end = read;
}
}
c = window[i_ptr++] ^ invert;
for (i = 0x01; (i & 0xFF) != 0; i <<= 1)
uint c = window[i_ptr++] ^ invert;
for (uint i = 0x01; (i & 0xFF) != 0; i <<= 1)
{
// Literal
if (c != 0 & i != 0)
{
// Literal
//ENSURE_BYTES
if (i_ptr >= i_end)
{
read = system.Read(input, window, inbuf, inputBufferSize);
if (read <= 0)
return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK;
if (i_ptr >= i_end)
{
read = input.Read(window, inbuf, input_buffer_size);
if (read <= 0)
return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK;
i_ptr = 0;
i_end = read;
i_ptr = inbuf;
i_end = read;
}
}
window[pos] = window[i_ptr++];
//ENSURE_BYTES
if (i_ptr >= i_end)
//WRITE_BYTE
{
read = system.Read(input, window, inbuf, inputBufferSize);
if (read <= 0)
return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK;
i_ptr = 0;
i_end = read;
try { output.Write(window, (int)pos, 1); }
catch { return Error.MSPACK_ERR_WRITE; }
}
pos++; pos &= LZSS_WINDOW_SIZE - 1;
pos++;
pos &= LZSS_WINDOW_SIZE - 1;
}
// Match
else
{
// Match
//ENSURE_BYTES
if (i_ptr >= i_end)
{
read = system.Read(input, window, inbuf, inputBufferSize);
if (read <= 0)
return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK;
if (i_ptr >= i_end)
{
read = input.Read(window, inbuf, input_buffer_size);
if (read <= 0)
return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK;
i_ptr = 0;
i_end = read;
i_ptr = inbuf;
i_end = read;
}
}
mpos = window[i_ptr++];
uint mpos = window[i_ptr++];
//ENSURE_BYTES
if (i_ptr >= i_end)
{
read = system.Read(input, window, inbuf, inputBufferSize);
if (read <= 0)
return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK;
if (i_ptr >= i_end)
{
read = input.Read(window, inbuf, input_buffer_size);
if (read <= 0)
return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK;
i_ptr = 0;
i_end = read;
i_ptr = inbuf;
i_end = read;
}
}
mpos |= (uint)(window[i_ptr] & 0xF0) << 4;
len = (uint)(window[i_ptr++] & 0x0F) + 3;
uint len = (uint)(window[i_ptr++] & 0x0F) + 3;
while (len-- != 0)
{
window[pos] = window[mpos];
//WRITE_BYTE;
if (system.Write(output, window, (int)pos, 1) != 1)
return Error.MSPACK_ERR_WRITE;
//WRITE_BYTE
{
try { output.Write(window, (int)pos, 1); }
catch { return Error.MSPACK_ERR_WRITE; }
}
pos++;
pos &= LZSS_WINDOW_SIZE - 1;
@@ -174,6 +175,9 @@ namespace LibMSPackSharp.Compression
}
}
}
/* not reached */
return Error.MSPACK_ERR_OK;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -137,23 +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 void READ_BYTES(ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer, bool msb)
{
READ_IF_NEEDED(ref i_ptr, ref i_end);
if (Error != Error.MSPACK_ERR_OK)
return;
byte b0 = InputBuffer[i_ptr++];
READ_IF_NEEDED(ref i_ptr, ref i_end);
if (Error != Error.MSPACK_ERR_OK)
return;
byte b1 = InputBuffer[i_ptr++];
INJECT_BITS((uint)((b1 << 8) | b0), 16, ref bits_left, ref bit_buffer, msb);
Error = Error.MSPACK_ERR_OK;
}
public override int HUFF_ERROR() => (int)(Error = Error.MSPACK_ERR_DECRUNCH);
}
}

View File

@@ -106,26 +106,28 @@ namespace LibMSPackSharp.Compression
return null;
// Allocate decompression state
MSZIPDStream zip = new MSZIPDStream();
return new MSZIPDStream
{
// Allocate input buffer
InputBuffer = new byte[input_buffer_size],
// Allocate input buffer
zip.InputBuffer = new byte[input_buffer_size];
// Initialise decompression state
Sys = system,
Input = input,
Output = output,
InputBufferSize = (uint)input_buffer_size,
InputEnd = 0,
Error = Error.MSPACK_ERR_OK,
RepairMode = repair_mode,
FlushWindow = FlushWindow,
// Initialise decompression state
zip.Sys = system;
zip.Input = input;
zip.Output = output;
zip.InputBufferSize = (uint)input_buffer_size;
zip.InputEnd = 0;
zip.Error = Error.MSPACK_ERR_OK;
zip.RepairMode = repair_mode;
zip.FlushWindow = FlushWindow;
zip.InputPointer = zip.InputLength = 0;
zip.OutputPointer = zip.OutputLength = 0;
zip.BitBuffer = 0; zip.BitsLeft = 0;
return zip;
InputPointer = 0,
InputLength = 0,
OutputPointer = 0,
OutputLength = 0,
BitBuffer = 0,
BitsLeft = 0,
};
}
/// <summary>
@@ -195,8 +197,12 @@ namespace LibMSPackSharp.Compression
bits_left = zip.BitsLeft;
// Skip to next read 'CK' header
i = (int)(bits_left & 7);
bit_buffer >>= (i); bits_left -= (i); //REMOVE_BITS(i);
i = bits_left & 7;
//REMOVE_BITS(i);
bit_buffer >>= (i);
bits_left -= (i);
state = 0;
do
@@ -207,7 +213,7 @@ namespace LibMSPackSharp.Compression
while (bits_left < 8)
{
//READ_BYTES;
//READ_IF_NEEDED;
if (i_ptr >= i_end)
{
@@ -222,7 +228,10 @@ namespace LibMSPackSharp.Compression
}
i = (int)(bit_buffer & ((1 << (8)) - 1)); //PEEK_BITS(8);
bit_buffer >>= (8); bits_left -= (8); //REMOVE_BITS(8);
//REMOVE_BITS(8);
bit_buffer >>= (8);
bits_left -= (8);
if (i == 'C')
state = 1;
@@ -244,7 +253,7 @@ namespace LibMSPackSharp.Compression
if ((error = (int)Inflate(zip)) != 0)
{
Console.WriteLine($"inflate error {(InflateErrorCode)error}");
Console.WriteLine($"Inflate error {(InflateErrorCode)error}");
if (zip.RepairMode)
{
// Recover partially-inflated buffers
@@ -304,11 +313,11 @@ namespace LibMSPackSharp.Compression
public static Error DecompressKWAJ(MSZIPDStream zip)
{
// For the bit buffer
uint bit_buffer = 0;
int bits_left = 0;
int i_ptr = 0, i_end = 0;
uint bit_buffer;
int bits_left;
int i_ptr, i_end;
int i = 0, error, block_len = 0;
int i, error, block_len;
// Unpack blocks until block_len == 0
for (; ; )
@@ -321,7 +330,10 @@ namespace LibMSPackSharp.Compression
// Align to bytestream, read block_len
i = (int)(bits_left & 7);
bit_buffer >>= (i); bits_left -= (i); //REMOVE_BITS(i);
//REMOVE_BITS(i);
bit_buffer >>= (i);
bits_left -= (i);
//READ_BITS(block_len, 8);
@@ -344,9 +356,12 @@ namespace LibMSPackSharp.Compression
}
block_len = (int)(bit_buffer & ((1 << (8)) - 1)); //PEEK_BITS(8);
bit_buffer >>= (8); bits_left -= (8); //REMOVE_BITS(8);
// READ_BITS(block_len, 8);
//REMOVE_BITS(8);
bit_buffer >>= (8);
bits_left -= (8);
// READ_BITS(i, 8);
//ENSURE_BITS(8);
while (bits_left < 8)
@@ -367,7 +382,10 @@ namespace LibMSPackSharp.Compression
}
i = (int)(bit_buffer & ((1 << (8)) - 1)); //PEEK_BITS(8);
bit_buffer >>= (8); bits_left -= (8); //REMOVE_BITS(8);
//REMOVE_BITS(8);
bit_buffer >>= (8);
bits_left -= (8);
block_len |= i << 8;
@@ -397,7 +415,10 @@ namespace LibMSPackSharp.Compression
}
i = (int)(bit_buffer & ((1 << (8)) - 1)); //PEEK_BITS(8);
bit_buffer >>= (8); bits_left -= (8); //REMOVE_BITS(8);
//REMOVE_BITS(8);
bit_buffer >>= (8);
bits_left -= (8);
if (i != 'C')
return Error.MSPACK_ERR_DATAFORMAT;
@@ -423,7 +444,10 @@ namespace LibMSPackSharp.Compression
}
i = (int)(bit_buffer & ((1 << (8)) - 1)); //PEEK_BITS(8);
bit_buffer >>= (8); bits_left -= (8); //REMOVE_BITS(8);
//REMOVE_BITS(8);
bit_buffer >>= (8);
bits_left -= (8);
if (i != 'K')
return Error.MSPACK_ERR_DATAFORMAT;
@@ -475,7 +499,7 @@ namespace LibMSPackSharp.Compression
// Read the number of codes
// READ_BITS(lit_codes, 5);
//ENSURE_BITS(5);
while (bits_left < 5)
{
@@ -495,7 +519,10 @@ namespace LibMSPackSharp.Compression
}
lit_codes = (bit_buffer & ((1 << (5)) - 1)); //PEEK_BITS(5);
bit_buffer >>= (5); bits_left -= (5); //REMOVE_BITS(5);
//REMOVE_BITS(5);
bit_buffer >>= (5);
bits_left -= (5);
lit_codes += 257;
@@ -520,7 +547,10 @@ namespace LibMSPackSharp.Compression
}
dist_codes = (bit_buffer & ((1 << (5)) - 1)); //PEEK_BITS(5);
bit_buffer >>= (5); bits_left -= (5); //REMOVE_BITS(5);
//REMOVE_BITS(5);
bit_buffer >>= (5);
bits_left -= (5);
dist_codes += 1;
@@ -545,7 +575,10 @@ namespace LibMSPackSharp.Compression
}
bitlen_codes = (bit_buffer & ((1 << (8)) - 1)); //PEEK_BITS(4);
bit_buffer >>= (4); bits_left -= (4); //REMOVE_BITS(4);
//REMOVE_BITS(4);
bit_buffer >>= (4);
bits_left -= (4);
bitlen_codes += 4;
if (lit_codes > MSZIP_LITERAL_MAXSYMBOLS)
@@ -577,7 +610,10 @@ namespace LibMSPackSharp.Compression
}
bl_len[bitlen_order[i]] = (byte)(bit_buffer & ((1 << (3)) - 1)); //PEEK_BITS(3);
bit_buffer >>= (3); bits_left -= (3); //REMOVE_BITS(3);
//REMOVE_BITS(3);
bit_buffer >>= (3);
bits_left -= (3);
}
while (i < 19)
@@ -613,7 +649,10 @@ namespace LibMSPackSharp.Compression
}
code = bl_table[(bit_buffer & ((1 << (7)) - 1))]; //PEEK_BITS(7);
bit_buffer >>= (bl_len[code]); bits_left -= (bl_len[code]); //REMOVE_BITS(bl_len[code]);
//REMOVE_BITS(bl_len[code]);
bit_buffer >>= (bl_len[code]);
bits_left -= (bl_len[code]);
if (code < 16)
{
@@ -624,84 +663,61 @@ namespace LibMSPackSharp.Compression
switch (code)
{
case 16:
//READ_BITS(run, 2);
//ENSURE_BITS(2);
while (bits_left < 2)
//READ_BITS(run, 2)
{
//READ_BYTES;
//READ_IF_NEEDED;
if (i_ptr >= i_end)
//ENSURE_BITS(2)
while (bits_left < (2))
{
if (zip.ReadInput() != Error.MSPACK_ERR_OK)
return (InflateErrorCode)zip.Error;
i_ptr = zip.InputPointer;
i_end = zip.InputLength;
READ_BYTES;
}
bit_buffer |= (uint)(zip.InputBuffer[i_ptr++]) << bits_left; bits_left += (8); // INJECT_BITS(zip.InputBuffer[i_ptr++], 8);
}
run = (int)(bit_buffer >> (BITBUF_WIDTH - (2)));
run = (bit_buffer & ((1 << (2)) - 1)); //PEEK_BITS(2);
bit_buffer >>= (2); bits_left -= (2); //REMOVE_BITS(2);
// REMOVE_BITS(2);
bit_buffer <<= (2);
bits_left -= (2);
}
run += 3;
code = last_code;
break;
case 17:
//READ_BITS(run, 3);
//ENSURE_BITS(3);
while (bits_left < 3)
//READ_BITS(run, 3)
{
//READ_BYTES;
//READ_IF_NEEDED;
if (i_ptr >= i_end)
//ENSURE_BITS(3)
while (bits_left < (3))
{
if (zip.ReadInput() != Error.MSPACK_ERR_OK)
return (InflateErrorCode)zip.Error;
i_ptr = zip.InputPointer;
i_end = zip.InputLength;
READ_BYTES;
}
bit_buffer |= (uint)(zip.InputBuffer[i_ptr++]) << bits_left; bits_left += (8); // INJECT_BITS(zip.InputBuffer[i_ptr++], 8);
run = (int)(bit_buffer >> (BITBUF_WIDTH - (3)));
// REMOVE_BITS(3);
bit_buffer <<= (3);
bits_left -= (3);
}
run = (bit_buffer & ((1 << (3)) - 1)); //PEEK_BITS(3);
bit_buffer >>= (3); bits_left -= (3); //REMOVE_BITS(3);
run += 3;
code = 0;
break;
case 18:
//READ_BITS(run, 7);
//ENSURE_BITS(7);
while (bits_left < 7)
//READ_BITS(run, 7)
{
//READ_BYTES;
//READ_IF_NEEDED;
if (i_ptr >= i_end)
//ENSURE_BITS(7)
while (bits_left < (7))
{
if (zip.ReadInput() != Error.MSPACK_ERR_OK)
return (InflateErrorCode)zip.Error;
i_ptr = zip.InputPointer;
i_end = zip.InputLength;
READ_BYTES;
}
bit_buffer |= (uint)(zip.InputBuffer[i_ptr++]) << bits_left; bits_left += (8); // INJECT_BITS(zip.InputBuffer[i_ptr++], 8);
}
run = (int)(bit_buffer >> (BITBUF_WIDTH - (7)));
run = (bit_buffer & ((1 << (7)) - 1)); //PEEK_BITS(7);
bit_buffer >>= (7); bits_left -= (7); //REMOVE_BITS(7);
// REMOVE_BITS(7);
bit_buffer <<= (7);
bits_left -= (7);
}
run += 11;
code = 0;
@@ -771,53 +787,37 @@ namespace LibMSPackSharp.Compression
{
// Read in last block bit
//READ_BITS(last_block, 1);
//ENSURE_BITS(1);
while (bits_left < 1)
//READ_BITS(last_block, 1)
{
//READ_BYTES;
//READ_IF_NEEDED;
if (i_ptr >= i_end)
//ENSURE_BITS(1)
while (bits_left < (1))
{
if (zip.ReadInput() != Error.MSPACK_ERR_OK)
return (InflateErrorCode)zip.Error;
i_ptr = zip.InputPointer;
i_end = zip.InputLength;
READ_BYTES;
}
bit_buffer |= (uint)(zip.InputBuffer[i_ptr++]) << bits_left; bits_left += (8); // INJECT_BITS(zip.InputBuffer[i_ptr++], 8);
}
last_block = (int)(bit_buffer >> (BITBUF_WIDTH - (1)));
last_block = (int)(bit_buffer & ((1 << (1)) - 1)); //PEEK_BITS(1);
bit_buffer >>= (1); bits_left -= (1); //REMOVE_BITS(1);
// REMOVE_BITS(1);
bit_buffer <<= (1);
bits_left -= (1);
}
// Read in block type
//READ_BITS(block_type, 2);
//ENSURE_BITS(2);
while (bits_left < 2)
//READ_BITS(block_type, 2)
{
//READ_BYTES;
//READ_IF_NEEDED;
if (i_ptr >= i_end)
//ENSURE_BITS(2)
while (bits_left < (2))
{
if (zip.ReadInput() != Error.MSPACK_ERR_OK)
return (InflateErrorCode)zip.Error;
i_ptr = zip.InputPointer;
i_end = zip.InputLength;
READ_BYTES;
}
bit_buffer |= (uint)(zip.InputBuffer[i_ptr++]) << bits_left; bits_left += (8); // INJECT_BITS(zip.InputBuffer[i_ptr++], 8);
}
block_type = (int)(bit_buffer >> (BITBUF_WIDTH - (2)));
block_type = (int)(bit_buffer & ((1 << (2)) - 1)); //PEEK_BITS(2);
bit_buffer >>= (2); bits_left -= (2); //REMOVE_BITS(2);
// REMOVE_BITS(2);
bit_buffer <<= (2);
bits_left -= (2);
}
// Uncompressed block
if (block_type == 0)
@@ -826,7 +826,10 @@ namespace LibMSPackSharp.Compression
// Go to byte boundary
i = bits_left & 7;
bit_buffer >>= (i); bits_left -= (i); //REMOVE_BITS(i);
//REMOVE_BITS(i);
bit_buffer >>= (i);
bits_left -= (i);
// Read 4 bytes of data, emptying the bit-buffer if necessary
for (i = 0; (bits_left >= 8); i++)
@@ -835,7 +838,10 @@ namespace LibMSPackSharp.Compression
return InflateErrorCode.INF_ERR_BITBUF;
lens_buf[i] = (byte)(bit_buffer & ((1 << (8)) - 1)); //PEEK_BITS(8);
bit_buffer >>= (8); bits_left -= (8); //REMOVE_BITS(8);
//REMOVE_BITS(8);
bit_buffer >>= (8);
bits_left -= (8);
}
if (bits_left != 0)
@@ -1010,7 +1016,10 @@ namespace LibMSPackSharp.Compression
}
(length) = (int)(bit_buffer & lsb_bit_mask[(lit_extrabits[code])]); //PEEK_BITS_T(lit_extrabits[code]);
bit_buffer >>= (lit_extrabits[code]); bits_left -= (lit_extrabits[code]); //REMOVE_BITS(lit_extrabits[code]);
//REMOVE_BITS(lit_extrabits[code]);
bit_buffer >>= (lit_extrabits[code]);
bits_left -= (lit_extrabits[code]);
length += lit_lengths[code];
@@ -1041,7 +1050,10 @@ namespace LibMSPackSharp.Compression
}
(distance) = (int)(bit_buffer & lsb_bit_mask[(dist_extrabits[code])]); //PEEK_BITS_T(dist_extrabits[code]);
bit_buffer >>= (dist_extrabits[code]); bits_left -= (dist_extrabits[code]); //REMOVE_BITS(lit_extrabits[code]);
//REMOVE_BITS(lit_extrabits[code]);
bit_buffer >>= (dist_extrabits[code]);
bits_left -= (dist_extrabits[code]);
distance += dist_offsets[code];

View File

@@ -49,16 +49,6 @@ namespace LibMSPackSharp.Compression
#endregion
public override void READ_BYTES(ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer, bool msb)
{
READ_IF_NEEDED(ref i_ptr, ref i_end);
if (Error != Error.MSPACK_ERR_OK)
return;
INJECT_BITS(InputBuffer[i_ptr++], 8, ref bits_left, ref bit_buffer, msb);
Error = Error.MSPACK_ERR_OK;
}
public override int HUFF_ERROR() => (int)InflateErrorCode.INF_ERR_HUFFSYM;
}
}

View File

@@ -209,7 +209,13 @@ namespace LibMSPackSharp.Compression
return Error.MSPACK_ERR_OK;
// Restore local state
qtm.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
//RESTORE_BITS
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;
@@ -226,9 +232,22 @@ namespace LibMSPackSharp.Compression
{
high = 0xFFFF;
low = 0;
int tempCurrent = current;
qtm.READ_BITS(ref tempCurrent, 16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
current = (ushort)tempCurrent;
//READ_BITS(i, 16)
{
//ENSURE_BITS(16)
while (bits_left < (16))
{
READ_BYTES;
}
i = (int)(bit_buffer >> (BITBUF_WIDTH - (16)));
// REMOVE_BITS(16);
bit_buffer <<= (16);
bits_left -= (16);
}
qtm.HeaderRead = 1;
}
@@ -263,14 +282,35 @@ namespace LibMSPackSharp.Compression
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);
qtm.READ_MANY_BITS(ref extra, extra_bits[sym], ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
if (qtm.Error != Error.MSPACK_ERR_OK)
return qtm.Error;
// READ_MANY_BITS(extra, extra_bits[sym])
needed = extra_bits[sym];
extra = 0;
while (needed > 0)
{
if (bits_left <= (QTMDStream.BITBUF_WIDTH - 16))
{
READ_BYTES;
}
bitrun = (byte)((bits_left < needed) ? bits_left : needed);
int peek = (int)(bit_buffer >> (QTMDStream.BITBUF_WIDTH - (bitrun)));
extra = (uint)((extra << bitrun) | peek);
// REMOVE_BITS(bitrun);
bit_buffer <<= bitrun;
bits_left -= bitrun;
needed -= bitrun;
}
match_offset = position_base[sym] + extra + 1;
match_length = 3;
@@ -279,9 +319,29 @@ namespace LibMSPackSharp.Compression
// 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);
qtm.READ_MANY_BITS(ref extra, extra_bits[sym], ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
if (qtm.Error != Error.MSPACK_ERR_OK)
return qtm.Error;
// READ_MANY_BITS(extra, extra_bits[sym])
needed = extra_bits[sym];
extra = 0;
while (needed > 0)
{
if (bits_left <= (QTMDStream.BITBUF_WIDTH - 16))
{
READ_BYTES;
}
bitrun = (byte)((bits_left < needed) ? bits_left : needed);
int peek = (int)(bit_buffer >> (QTMDStream.BITBUF_WIDTH - (bitrun)));
extra = (uint)((extra << bitrun) | peek);
// REMOVE_BITS(bitrun);
bit_buffer <<= bitrun;
bits_left -= bitrun;
needed -= bitrun;
}
match_offset = position_base[sym] + extra + 1;
match_length = 4;
@@ -290,16 +350,56 @@ namespace LibMSPackSharp.Compression
// 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);
qtm.READ_MANY_BITS(ref extra, length_extra[sym], ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
if (qtm.Error != Error.MSPACK_ERR_OK)
return qtm.Error;
// READ_MANY_BITS(extra, length_extra[sym])
needed = length_extra[sym];
extra = 0;
while (needed > 0)
{
if (bits_left <= (QTMDStream.BITBUF_WIDTH - 16))
{
READ_BYTES;
}
bitrun = (byte)((bits_left < needed) ? bits_left : needed);
int peek = (int)(bit_buffer >> (QTMDStream.BITBUF_WIDTH - (bitrun)));
extra = (uint)((extra << bitrun) | peek);
// REMOVE_BITS(bitrun);
bit_buffer <<= bitrun;
bits_left -= bitrun;
needed -= bitrun;
}
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);
qtm.READ_MANY_BITS(ref extra, extra_bits[sym], ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
if (qtm.Error != Error.MSPACK_ERR_OK)
return qtm.Error;
// READ_MANY_BITS(extra, extra_bits[sym])
needed = extra_bits[sym];
extra = 0;
while (needed > 0)
{
if (bits_left <= (QTMDStream.BITBUF_WIDTH - 16))
{
READ_BYTES;
}
bitrun = (byte)((bits_left < needed) ? bits_left : needed);
int peek = (int)(bit_buffer >> (QTMDStream.BITBUF_WIDTH - (bitrun)));
extra = (uint)((extra << bitrun) | peek);
// REMOVE_BITS(bitrun);
bit_buffer <<= bitrun;
bits_left -= bitrun;
needed -= bitrun;
}
match_offset = position_base[sym] + extra + 1;
break;
@@ -421,14 +521,31 @@ namespace LibMSPackSharp.Compression
{
// Re-align input
if ((bits_left & 7) != 0)
qtm.REMOVE_BITS(bits_left & 7, ref bits_left, ref bit_buffer, msb: true);
{
//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. */
do
{
qtm.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
//READ_BITS(i, 8)
{
//ENSURE_BITS(8)
while (bits_left < (8))
{
READ_BYTES;
}
i = (int)(bit_buffer >> (BITBUF_WIDTH - (8)));
// REMOVE_BITS(8);
bit_buffer <<= (8);
bits_left -= (8);
}
} while (i != 0xFF);
qtm.HeaderRead = 0;
@@ -466,7 +583,13 @@ namespace LibMSPackSharp.Compression
}
// Store local state
qtm.STORE_BITS(i_ptr, i_end, bit_buffer, bits_left);
//STORE_BITS
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;
@@ -532,12 +655,20 @@ namespace LibMSPackSharp.Compression
low <<= 1;
high = (ushort)((high << 1) | 1);
qtm.ENSURE_BITS(1, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
// ENSURE_BITS(1)
while (bits_left < 1)
{
READ_BYTES;
}
if (qtm.Error != Error.MSPACK_ERR_OK)
return;
current = (ushort)((current << 1) | qtm.PEEK_BITS(1, bit_buffer, msb: true));
qtm.REMOVE_BITS(1, ref bits_left, ref bit_buffer, msb: true);
current = (ushort)((current << 1) | (bit_buffer >> (LZXDStream.BITBUF_WIDTH - (1)))); //PEEK_BITS(1)
//REMOVE_BITS(1);
bit_buffer <<= (1);
bits_left -= (1);
}
}

View File

@@ -120,23 +120,6 @@ namespace LibMSPackSharp.Compression
public QTMDModelSym[] Model7Symbols { get; set; } = new QTMDModelSym[7 + 1];
public override void READ_BYTES(ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer, bool msb)
{
READ_IF_NEEDED(ref i_ptr, ref i_end);
if (Error != Error.MSPACK_ERR_OK)
return;
byte b0 = InputBuffer[i_ptr++];
READ_IF_NEEDED(ref i_ptr, ref i_end);
if (Error != Error.MSPACK_ERR_OK)
return;
byte b1 = InputBuffer[i_ptr++];
INJECT_BITS((uint)((b0 << 8) | b1), 16, ref bits_left, ref bit_buffer, msb);
Error = Error.MSPACK_ERR_OK;
}
public override int HUFF_ERROR() => (int)Error.MSPACK_ERR_OK;
}
}

View File

@@ -417,16 +417,28 @@ namespace LibMSPackSharp.KWAJ
private static Error LZHDecompress(InternalStream lzh)
{
uint bit_buffer = 0, len = 0, j = 0;
int i, bits_left = 0;
int i_ptr = 0, i_end = 0;
uint bit_buffer, len = 0, j = 0;
int i, bits_left;
int i_ptr, i_end;
bool lit_run = false;
int pos = 0, offset;
int[] types = new int[6];
// Reset global state
lzh.INIT_BITS();
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
//INIT_BITS
lzh.InputPointer = 0;
lzh.InputLength = 0;
lzh.BitBuffer = 0;
lzh.BitsLeft = 0;
lzh.InputEnd = 0;
//RESTORE_BITS
i_ptr = lzh.InputPointer;
i_end = lzh.InputLength;
bit_buffer = lzh.BitBuffer;
bits_left = lzh.BitsLeft;
for (i = 0; i < LZSS.LZSS_WINDOW_SIZE; i++)
{
lzh.Window[i] = LZSS.LZSS_WINDOW_FILL;
@@ -435,10 +447,23 @@ namespace LibMSPackSharp.KWAJ
// Read 6 encoding types (for byte alignment) but only 5 are needed
for (i = 0; i < 6; i++)
{
//READ_BITS_SAFE(val, n)
lzh.READ_BITS(ref types[i], 4, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
if (lzh.Error != Error.MSPACK_ERR_OK)
return lzh.Error;
//READ_BITS_SAFE(types[i], 4)
//READ_BITS(types[i], 4)
{
//ENSURE_BITS(nbits)
while (bits_left < (4))
{
READ_BYTES;
}
types[i] = (int)(bit_buffer >> (BITBUF_WIDTH - (4)));
// REMOVE_BITS(4);
bit_buffer <<= (4);
bits_left -= (4);
}
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
}
@@ -446,52 +471,107 @@ namespace LibMSPackSharp.KWAJ
// Read huffman table symbol lengths and build huffman trees
//BUILD_TREE(tbl, type)
lzh.STORE_BITS(i_ptr, i_end, bit_buffer, bits_left);
//STORE_BITS
lzh.InputPointer = i_ptr;
lzh.InputLength = i_end;
lzh.BitBuffer = bit_buffer;
lzh.BitsLeft = bits_left;
Error err = LZHReadLens(lzh, (uint)types[0], KWAJ_MATCHLEN1_SYMS, lzh.MATCHLEN1_len);
if (err != Error.MSPACK_ERR_OK)
return err;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
//RESTORE_BITS
i_ptr = lzh.InputPointer;
i_end = lzh.InputLength;
bit_buffer = lzh.BitBuffer;
bits_left = lzh.BitsLeft;
if (!InternalStream.MakeDecodeTable(KWAJ_MATCHLEN1_SYMS, KWAJ_MATCHLEN1_TBLSIZE, lzh.MATCHLEN1_len, lzh.MATCHLEN1_table, msb: true))
return Error.MSPACK_ERR_DATAFORMAT;
//BUILD_TREE(tbl, type)
lzh.STORE_BITS(i_ptr, i_end, bit_buffer, bits_left);
//STORE_BITS
lzh.InputPointer = i_ptr;
lzh.InputLength = i_end;
lzh.BitBuffer = bit_buffer;
lzh.BitsLeft = bits_left;
err = LZHReadLens(lzh, (uint)types[1], KWAJ_MATCHLEN2_SYMS, lzh.MATCHLEN2_len);
if (err != Error.MSPACK_ERR_OK)
return err;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
//RESTORE_BITS
i_ptr = lzh.InputPointer;
i_end = lzh.InputLength;
bit_buffer = lzh.BitBuffer;
bits_left = lzh.BitsLeft;
if (!InternalStream.MakeDecodeTable(KWAJ_MATCHLEN2_SYMS, KWAJ_MATCHLEN2_TBLSIZE, lzh.MATCHLEN2_len, lzh.MATCHLEN2_table, msb: true))
return Error.MSPACK_ERR_DATAFORMAT;
//BUILD_TREE(tbl, type)
lzh.STORE_BITS(i_ptr, i_end, bit_buffer, bits_left);
//STORE_BITS
lzh.InputPointer = i_ptr;
lzh.InputLength = i_end;
lzh.BitBuffer = bit_buffer;
lzh.BitsLeft = bits_left;
err = LZHReadLens(lzh, (uint)types[2], KWAJ_LITLEN_SYMS, lzh.LITLEN_len);
if (err != Error.MSPACK_ERR_OK)
return err;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
//RESTORE_BITS
i_ptr = lzh.InputPointer;
i_end = lzh.InputLength;
bit_buffer = lzh.BitBuffer;
bits_left = lzh.BitsLeft;
if (!InternalStream.MakeDecodeTable(KWAJ_LITLEN_SYMS, KWAJ_LITLEN_TBLSIZE, lzh.LITLEN_len, lzh.LITLEN_table, msb: true))
return Error.MSPACK_ERR_DATAFORMAT;
//BUILD_TREE(tbl, type)
lzh.STORE_BITS(i_ptr, i_end, bit_buffer, bits_left);
//STORE_BITS
lzh.InputPointer = i_ptr;
lzh.InputLength = i_end;
lzh.BitBuffer = bit_buffer;
lzh.BitsLeft = bits_left;
err = LZHReadLens(lzh, (uint)types[3], KWAJ_OFFSET_SYMS, lzh.OFFSET_len);
if (err != Error.MSPACK_ERR_OK)
return err;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
//RESTORE_BITS
i_ptr = lzh.InputPointer;
i_end = lzh.InputLength;
bit_buffer = lzh.BitBuffer;
bits_left = lzh.BitsLeft;
if (!InternalStream.MakeDecodeTable(KWAJ_OFFSET_SYMS, KWAJ_OFFSET_TBLSIZE, lzh.OFFSET_len, lzh.OFFSET_table, msb: true))
return Error.MSPACK_ERR_DATAFORMAT;
//BUILD_TREE(tbl, type)
lzh.STORE_BITS(i_ptr, i_end, bit_buffer, bits_left);
//STORE_BITS
lzh.InputPointer = i_ptr;
lzh.InputLength = i_end;
lzh.BitBuffer = bit_buffer;
lzh.BitsLeft = bits_left;
err = LZHReadLens(lzh, (uint)types[4], KWAJ_LITERAL_SYMS, lzh.LITERAL_len);
if (err != Error.MSPACK_ERR_OK)
return err;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
//RESTORE_BITS
i_ptr = lzh.InputPointer;
i_end = lzh.InputLength;
bit_buffer = lzh.BitBuffer;
bits_left = lzh.BitsLeft;
if (!InternalStream.MakeDecodeTable(KWAJ_LITERAL_SYMS, KWAJ_LITERAL_TBLSIZE, lzh.LITERAL_len, lzh.LITERAL_table, msb: true))
return Error.MSPACK_ERR_DATAFORMAT;
@@ -527,16 +607,27 @@ namespace LibMSPackSharp.KWAJ
offset = (int)(j << 6);
//READ_BITS_SAFE(val, n)
int tempj = (int)j;
lzh.READ_BITS(ref tempj, 6, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
if (lzh.Error != Error.MSPACK_ERR_OK)
return lzh.Error;
//READ_BITS_SAFE(j, 6)
//READ_BITS(j, 6)
{
//ENSURE_BITS(6)
while (bits_left < (6))
{
READ_BYTES;
}
j = (int)(bit_buffer >> (BITBUF_WIDTH - (6)));
// REMOVE_BITS(6);
bit_buffer <<= (6);
bits_left -= (6);
}
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
j = (uint)tempj;
offset |= tempj;
offset |= j;
// Copy match as output and into the ring buffer
while (len-- > 0)
@@ -583,13 +674,18 @@ namespace LibMSPackSharp.KWAJ
public static Error LZHReadLens(InternalStream lzh, uint type, uint numsyms, byte[] lens)
{
uint bit_buffer = 0;
int bits_left = 0;
int i_ptr = 0, i_end = 0;
uint bit_buffer;
int bits_left;
int i_ptr, i_end;
uint i;
int c = 0, sel = 0;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
//RESTORE_BITS
i_ptr = lzh.InputPointer;
i_end = lzh.InputLength;
bit_buffer = lzh.BitBuffer;
bits_left = lzh.BitsLeft;
switch (type)
{
case 0:
@@ -603,16 +699,46 @@ namespace LibMSPackSharp.KWAJ
break;
case 1:
//READ_BITS_SAFE(val, n)
lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
//READ_BITS_SAFE(c, 4)
//READ_BITS(c, 4)
{
//ENSURE_BITS(4)
while (bits_left < (4))
{
READ_BYTES;
}
c = (int)(bit_buffer >> (BITBUF_WIDTH - (4)));
// REMOVE_BITS(4);
bit_buffer <<= (4);
bits_left -= (4);
}
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
lens[0] = (byte)c;
for (i = 1; i < numsyms; i++)
{
//READ_BITS_SAFE(val, n)
lzh.READ_BITS(ref sel, 1, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
//READ_BITS_SAFE(sel, 1)
//READ_BITS(sel, 1)
{
//ENSURE_BITS(1)
while (bits_left < (1))
{
READ_BYTES;
}
sel = (int)(bit_buffer >> (BITBUF_WIDTH - (1)));
// REMOVE_BITS(1);
bit_buffer <<= (1);
bits_left -= (1);
}
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -622,8 +748,23 @@ namespace LibMSPackSharp.KWAJ
}
else
{
//READ_BITS_SAFE(val, n)
lzh.READ_BITS(ref sel, 1, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
//READ_BITS_SAFE(sel, 1)
//READ_BITS(sel, 1)
{
//ENSURE_BITS(1)
while (bits_left < (1))
{
READ_BYTES;
}
sel = (int)(bit_buffer >> (BITBUF_WIDTH - (1)));
// REMOVE_BITS(1);
bit_buffer <<= (1);
bits_left -= (1);
}
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -633,8 +774,23 @@ namespace LibMSPackSharp.KWAJ
}
else
{
//READ_BITS_SAFE(val, n)
lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
//READ_BITS_SAFE(c, 4)
//READ_BITS(c, 4)
{
//ENSURE_BITS(nbits)
while (bits_left < (4))
{
READ_BYTES;
}
c = (int)(bit_buffer >> (BITBUF_WIDTH - (4)));
// REMOVE_BITS(4);
bit_buffer <<= (4);
bits_left -= (4);
}
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -645,23 +801,68 @@ namespace LibMSPackSharp.KWAJ
break;
case 2:
//READ_BITS_SAFE(val, n)
lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
//READ_BITS_SAFE(c, 4)
//READ_BITS(c, 4)
{
//ENSURE_BITS(4)
while (bits_left < (4))
{
READ_BYTES;
}
c = (int)(bit_buffer >> (BITBUF_WIDTH - (4)));
// REMOVE_BITS(4);
bit_buffer <<= (4);
bits_left -= (4);
}
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
lens[0] = (byte)c;
for (i = 1; i < numsyms; i++)
{
//READ_BITS_SAFE(val, n)
lzh.READ_BITS(ref sel, 2, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
//READ_BITS_SAFE(sel, 2)
//READ_BITS(sel, 2)
{
//ENSURE_BITS(2)
while (bits_left < (2))
{
READ_BYTES;
}
sel = (int)(bit_buffer >> (BITBUF_WIDTH - (2)));
// REMOVE_BITS(2);
bit_buffer <<= (2);
bits_left -= (2);
}
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
if (sel == 3)
{
//READ_BITS_SAFE(val, n)
lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
//READ_BITS_SAFE(c, 4)
//READ_BITS(c, 4)
{
//ENSURE_BITS(4)
while (bits_left < (4))
{
READ_BYTES;
}
c = (int)(bit_buffer >> (BITBUF_WIDTH - (4)));
// REMOVE_BITS(4);
bit_buffer <<= (4);
bits_left -= (4);
}
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
}
@@ -678,8 +879,23 @@ namespace LibMSPackSharp.KWAJ
case 3:
for (i = 0; i < numsyms; i++)
{
//READ_BITS_SAFE(val, n)
lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
//READ_BITS_SAFE(c, 4)
//READ_BITS(c, 4)
{
//ENSURE_BITS(4)
while (bits_left < (4))
{
READ_BYTES;
}
c = (int)(bit_buffer >> (BITBUF_WIDTH - (4)));
// REMOVE_BITS(4);
bit_buffer <<= (4);
bits_left -= (4);
}
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -689,7 +905,11 @@ namespace LibMSPackSharp.KWAJ
break;
}
lzh.STORE_BITS(i_ptr, i_end, bit_buffer, bits_left);
//STORE_BITS
lzh.InputPointer = i_ptr;
lzh.InputLength = i_end;
lzh.BitBuffer = bit_buffer;
lzh.BitsLeft = bits_left;
return Error.MSPACK_ERR_OK;
}

View File

@@ -33,21 +33,6 @@ namespace LibMSPackSharp.KWAJ
public byte[] Window { get; set; } = new byte[LZSS.LZSS_WINDOW_SIZE];
public override void READ_BYTES(ref int i_ptr, ref int i_end, ref int bits_left, ref uint bit_buffer, bool msb)
{
if (i_ptr >= i_end)
{
if ((Error = Implementation.LZHReadInput(this)) != Error.MSPACK_ERR_OK)
return;
i_ptr = InputPointer;
i_end = InputLength;
}
INJECT_BITS(InputBuffer[i_ptr++], 8, ref bits_left, ref bit_buffer, msb);
Error = Error.MSPACK_ERR_OK;
}
public override int HUFF_ERROR() => (int)Error.MSPACK_ERR_DATAFORMAT;
}
}