private byte[] Buffer(int count) { byte[] buffer = new byte[count]; int numRead = 0; HuffmanTree tree = ReadHuffmanTree(); XpressBitStream bitStream = new XpressBitStream(_compressedStream); while (numRead < count) { uint symbol = tree.NextSymbol(bitStream); if (symbol < 256) { // The first 256 symbols are literal byte values buffer[numRead] = (byte)symbol; numRead++; } else { // The next 256 symbols are 4 bits each for offset and length. int offsetBits = (int)((symbol - 256) / 16); int len = (int)((symbol - 256) % 16); // The actual offset int offset = (int)((1 << offsetBits) - 1 + bitStream.Read(offsetBits)); // Lengths up to 15 bytes are stored directly in the symbol bits, beyond that // the length is stored in the compression stream. if (len == 15) { // Note this access is directly to the underlying stream - we're not going // through the bit stream. This makes the precise behaviour of the bit stream, // in terms of read-ahead critical. int b = ReadCompressedByte(); if (b == 0xFF) { // Again, note this access is directly to the underlying stream - we're not going // through the bit stream. len = ReadCompressedUShort(); } else { len += b; } } // Minimum length for a match is 3 bytes, so all lengths are stored as an offset // from 3. len += 3; // Simply do the copy for (int i = 0; i < len; ++i) { buffer[numRead] = buffer[numRead - offset - 1]; numRead++; } } } return(buffer); }
private byte[] Buffer(int count) { byte[] buffer = new byte[count]; int numRead = 0; HuffmanTree tree = ReadHuffmanTree(); XpressBitStream bitStream = new XpressBitStream(_compressedStream); while (numRead < count) { uint symbol = tree.NextSymbol(bitStream); if (symbol < 256) { // The first 256 symbols are literal byte values buffer[numRead] = (byte)symbol; numRead++; } else { // The next 256 symbols are 4 bits each for offset and length. int offsetBits = (int)((symbol - 256) / 16); int len = (int)((symbol - 256) % 16); // The actual offset int offset = (int)((1 << offsetBits) - 1 + bitStream.Read(offsetBits)); // Lengths up to 15 bytes are stored directly in the symbol bits, beyond that // the length is stored in the compression stream. if (len == 15) { // Note this access is directly to the underlying stream - we're not going // through the bit stream. This makes the precise behaviour of the bit stream, // in terms of read-ahead critical. int b = ReadCompressedByte(); if (b == 0xFF) { // Again, note this access is directly to the underlying stream - we're not going // through the bit stream. len = ReadCompressedUShort(); } else { len += b; } } // Minimum length for a match is 3 bytes, so all lengths are stored as an offset // from 3. len += 3; // Simply do the copy for (int i = 0; i < len; ++i) { buffer[numRead] = buffer[numRead - offset - 1]; numRead++; } } } return buffer; }