Exemplo n.º 1
1
        /// <summary>
        /// Initializes a new instance of the BZip2DecoderStream class.
        /// </summary>
        /// <param name="stream">The compressed input stream.</param>
        /// <param name="ownsStream">Whether ownership of stream passes to the new instance.</param>
        public BZip2DecoderStream(Stream stream, Ownership ownsStream)
        {
            _compressedStream = stream;
            _ownsCompressed = ownsStream;

            _bitstream = new BigEndianBitStream(new BufferedStream(stream));

            // The Magic BZh
            byte[] magic = new byte[3];
            magic[0] = (byte)_bitstream.Read(8);
            magic[1] = (byte)_bitstream.Read(8);
            magic[2] = (byte)_bitstream.Read(8);
            if (magic[0] != 0x42 || magic[1] != 0x5A || magic[2] != 0x68)
            {
                throw new InvalidDataException("Bad magic at start of stream");
            }

            // The size of the decompression blocks in multiples of 100,000
            int blockSize = (int)_bitstream.Read(8) - 0x30;
            if (blockSize < 1 || blockSize > 9)
            {
                throw new InvalidDataException("Unexpected block size in header: " + blockSize);
            }

            blockSize *= 100000;

            _rleStream = new BZip2RleStream();
            _blockDecoder = new BZip2BlockDecoder(blockSize);
            _blockBuffer = new byte[blockSize];

            if (ReadBlock() == 0)
            {
                _eof = true;
            }
        }
Exemplo n.º 2
0
        public int Process(BitStream bitstream, byte[] outputBuffer, int outputBufferOffset)
        {
            _crc = 0;
            for (int i = 0; i < 4; ++i)
            {
                _crc = (_crc << 8) | bitstream.Read(8);
            }

            bool rand = bitstream.Read(1) != 0;
            int origPtr = (int)bitstream.Read(24);

            int thisBlockSize = ReadBuffer(bitstream, outputBuffer, outputBufferOffset);

            _inverseBurrowsWheeler.OriginalIndex = origPtr;
            _inverseBurrowsWheeler.Process(outputBuffer, outputBufferOffset, thisBlockSize, outputBuffer, outputBufferOffset);

            if (rand)
            {
                BZip2Randomizer randomizer = new BZip2Randomizer();
                randomizer.Process(outputBuffer, outputBufferOffset, thisBlockSize, outputBuffer, outputBufferOffset);
            }

            return thisBlockSize;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the BZip2DecoderStream class.
        /// </summary>
        /// <param name="stream">The compressed input stream.</param>
        /// <param name="ownsStream">Whether ownership of stream passes to the new instance.</param>
        public BZip2DecoderStream(Stream stream, Ownership ownsStream)
        {
            _compressedStream = stream;
            _ownsCompressed   = ownsStream;

            _bitstream = new BigEndianBitStream(new BufferedStream(stream));

            // The Magic BZh
            byte[] magic = new byte[3];
            magic[0] = (byte)_bitstream.Read(8);
            magic[1] = (byte)_bitstream.Read(8);
            magic[2] = (byte)_bitstream.Read(8);
            if (magic[0] != 0x42 || magic[1] != 0x5A || magic[2] != 0x68)
            {
                throw new InvalidDataException("Bad magic at start of stream");
            }

            // The size of the decompression blocks in multiples of 100,000
            int blockSize = (int)_bitstream.Read(8) - 0x30;

            if (blockSize < 1 || blockSize > 9)
            {
                throw new InvalidDataException("Unexpected block size in header: " + blockSize);
            }

            blockSize *= 100000;

            _rleStream    = new BZip2RleStream();
            _blockDecoder = new BZip2BlockDecoder(blockSize);
            _blockBuffer  = new byte[blockSize];

            if (ReadBlock() == 0)
            {
                _eof = true;
            }
        }
        private void Initialize(int maxSymbols)
        {
            int numTrees = (int)_bitstream.Read(3);

            if (numTrees < 2 || numTrees > 6)
            {
                throw new InvalidDataException("Invalid number of tables");
            }

            int numSelectors = (int)_bitstream.Read(15);

            if (numSelectors < 1)
            {
                throw new InvalidDataException("Invalid number of selectors");
            }

            _selectors = new byte[numSelectors];
            MoveToFront mtf = new MoveToFront(numTrees, true);

            for (int i = 0; i < numSelectors; ++i)
            {
                _selectors[i] = mtf.GetAndMove(CountSetBits(numTrees));
            }

            _trees = new HuffmanTree[numTrees];
            for (int t = 0; t < numTrees; ++t)
            {
                uint[] lengths = new uint[maxSymbols];

                uint len = _bitstream.Read(5);
                for (int i = 0; i < maxSymbols; ++i)
                {
                    if (len < 1 || len > 20)
                    {
                        throw new InvalidDataException("Invalid length constructing Huffman tree");
                    }

                    while (_bitstream.Read(1) != 0)
                    {
                        len = _bitstream.Read(1) == 0 ? len + 1 : len - 1;

                        if (len < 1 || len > 20)
                        {
                            throw new InvalidDataException("Invalid length constructing Huffman tree");
                        }
                    }

                    lengths[i] = len;
                }

                _trees[t] = new HuffmanTree(lengths);
            }

            _symbolsToNextSelector = 0;
            _nextSelector          = 0;
        }
Exemplo n.º 5
0
        public int Process(BitStream bitstream, byte[] outputBuffer, int outputBufferOffset)
        {
            _crc = 0;
            for (int i = 0; i < 4; ++i)
            {
                _crc = (_crc << 8) | bitstream.Read(8);
            }

            bool rand    = bitstream.Read(1) != 0;
            int  origPtr = (int)bitstream.Read(24);

            int thisBlockSize = ReadBuffer(bitstream, outputBuffer, outputBufferOffset);

            _inverseBurrowsWheeler.OriginalIndex = origPtr;
            _inverseBurrowsWheeler.Process(outputBuffer, outputBufferOffset, thisBlockSize, outputBuffer, outputBufferOffset);

            if (rand)
            {
                BZip2Randomizer randomizer = new BZip2Randomizer();
                randomizer.Process(outputBuffer, outputBufferOffset, thisBlockSize, outputBuffer, outputBufferOffset);
            }

            return(thisBlockSize);
        }
Exemplo n.º 6
0
        private static int ReadBuffer(BitStream bitstream, byte[] buffer, int offset)
        {
            // The MTF state
            int numInUse = 0;
            MoveToFront moveFrontTransform = new MoveToFront();
            bool[] inUseGroups = new bool[16];
            for (int i = 0; i < 16; ++i)
            {
                inUseGroups[i] = bitstream.Read(1) != 0;
            }

            for (int i = 0; i < 256; ++i)
            {
                if (inUseGroups[i / 16])
                {
                    if (bitstream.Read(1) != 0)
                    {
                        moveFrontTransform.Set(numInUse, (byte)i);
                        numInUse++;
                    }
                }
            }

            // Initialize 'virtual' Huffman tree from bitstream
            BZip2CombinedHuffmanTrees huffmanTree = new BZip2CombinedHuffmanTrees(bitstream, numInUse + 2);

            // Main loop reading data
            int readBytes = 0;
            while (true)
            {
                uint symbol = huffmanTree.NextSymbol();

                if (symbol < 2)
                {
                    // RLE, with length stored in a binary-style format
                    uint runLength = 0;
                    int bitShift = 0;
                    while (symbol < 2)
                    {
                        runLength += (symbol + 1) << bitShift;
                        bitShift++;

                        symbol = huffmanTree.NextSymbol();
                    }

                    byte b = moveFrontTransform.Head;
                    while (runLength > 0)
                    {
                        buffer[offset + readBytes] = b;
                        ++readBytes;
                        --runLength;
                    }
                }

                if (symbol <= numInUse)
                {
                    // Single byte
                    byte b = moveFrontTransform.GetAndMove((int)symbol - 1);
                    buffer[offset + readBytes] = b;
                    ++readBytes;
                }
                else if (symbol == numInUse + 1)
                {
                    // End of block marker
                    return readBytes;
                }
                else
                {
                    throw new InvalidDataException("Invalid symbol from Huffman table");
                }
            }
        }
Exemplo n.º 7
0
        private static int ReadBuffer(BitStream bitstream, byte[] buffer, int offset)
        {
            // The MTF state
            int         numInUse           = 0;
            MoveToFront moveFrontTransform = new MoveToFront();

            bool[] inUseGroups = new bool[16];
            for (int i = 0; i < 16; ++i)
            {
                inUseGroups[i] = bitstream.Read(1) != 0;
            }

            for (int i = 0; i < 256; ++i)
            {
                if (inUseGroups[i / 16])
                {
                    if (bitstream.Read(1) != 0)
                    {
                        moveFrontTransform.Set(numInUse, (byte)i);
                        numInUse++;
                    }
                }
            }

            // Initialize 'virtual' Huffman tree from bitstream
            BZip2CombinedHuffmanTrees huffmanTree = new BZip2CombinedHuffmanTrees(bitstream, numInUse + 2);

            // Main loop reading data
            int readBytes = 0;

            while (true)
            {
                uint symbol = huffmanTree.NextSymbol();

                if (symbol < 2)
                {
                    // RLE, with length stored in a binary-style format
                    uint runLength = 0;
                    int  bitShift  = 0;
                    while (symbol < 2)
                    {
                        runLength += (symbol + 1) << bitShift;
                        bitShift++;

                        symbol = huffmanTree.NextSymbol();
                    }

                    byte b = moveFrontTransform.Head;
                    while (runLength > 0)
                    {
                        buffer[offset + readBytes] = b;
                        ++readBytes;
                        --runLength;
                    }
                }

                if (symbol <= numInUse)
                {
                    // Single byte
                    byte b = moveFrontTransform.GetAndMove((int)symbol - 1);
                    buffer[offset + readBytes] = b;
                    ++readBytes;
                }
                else if (symbol == numInUse + 1)
                {
                    // End of block marker
                    return(readBytes);
                }
                else
                {
                    throw new InvalidDataException("Invalid symbol from Huffman table");
                }
            }
        }