Start doing a better job with MSZIP

This commit is contained in:
Matt Nadareski
2023-01-02 11:19:06 -08:00
parent b17f8dac7a
commit cdeaf09ed6
8 changed files with 352 additions and 268 deletions

View File

@@ -3,7 +3,7 @@ using ICSharpCode.SharpZipLib.Zip.Compression;
namespace BurnOutSharp.Compression
{
public class MSZIP
public class MSZIP_zlib
{
#region Instance Variables

View File

@@ -0,0 +1,145 @@
using BurnOutSharp.Models.Compression.MSZIP;
using static BurnOutSharp.Models.Compression.MSZIP.Constants;
namespace BurnOutSharp.Compression.MSZIP
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/fdi.c"/>
public class Decompressor
{
/// <summary>
/// Free a single huffman node
/// </summary>
/// <remarks>No-op because of garbage collection</remarks>
public static void Free(HuffmanNode node) { }
// TODO: Port other methods
/// <summary>
/// Decompress a byte array using a given State
/// </summary>
public static bool Decompress(State state, int inlen, byte[] inbuf, int outlen, byte[] outbuf)
{
state.InputPosition = 0; // inbuf[0];
state.BitBuffer = state.BitCount = state.WindowPosition = 0;
if (outlen > ZIPWSIZE)
return false;
// CK = Chris Kirmse, official Microsoft purloiner
if (inbuf[state.InputPosition + 0] != 0x43 || inbuf[state.InputPosition + 1] != 0x48)
return false;
state.InputPosition += 2;
int lastBlockFlag = 0;
do
{
if (InflateBlock(ref lastBlockFlag, state, inbuf, outbuf) != 0)
return false;
} while (lastBlockFlag == 0);
// Return success
return true;
}
/// <summary>
/// Decompress a deflated block
/// </summary>
private static uint InflateBlock(ref int e, State state, byte[] inbuf, byte[] outbuf)
{
// Make local bit buffer
uint bitBuffer = state.BitBuffer;
uint bitCount = state.BitCount;
// Read in last block bit
ZIPNEEDBITS(1, state, inbuf, ref bitBuffer, ref bitCount);
e = (int)(bitBuffer & 1);
ZIPDUMPBITS(1, ref bitBuffer, ref bitCount);
// Read in block type
ZIPNEEDBITS(2, state, inbuf, ref bitBuffer, ref bitCount);
CompressionType blockType = (CompressionType)(bitBuffer & 3);
ZIPDUMPBITS(2, ref bitBuffer, ref bitCount);
// Restore the global bit buffer
state.BitBuffer = bitBuffer;
state.BitCount = bitCount;
// Inflate that block type
switch (blockType)
{
case CompressionType.NoCompression:
return (uint)DecompressStored(state, inbuf, outbuf);
case CompressionType.FixedHuffman:
return 0; // TODO: return fdi_Zipinflate_fixed(decomp_state);
case CompressionType.DynamicHuffman:
return 0; // TODO: return fdi_Zipinflate_dynamic(decomp_state);
// Bad block type
case CompressionType.Reserved:
default:
return 2;
}
}
/// <summary>
/// "Decompress" a stored block
/// </summary>
private static int DecompressStored(State state, byte[] inbuf, byte[] outbuf)
{
// Make local copies of globals
uint bitBuffer = state.BitBuffer;
uint bitCount = state.BitCount;
uint windowPosition = state.WindowPosition;
// Go to byte boundary
int n = (int)(bitCount & 7);
ZIPDUMPBITS(n, ref bitBuffer, ref bitCount);
// Get the length and its compliment
ZIPNEEDBITS(16, state, inbuf, ref bitBuffer, ref bitCount);
n = (int)(bitBuffer & 0xffff);
ZIPDUMPBITS(16, ref bitBuffer, ref bitCount);
ZIPNEEDBITS(16, state, inbuf, ref bitBuffer, ref bitCount);
if (n != (~bitBuffer & 0xffff))
return 1; // Error in compressed data
ZIPDUMPBITS(16, ref bitBuffer, ref bitCount);
// Read and output the compressed data
while (n-- > 0)
{
ZIPNEEDBITS(8, state, inbuf, ref bitBuffer, ref bitCount);
outbuf[windowPosition++] = (byte)bitBuffer;
ZIPDUMPBITS(8, ref bitBuffer, ref bitCount);
}
// Restore the globals from the locals
state.WindowPosition = windowPosition;
state.BitBuffer = bitBuffer;
state.BitCount = bitCount;
return 0;
}
#region Macros
private static void ZIPNEEDBITS(int n, State state, byte[] inbuf, ref uint bitBuffer, ref uint bitCount)
{
while (bitCount < n)
{
int c = inbuf[state.InputPosition++];
bitBuffer |= (uint)(c << (int)bitCount);
bitCount += 8;
}
}
private static void ZIPDUMPBITS(int n, ref uint bitBuffer, ref uint bitCount)
{
bitBuffer >>= n;
bitCount -= (uint)n;
}
#endregion
}
}

View File

@@ -0,0 +1,29 @@
namespace BurnOutSharp.Compression.MSZIP
{
public class HuffmanNode
{
/// <summary>
/// Number of extra bits or operation
/// </summary>
public byte ExtraBits;
/// <summary>
/// Number of bits in this code or subcode
/// </summary>
public byte BitLength;
#region v
/// <summary>
/// Literal, length base, or distance base
/// </summary>
public ushort Base;
/// <summary>
/// Pointer to next level of table
/// </summary>
public HuffmanNode NextLevel;
#endregion
}
}

View File

@@ -0,0 +1,56 @@
using static BurnOutSharp.Models.Compression.MSZIP.Constants;
namespace BurnOutSharp.Compression.MSZIP
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
public class State
{
/// <summary>
/// Current offset within the window
/// </summary>
public uint WindowPosition;
/// <summary>
/// Bit buffer
/// </summary>
public uint BitBuffer;
/// <summary>
/// Bits in bit buffer
/// </summary>
public uint BitCount;
/// <summary>
/// Literal/length and distance code lengths
/// </summary>
public uint[] Lengths = new uint[288 + 32];
/// <summary>
/// Bit length count table
/// </summary>
public uint[] Counts = new uint[ZIPBMAX + 1];
/// <summary>
/// Memory for l[-1..ZIPBMAX-1]
/// </summary>
public int[] LengthMemory = new int[ZIPBMAX + 1];
/// <summary>
/// Table stack
/// </summary>
public HuffmanNode[] TableStack = new HuffmanNode[ZIPBMAX];
/// <summary>
/// Values in order of bit length
/// </summary>
public uint[] Values = new uint[ZIPN_MAX];
/// <summary>
/// Bit offsets, then code stack
/// </summary>
public uint[] BitOffsets = new uint[ZIPBMAX + 1];
/// <remarks>byte*</remarks>
public int InputPosition;
}
}

View File

@@ -0,0 +1,89 @@
namespace BurnOutSharp.Models.Compression.MSZIP
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
public static class Constants
{
/// <summary>
/// Window size
/// </summary>
public const ushort ZIPWSIZE = 0x8000;
/// <summary>
/// Bits in base literal/length lookup table
/// </summary>
public const int ZIPLBITS = 9;
/// <summary>
/// Bits in base distance lookup table
/// </summary>
public const int ZIPDBITS = 6;
/// <summary>
/// Maximum bit length of any code
/// </summary>
public const int ZIPBMAX = 16;
/// <summary>
/// Maximum number of codes in any set
/// </summary>
public const int ZIPN_MAX = 288;
#region THOSE_ZIP_CONSTS
/// <summary>
/// Order of the bit length code lengths
/// </summary>
public static readonly byte[] BitLengthOrder = new byte[]
{
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
};
/// <summary>
/// Copy lengths for literal codes 257..285
/// </summary>
public static readonly ushort[] CopyLengths = new ushort[]
{
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51,
59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
};
/// <summary>
/// Extra bits for literal codes 257..285
/// </summary>
/// <remarks>99 == invalid</remarks>
public static readonly ushort[] LiteralExtraBits = new ushort[]
{
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
4, 5, 5, 5, 5, 0, 99, 99
};
/// <summary>
/// Copy offsets for distance codes 0..29
/// </summary>
public static readonly ushort[] CopyOffsets = new ushort[]
{
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
};
/// <summary>
/// Extra bits for distance codes
/// </summary>
public static readonly ushort[] DistanceExtraBits = new ushort[]
{
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
10, 11, 11, 12, 12, 13, 13
};
/// <summary>
/// And'ing with Zipmask[n] masks the lower n bits
/// </summary>
public static readonly ushort[] BitMasks = new ushort[17]
{
0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
};
#endregion
}
}

View File

@@ -216,7 +216,7 @@ namespace BurnOutSharp.Wrappers
return null;
// Store the last decompressed block for MS-ZIP
Compression.MSZIP mszip = new Compression.MSZIP();
Compression.MSZIP_zlib mszip = new Compression.MSZIP_zlib();
bool hasLastBlock = false;
List<byte> data = new List<byte>();

View File

@@ -1,6 +1,7 @@
// using static BurnOutSharp.Wrappers.CabinetConstants;
// using static BurnOutSharp.Wrappers.FDIcConstants;
// using static BurnOutSharp.Wrappers.FDIConstants;
// using static BurnOutSharp.Models.Compression.MSZIP.Constants;
// using cab_LONG = System.Int32;
// using cab_off_t = System.UInt32;
// using cab_UBYTE = System.Byte;
@@ -11,14 +12,6 @@
// {
// internal unsafe class MSZIPfdi
// {
// /// <summary>
// /// Ziphuft_free (internal)
// /// </summary>
// static void fdi_Ziphuft_free(FDI_Int fdi, Ziphuft t)
// {
// // No-op because of garbage collection
// }
// /// <summary>
// /// fdi_Ziphuft_build (internal)
// /// </summary>
@@ -170,7 +163,7 @@
// if (!(q = decomp_state.fdi.alloc((z + 1) * sizeof(Ziphuft))))
// {
// if (h)
// fdi_Ziphuft_free(decomp_state.fdi, decomp_state.zip.u[0]);
// Free(decomp_state.fdi, decomp_state.zip.u[0]);
// return 3; /* not enough memory */
// }
@@ -249,8 +242,8 @@
// w = decomp_state.zip.window_posn; /* initialize window position */
// /* inflate the coded data */
// ml = Zipmask[bl]; /* precompute masks for speed */
// md = Zipmask[bd];
// ml = BitMasks[bl]; /* precompute masks for speed */
// md = BitMasks[bd];
// for (; ; )
// {
@@ -263,7 +256,7 @@
// ZIPDUMPBITS(t.b)
// e -= 16;
// ZIPNEEDBITS(e)
// } while ((e = (t = t.v.t + (b & Zipmask[e])).e) > 16);
// } while ((e = (t = t.v.t + (b & BitMasks[e])).e) > 16);
// ZIPDUMPBITS(t.b)
// if (e == 16) /* then it's a literal */
// decomp_state.outbuf[w++] = (cab_UBYTE)t.v.n;
@@ -275,7 +268,7 @@
// /* get length of block to copy */
// ZIPNEEDBITS(e)
// n = t.v.n + (b & Zipmask[e]);
// n = t.v.n + (b & BitMasks[e]);
// ZIPDUMPBITS(e);
// /* decode distance of block to copy */
@@ -288,10 +281,10 @@
// ZIPDUMPBITS(t.b)
// e -= 16;
// ZIPNEEDBITS(e)
// } while ((e = (t = t.v.t + (b & Zipmask[e])).e) > 16);
// } while ((e = (t = t.v.t + (b & BitMasks[e])).e) > 16);
// ZIPDUMPBITS(t.b)
// ZIPNEEDBITS(e)
// d = w - t.v.n - (b & Zipmask[e]);
// d = w - t.v.n - (b & BitMasks[e]);
// ZIPDUMPBITS(e)
// do
// {
@@ -316,51 +309,6 @@
// return 0;
// }
// /// <summary>
// /// Zipinflate_stored (internal)
// ///
// /// "decompress" an inflated type 0 (stored) block.
// /// </summary>
// static cab_LONG fdi_Zipinflate_stored(fdi_decomp_state decomp_state)
// {
// cab_ULONG n; /* number of bytes in block */
// cab_ULONG w; /* current window position */
// cab_ULONG b; /* bit buffer */
// cab_ULONG k; /* number of bits in bit buffer */
// /* make local copies of globals */
// b = decomp_state.zip.bb; /* initialize bit buffer */
// k = decomp_state.zip.bk;
// w = decomp_state.zip.window_posn; /* initialize window position */
// /* go to byte boundary */
// n = k & 7;
// ZIPDUMPBITS(n);
// /* get the length and its complement */
// ZIPNEEDBITS(16)
// n = (b & 0xffff);
// ZIPDUMPBITS(16)
// ZIPNEEDBITS(16)
// if (n != ((~b) & 0xffff))
// return 1; /* error in compressed data */
// ZIPDUMPBITS(16)
// /* read and output the compressed data */
// while (n--)
// {
// ZIPNEEDBITS(8)
// decomp_state.outbuf[w++] = (cab_UBYTE)b;
// ZIPDUMPBITS(8)
// }
// /* restore the globals from the locals */
// decomp_state.zip.window_posn = w; /* restore global window pointer */
// decomp_state.zip.bb = b; /* restore global bit buffer */
// decomp_state.zip.bk = k;
// return 0;
// }
// /// <summary>
// /// fdi_Zipinflate_fixed (internal)
// /// </summary>
@@ -384,24 +332,24 @@
// for (; i < 288; i++) /* make a complete, but wrong code set */
// l[i] = 8;
// fixed_bl = 7;
// if ((i = fdi_Ziphuft_build(l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl, decomp_state)))
// if ((i = fdi_Ziphuft_build(l, 288, 257, CopyLengths, LiteralExtraBits, &fixed_tl, &fixed_bl, decomp_state)))
// return i;
// /* distance table */
// for (i = 0; i < 30; i++) /* make an incomplete code set */
// l[i] = 5;
// fixed_bd = 5;
// if ((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1)
// if ((i = fdi_Ziphuft_build(l, 30, 0, CopyOffsets, DistanceExtraBits, &fixed_td, &fixed_bd, decomp_state)) > 1)
// {
// fdi_Ziphuft_free(decomp_state.fdi, fixed_tl);
// Free(decomp_state.fdi, fixed_tl);
// return i;
// }
// /* decompress until an end-of-block code */
// i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state);
// fdi_Ziphuft_free(decomp_state.fdi, fixed_td);
// fdi_Ziphuft_free(decomp_state.fdi, fixed_tl);
// Free(decomp_state.fdi, fixed_td);
// Free(decomp_state.fdi, fixed_tl);
// return i;
// }
@@ -450,24 +398,24 @@
// for (j = 0; j < nb; j++)
// {
// ZIPNEEDBITS(3)
// ll[Zipborder[j]] = b & 7;
// ll[BitLengthOrder[j]] = b & 7;
// ZIPDUMPBITS(3)
// }
// for (; j < 19; j++)
// ll[Zipborder[j]] = 0;
// ll[BitLengthOrder[j]] = 0;
// /* build decoding table for trees--single level, 7 bit lookup */
// bl = 7;
// if ((i = fdi_Ziphuft_build(ll, 19, 19, null, null, &tl, &bl, decomp_state)) != 0)
// {
// if (i == 1)
// fdi_Ziphuft_free(decomp_state.fdi, tl);
// Free(decomp_state.fdi, tl);
// return i; /* incomplete code set */
// }
// /* read in literal and distance code lengths */
// n = nl + nd;
// m = Zipmask[bl];
// m = BitMasks[bl];
// i = l = 0;
// while ((cab_ULONG)i < n)
// {
@@ -512,7 +460,7 @@
// }
// /* free decoding table for trees */
// fdi_Ziphuft_free(decomp_state.fdi, tl);
// Free(decomp_state.fdi, tl);
// /* restore the global bit buffer */
// decomp_state.zip.bb = b;
@@ -520,92 +468,23 @@
// /* build the decoding tables for literal/length and distance codes */
// bl = ZIPLBITS;
// if ((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0)
// if ((i = fdi_Ziphuft_build(ll, nl, 257, CopyLengths, LiteralExtraBits, &tl, &bl, decomp_state)) != 0)
// {
// if (i == 1)
// fdi_Ziphuft_free(decomp_state.fdi, tl);
// Free(decomp_state.fdi, tl);
// return i; /* incomplete code set */
// }
// bd = ZIPDBITS;
// fdi_Ziphuft_build(ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd, decomp_state);
// fdi_Ziphuft_build(ll + nl, nd, 0, CopyOffsets, DistanceExtraBits, &td, &bd, decomp_state);
// /* decompress until an end-of-block code */
// if (fdi_Zipinflate_codes(tl, td, bl, bd, decomp_state))
// return 1;
// /* free the decoding tables, return */
// fdi_Ziphuft_free(decomp_state.fdi, tl);
// fdi_Ziphuft_free(decomp_state.fdi, td);
// Free(decomp_state.fdi, tl);
// Free(decomp_state.fdi, td);
// return 0;
// }
// /// <summary>
// /// fdi_Zipinflate_block (internal)
// ///
// /// decompress an inflated block
// /// </summary>
// static cab_LONG fdi_Zipinflate_block(cab_LONG* e, fdi_decomp_state decomp_state) /* e == last block flag */
// {
// cab_ULONG t; /* block type */
// cab_ULONG b; /* bit buffer */
// cab_ULONG k; /* number of bits in bit buffer */
// /* make local bit buffer */
// b = decomp_state.zip.bb;
// k = decomp_state.zip.bk;
// /* read in last block bit */
// ZIPNEEDBITS(1)
// * e = (cab_LONG)b & 1;
// ZIPDUMPBITS(1)
// /* read in block type */
// ZIPNEEDBITS(2)
// t = b & 3;
// ZIPDUMPBITS(2)
// /* restore the global bit buffer */
// decomp_state.zip.bb = b;
// decomp_state.zip.bk = k;
// /* inflate that block type */
// if (t == 2)
// return fdi_Zipinflate_dynamic(decomp_state);
// if (t == 0)
// return fdi_Zipinflate_stored(decomp_state);
// if (t == 1)
// return fdi_Zipinflate_fixed(decomp_state);
// /* bad block type */
// return 2;
// }
// /// <summary>
// /// ZIPfdi_decomp(internal)
// /// </summary>
// static int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state decomp_state)
// {
// cab_LONG e; /* last block flag */
// TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
// decomp_state.zip.inpos = decomp_state.inbuf;
// decomp_state.zip.bb = decomp_state.zip.bk = decomp_state.zip.window_posn = 0;
// if (outlen > ZIPWSIZE)
// return DECR_DATAFORMAT;
// /* CK = Chris Kirmse, official Microsoft purloiner */
// if (decomp_state.zip.inpos[0] != 0x43 || decomp_state.zip.inpos[1] != 0x4B)
// return DECR_ILLEGALDATA;
// decomp_state.zip.inpos += 2;
// do
// {
// if (fdi_Zipinflate_block(&e, decomp_state))
// return DECR_ILLEGALDATA;
// } while (!e);
// /* return success */
// return DECR_OK;
// }
// }
// }

View File

@@ -3,6 +3,7 @@
// using System.IO;
// using System.Linq;
// using BurnOutSharp.Compression;
// using BurnOutSharp.Compression.MSZIP;
// using static BurnOutSharp.Wrappers.CabinetConstants;
// using static BurnOutSharp.Wrappers.FDIcConstants;
// using static BurnOutSharp.Wrappers.FDIConstants;
@@ -1177,126 +1178,11 @@
// public const int CAB_BLOCKMAX = (32768);
// public const int CAB_INPUTMAX = (CAB_BLOCKMAX + 6144);
// /****************************************************************************/
// /* Tables for deflate from PKZIP's appnote.txt. */
// //#define THOSE_ZIP_CONSTS
// /* Order of the bit length code lengths */
// public static readonly byte[] Zipborder =
// { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
// /* Copy lengths for literal codes 257..285 */
// public static readonly ushort[] Zipcplens =
// { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51,
// 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
// /* Extra bits for literal codes 257..285 */
// public static readonly ushort[] Zipcplext =
// { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
// 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
// /* Copy offsets for distance codes 0..29 */
// public static readonly ushort[] Zipcpdist =
// { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
// 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
// /* Extra bits for distance codes */
// public static readonly ushort[] Zipcpdext =
// { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
// 10, 11, 11, 12, 12, 13, 13};
// /* And'ing with Zipmask[n] masks the lower n bits */
// public static readonly ushort[] Zipmask = new ushort[17]
// { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
// 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff };
// /* SESSION Operation */
// public const uint EXTRACT_FILLFILELIST = 0x00000001;
// public const uint EXTRACT_EXTRACTFILES = 0x00000002;
// }
// /* MSZIP stuff */
// /// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
// internal class Ziphuft
// {
// /// <summary>
// /// number of extra bits or operation
// /// </summary>
// public byte e;
// /// <summary>
// /// number of bits in this code or subcode
// /// </summary>
// public byte b;
// #region v
// /// <summary>
// /// literal, length base, or distance base
// /// </summary>
// public ushort n;
// /// <summary>
// /// pointer to next level of table
// /// </summary>
// public Ziphuft t;
// #endregion
// }
// /// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
// internal class ZIPstate
// {
// /// <summary>
// /// current offset within the window
// /// </summary>
// public uint window_posn;
// /// <summary>
// /// bit buffer
// /// </summary>
// public uint bb;
// /// <summary>
// /// bits in bit buffer
// /// </summary>
// public uint bk;
// /// <summary>
// /// literal/length and distance code lengths
// /// </summary>
// public uint[] ll = new uint[288 + 32];
// /// <summary>
// /// bit length count table
// /// </summary>
// public uint[] c = new uint[ZIPBMAX + 1];
// /// <summary>
// /// memory for l[-1..ZIPBMAX-1]
// /// </summary>
// public uint[] lx = new uint[ZIPBMAX + 1];
// /// <summary>
// /// table stack
// /// </summary>
// public Ziphuft[] u = new Ziphuft[ZIPBMAX];
// /// <summary>
// /// values in order of bit length
// /// </summary>
// public uint[] v = new uint[ZIPN_MAX];
// /// <summary>
// /// bit offsets, then code stack
// /// </summary>
// public uint[] x = new uint[ZIPBMAX + 1];
// public byte* inpos;
// }
// /* LZX stuff */
// /// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
@@ -1592,8 +1478,8 @@
// #region methods
// public ZIPstate zip;
// public QuantumState qtm;
// public Compression.MSZIP.State zip;
// public Compression.Quantum.State qtm;
// public LZXstate lzx;
// #endregion
@@ -1627,11 +1513,11 @@
// /* Quantum reads bytes in normal order; LZX is little-endian order */
// // #define ENSURE_BITS(n) \
// // while (bitsleft < (n)) { \
// // bitbuf |= ((inpos[1]<<8)|inpos[0]) << (CAB_Uint_BITS-16 - bitsleft); \
// // bitbuf |= ((inpos[1]<<8)|inpos[0]) << (16 - bitsleft); \
// // bitsleft += 16; inpos+=2; \
// // }
// // #define PEEK_BITS(n) (bitbuf >> (CAB_Uint_BITS - (n)))
// // #define PEEK_BITS(n) (bitbuf >> (32 - (n)))
// // #define REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n)))
// // #define READ_BITS(v,n) do { \
@@ -1669,7 +1555,7 @@
// // ENSURE_BITS(16); \
// // hufftbl = SYMTABLE(tbl); \
// // if ((i = hufftbl[PEEK_BITS(TABLEBITS(tbl))]) >= MAXSYMBOLS(tbl)) { \
// // j = 1 << (CAB_Uint_BITS - TABLEBITS(tbl)); \
// // j = 1 << (32 - TABLEBITS(tbl)); \
// // do { \
// // j >>= 1; i <<= 1; i |= (bitbuf & j) ? 1 : 0; \
// // if (!j) { return DECR_ILLEGALDATA; } \
@@ -1923,8 +1809,8 @@
// #region methods
// public ZIPstate zip;
// public QuantumState qtm;
// public Compression.MSZIP.State zip;
// public Compression.Quantum.State qtm;
// public LZXstate lzx;
// #endregion