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);
        }
Beispiel #2
0
        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;
        }