diff --git a/BurnOutSharp.Compression/Quantum.cs b/BurnOutSharp.Compression/Quantum.cs index d06e30dd..369b5b78 100644 --- a/BurnOutSharp.Compression/Quantum.cs +++ b/BurnOutSharp.Compression/Quantum.cs @@ -8,6 +8,91 @@ namespace BurnOutSharp.Compression { // TODO: Implement Quantum decompression + /* Bitstream reading macros (Quantum / normal byte order) + * + * Q_INIT_BITSTREAM should be used first to set up the system + * Q_READ_BITS(var,n) takes N bits from the buffer and puts them in var. + * unlike LZX, this can loop several times to get the + * requisite number of bits. + * Q_FILL_BUFFER adds more data to the bit buffer, if there is room + * for another 16 bits. + * Q_PEEK_BITS(n) extracts (without removing) N bits from the bit + * buffer + * Q_REMOVE_BITS(n) removes N bits from the bit buffer + * + * These bit access routines work by using the area beyond the MSB and the + * LSB as a free source of zeroes. This avoids having to mask any bits. + * So we have to know the bit width of the bitbuffer variable. This is + * defined as Uint_BITS. + * + * Uint_BITS should be at least 16 bits. Unlike LZX's Huffman decoding, + * Quantum's arithmetic decoding only needs 1 bit at a time, it doesn't + * need an assured number. Retrieving larger bitstrings can be done with + * multiple reads and fills of the bitbuffer. The code should work fine + * for machines where Uint >= 32 bits. + * + * Also note that Quantum reads bytes in normal order; LZX is in + * little-endian order. + */ + + // #define Q_INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0) + + // #define Q_FILL_BUFFER do { \ + // if (bitsleft <= (CAB_Uint_BITS - 16)) { \ + // bitbuf |= ((inpos[0]<<8)|inpos[1]) << (CAB_Uint_BITS-16 - bitsleft); \ + // bitsleft += 16; inpos += 2; \ + // } \ + // } while (0) + + // #define Q_PEEK_BITS(n) (bitbuf >> (CAB_Uint_BITS - (n))) + // #define Q_REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n))) + + // #define Q_READ_BITS(v,n) do { \ + // (v) = 0; \ + // for (bitsneed = (n); bitsneed; bitsneed -= bitrun) { \ + // Q_FILL_BUFFER; \ + // bitrun = (bitsneed > bitsleft) ? bitsleft : bitsneed; \ + // (v) = ((v) << bitrun) | Q_PEEK_BITS(bitrun); \ + // Q_REMOVE_BITS(bitrun); \ + // } \ + // } while (0) + + // #define Q_MENTRIES(model) (decomp_state.qtm.model).entries) + // #define Q_MSYM(model,symidx) (decomp_state.qtm.model).syms[(symidx)].sym) + // #define Q_MSYMFREQ(model,symidx) (decomp_state.qtm.model).syms[(symidx)].cumfreq) + + /* GET_SYMBOL(model, var) fetches the next symbol from the stated model + * and puts it in var. it may need to read the bitstream to do this. + */ + // #define GET_SYMBOL(m, var) do { \ + // range = ((H - L) & 0xFFFF) + 1; \ + // symf = ((((C - L + 1) * Q_MSYMFREQ(m,0)) - 1) / range) & 0xFFFF; \ + // \ + // for (i=1; i < Q_MENTRIES(m); i++) { \ + // if (Q_MSYMFREQ(m,i) <= symf) break; \ + // } \ + // (var) = Q_MSYM(m,i-1); \ + // \ + // range = (H - L) + 1; \ + // H = L + ((Q_MSYMFREQ(m,i-1) * range) / Q_MSYMFREQ(m,0)) - 1; \ + // L = L + ((Q_MSYMFREQ(m,i) * range) / Q_MSYMFREQ(m,0)); \ + // while (1) { \ + // if ((L & 0x8000) != (H & 0x8000)) { \ + // if ((L & 0x4000) && !(H & 0x4000)) { \ + // /* underflow case */ \ + // C ^= 0x4000; L &= 0x3FFF; H |= 0x4000; \ + // } \ + // else break; \ + // } \ + // L <<= 1; H = (H << 1) | 1; \ + // Q_FILL_BUFFER; \ + // C = (C << 1) | Q_PEEK_BITS(1); \ + // Q_REMOVE_BITS(1); \ + // } \ + // \ + // Quantum.UpdateModel(&(decomp_state.qtm.m)), i); \ + // } while (0) + /// /// Initialize a Quantum model that decodes symbols from s to (s + n - 1) /// @@ -21,7 +106,7 @@ namespace BurnOutSharp.Compression // Clear out the look-up table model.LookupTable = Enumerable.Repeat(0xFF, model.LookupTable.Length).ToArray(); - + // Loop through and build the look-up table for (ushort i = 0; i < entryCount; i++) { diff --git a/BurnOutSharp.Wrappers/MicrosoftCabinet.fdi.cs b/BurnOutSharp.Wrappers/MicrosoftCabinet.fdi.cs index 5dc244d7..b548473e 100644 --- a/BurnOutSharp.Wrappers/MicrosoftCabinet.fdi.cs +++ b/BurnOutSharp.Wrappers/MicrosoftCabinet.fdi.cs @@ -1604,91 +1604,6 @@ // * and cabextract.c. // */ -// /* Bitstream reading macros (Quantum / normal byte order) -// * -// * Q_INIT_BITSTREAM should be used first to set up the system -// * Q_READ_BITS(var,n) takes N bits from the buffer and puts them in var. -// * unlike LZX, this can loop several times to get the -// * requisite number of bits. -// * Q_FILL_BUFFER adds more data to the bit buffer, if there is room -// * for another 16 bits. -// * Q_PEEK_BITS(n) extracts (without removing) N bits from the bit -// * buffer -// * Q_REMOVE_BITS(n) removes N bits from the bit buffer -// * -// * These bit access routines work by using the area beyond the MSB and the -// * LSB as a free source of zeroes. This avoids having to mask any bits. -// * So we have to know the bit width of the bitbuffer variable. This is -// * defined as Uint_BITS. -// * -// * Uint_BITS should be at least 16 bits. Unlike LZX's Huffman decoding, -// * Quantum's arithmetic decoding only needs 1 bit at a time, it doesn't -// * need an assured number. Retrieving larger bitstrings can be done with -// * multiple reads and fills of the bitbuffer. The code should work fine -// * for machines where Uint >= 32 bits. -// * -// * Also note that Quantum reads bytes in normal order; LZX is in -// * little-endian order. -// */ - -// // #define Q_INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0) - -// // #define Q_FILL_BUFFER do { \ -// // if (bitsleft <= (CAB_Uint_BITS - 16)) { \ -// // bitbuf |= ((inpos[0]<<8)|inpos[1]) << (CAB_Uint_BITS-16 - bitsleft); \ -// // bitsleft += 16; inpos += 2; \ -// // } \ -// // } while (0) - -// // #define Q_PEEK_BITS(n) (bitbuf >> (CAB_Uint_BITS - (n))) -// // #define Q_REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n))) - -// // #define Q_READ_BITS(v,n) do { \ -// // (v) = 0; \ -// // for (bitsneed = (n); bitsneed; bitsneed -= bitrun) { \ -// // Q_FILL_BUFFER; \ -// // bitrun = (bitsneed > bitsleft) ? bitsleft : bitsneed; \ -// // (v) = ((v) << bitrun) | Q_PEEK_BITS(bitrun); \ -// // Q_REMOVE_BITS(bitrun); \ -// // } \ -// // } while (0) - -// // #define Q_MENTRIES(model) (decomp_state.qtm.model).entries) -// // #define Q_MSYM(model,symidx) (decomp_state.qtm.model).syms[(symidx)].sym) -// // #define Q_MSYMFREQ(model,symidx) (decomp_state.qtm.model).syms[(symidx)].cumfreq) - -// /* GET_SYMBOL(model, var) fetches the next symbol from the stated model -// * and puts it in var. it may need to read the bitstream to do this. -// */ -// // #define GET_SYMBOL(m, var) do { \ -// // range = ((H - L) & 0xFFFF) + 1; \ -// // symf = ((((C - L + 1) * Q_MSYMFREQ(m,0)) - 1) / range) & 0xFFFF; \ -// // \ -// // for (i=1; i < Q_MENTRIES(m); i++) { \ -// // if (Q_MSYMFREQ(m,i) <= symf) break; \ -// // } \ -// // (var) = Q_MSYM(m,i-1); \ -// // \ -// // range = (H - L) + 1; \ -// // H = L + ((Q_MSYMFREQ(m,i-1) * range) / Q_MSYMFREQ(m,0)) - 1; \ -// // L = L + ((Q_MSYMFREQ(m,i) * range) / Q_MSYMFREQ(m,0)); \ -// // while (1) { \ -// // if ((L & 0x8000) != (H & 0x8000)) { \ -// // if ((L & 0x4000) && !(H & 0x4000)) { \ -// // /* underflow case */ \ -// // C ^= 0x4000; L &= 0x3FFF; H |= 0x4000; \ -// // } \ -// // else break; \ -// // } \ -// // L <<= 1; H = (H << 1) | 1; \ -// // Q_FILL_BUFFER; \ -// // C = (C << 1) | Q_PEEK_BITS(1); \ -// // Q_REMOVE_BITS(1); \ -// // } \ -// // \ -// // Quantum.UpdateModel(&(decomp_state.qtm.m)), i); \ -// // } while (0) - // /* Bitstream reading macros (LZX / intel little-endian byte order) // * // * INIT_BITSTREAM should be used first to set up the system