Beispiel #1
0
        private void ReadMainTree()
        {
            uint[] lengths;

            if (_mainTree == null)
            {
                lengths = new uint[256 + 8 * _numPositionSlots];
            }
            else
            {
                lengths = _mainTree.Lengths;
            }

            HuffmanTree preTree = ReadFixedHuffmanTree(20, 4);

            ReadLengths(preTree, lengths, 0, 256);
            preTree = ReadFixedHuffmanTree(20, 4);
            ReadLengths(preTree, lengths, 256, 8 * _numPositionSlots);

            _mainTree = new HuffmanTree(lengths);
        }
Beispiel #2
0
        private void ReadLengths(HuffmanTree preTree, uint[] lengths, int offset, int count)
        {
            int i = 0;

            while (i < count)
            {
                uint value = preTree.NextSymbol(_bitStream);

                if (value == 17)
                {
                    uint numZeros = 4 + _bitStream.Read(4);
                    for (uint j = 0; j < numZeros; ++j)
                    {
                        lengths[offset + i] = 0;
                        ++i;
                    }
                }
                else if (value == 18)
                {
                    uint numZeros = 20 + _bitStream.Read(5);
                    for (uint j = 0; j < numZeros; ++j)
                    {
                        lengths[offset + i] = 0;
                        ++i;
                    }
                }
                else if (value == 19)
                {
                    uint same = _bitStream.Read(1);
                    value = preTree.NextSymbol(_bitStream);

                    if (value > 16)
                    {
                        throw new InvalidDataException("Invalid table encoding");
                    }

                    uint symbol = (17 + lengths[offset + i] - value) % 17;
                    for (uint j = 0; j < 4 + same; ++j)
                    {
                        lengths[offset + i] = symbol;
                        ++i;
                    }
                }
                else
                {
                    lengths[offset + i] = (17 + lengths[offset + i] - value) % 17;
                    ++i;
                }
            }
        }
Beispiel #3
0
        private HuffmanTree ReadDynamicHuffmanTree(int count, HuffmanTree preTree, HuffmanTree oldTree)
        {
            uint[] lengths;

            if (oldTree == null)
            {
                lengths = new uint[256 + 8 * _numPositionSlots];
            }
            else
            {
                lengths = oldTree.Lengths;
            }

            ReadLengths(preTree, lengths, 0, count);

            return new HuffmanTree(lengths);
        }
Beispiel #4
0
 private void ReadLengthTree()
 {
     HuffmanTree preTree = ReadFixedHuffmanTree(20, 4);
     _lengthTree = ReadDynamicHuffmanTree(249, preTree, _lengthTree);
 }
Beispiel #5
0
        private void ReadMainTree()
        {
            uint[] lengths;

            if (_mainTree == null)
            {
                lengths = new uint[256 + 8 * _numPositionSlots];
            }
            else
            {
                lengths = _mainTree.Lengths;
            }

            HuffmanTree preTree = ReadFixedHuffmanTree(20, 4);
            ReadLengths(preTree, lengths, 0, 256);
            preTree = ReadFixedHuffmanTree(20, 4);
            ReadLengths(preTree, lengths, 256, 8 * _numPositionSlots);

            _mainTree = new HuffmanTree(lengths);
        }
Beispiel #6
0
        private void DecodeCompressedBlock(BlockType blockType, int blockSize)
        {
            if (blockType == BlockType.AlignedOffset)
            {
                _alignedOffsetTree = ReadFixedHuffmanTree(8, 3);
            }
            ReadMainTree();
            ReadLengthTree();
            
            uint numRead = 0;
            while (numRead < (uint)blockSize)
            {
                uint symbol = _mainTree.NextSymbol(_bitStream);

                if (symbol < 256)
                {
                    _buffer[_bufferCount + numRead++] = (byte)symbol;
                }
                else
                {
                    uint lengthHeader = (symbol - 256) & 7;
                    uint matchLength = lengthHeader + 2 + ((lengthHeader == 7) ? _lengthTree.NextSymbol(_bitStream) : 0);
                    uint positionSlot = (symbol - 256) >> 3;

                    uint matchOffset;
                    if (positionSlot == 0)
                    {
                        matchOffset = _repeatedOffsets[0];
                    }
                    else if (positionSlot == 1)
                    {
                        matchOffset = _repeatedOffsets[1];
                        _repeatedOffsets[1] = _repeatedOffsets[0];
                        _repeatedOffsets[0] = matchOffset;
                    }
                    else if (positionSlot == 2)
                    {
                        matchOffset = _repeatedOffsets[2];
                        _repeatedOffsets[2] = _repeatedOffsets[0];
                        _repeatedOffsets[0] = matchOffset;
                    }
                    else
                    {
                        int extra = (int)s_extraBits[positionSlot];

                        uint formattedOffset;

                        if (blockType == BlockType.AlignedOffset)
                        {
                            uint verbatimBits = 0;
                            uint alignedBits = 0;

                            if (extra >= 3)
                            {
                                verbatimBits = _bitStream.Read(extra - 3) << 3;
                                alignedBits = _alignedOffsetTree.NextSymbol(_bitStream);
                            }
                            else if (extra > 0)
                            {
                                verbatimBits = _bitStream.Read(extra);
                            }

                            formattedOffset = s_positionSlots[positionSlot] + verbatimBits + alignedBits;
                        }
                        else
                        {
                            uint verbatimBits = (extra > 0) ? _bitStream.Read(extra) : 0;

                            formattedOffset = s_positionSlots[positionSlot] + verbatimBits;
                        }

                        matchOffset = formattedOffset - 2;

                        _repeatedOffsets[2] = _repeatedOffsets[1];
                        _repeatedOffsets[1] = _repeatedOffsets[0];
                        _repeatedOffsets[0] = matchOffset;
                    }

                    int destOffset = _bufferCount + (int)numRead;
                    int srcOffset = destOffset - (int)matchOffset;
                    for (int i = 0; i < matchLength; ++i)
                    {
                        _buffer[destOffset + i] = _buffer[srcOffset + i];
                    }

                    numRead += matchLength;
                }
            }
        }
        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 #8
0
        private void ReadLengthTree()
        {
            HuffmanTree preTree = ReadFixedHuffmanTree(20, 4);

            _lengthTree = ReadDynamicHuffmanTree(249, preTree, _lengthTree);
        }
Beispiel #9
0
        private void DecodeCompressedBlock(BlockType blockType, int blockSize)
        {
            if (blockType == BlockType.AlignedOffset)
            {
                _alignedOffsetTree = ReadFixedHuffmanTree(8, 3);
            }
            ReadMainTree();
            ReadLengthTree();

            uint numRead = 0;

            while (numRead < (uint)blockSize)
            {
                uint symbol = _mainTree.NextSymbol(_bitStream);

                if (symbol < 256)
                {
                    _buffer[_bufferCount + numRead++] = (byte)symbol;
                }
                else
                {
                    uint lengthHeader = (symbol - 256) & 7;
                    uint matchLength  = lengthHeader + 2 + ((lengthHeader == 7) ? _lengthTree.NextSymbol(_bitStream) : 0);
                    uint positionSlot = (symbol - 256) >> 3;

                    uint matchOffset;
                    if (positionSlot == 0)
                    {
                        matchOffset = _repeatedOffsets[0];
                    }
                    else if (positionSlot == 1)
                    {
                        matchOffset         = _repeatedOffsets[1];
                        _repeatedOffsets[1] = _repeatedOffsets[0];
                        _repeatedOffsets[0] = matchOffset;
                    }
                    else if (positionSlot == 2)
                    {
                        matchOffset         = _repeatedOffsets[2];
                        _repeatedOffsets[2] = _repeatedOffsets[0];
                        _repeatedOffsets[0] = matchOffset;
                    }
                    else
                    {
                        int extra = (int)s_extraBits[positionSlot];

                        uint formattedOffset;

                        if (blockType == BlockType.AlignedOffset)
                        {
                            uint verbatimBits = 0;
                            uint alignedBits  = 0;

                            if (extra >= 3)
                            {
                                verbatimBits = _bitStream.Read(extra - 3) << 3;
                                alignedBits  = _alignedOffsetTree.NextSymbol(_bitStream);
                            }
                            else if (extra > 0)
                            {
                                verbatimBits = _bitStream.Read(extra);
                            }

                            formattedOffset = s_positionSlots[positionSlot] + verbatimBits + alignedBits;
                        }
                        else
                        {
                            uint verbatimBits = (extra > 0) ? _bitStream.Read(extra) : 0;

                            formattedOffset = s_positionSlots[positionSlot] + verbatimBits;
                        }

                        matchOffset = formattedOffset - 2;

                        _repeatedOffsets[2] = _repeatedOffsets[1];
                        _repeatedOffsets[1] = _repeatedOffsets[0];
                        _repeatedOffsets[0] = matchOffset;
                    }

                    int destOffset = _bufferCount + (int)numRead;
                    int srcOffset  = destOffset - (int)matchOffset;
                    for (int i = 0; i < matchLength; ++i)
                    {
                        _buffer[destOffset + i] = _buffer[srcOffset + i];
                    }

                    numRead += matchLength;
                }
            }
        }