예제 #1
0
        //Each block of compressed data begins with 3 header bits
        // containing the following data:
        //    first bit       BFINAL
        //    next 2 bits     BTYPE
        // Note that the header bits do not necessarily begin on a byte
        // boundary, since a block does not necessarily occupy an integral
        // number of bytes.
        // BFINAL is set if and only if this is the last block of the data
        // set.
        // BTYPE specifies how the data are compressed, as follows:
        //    00 - no compression
        //    01 - compressed with fixed Huffman codes
        //    10 - compressed with dynamic Huffman codes
        //    11 - reserved (error)
        // The only difference between the two compressed cases is how the
        // Huffman codes for the literal/length and distance alphabets are
        // defined.
        //
        // This function returns true for success (end of block or output window is full,)
        // false if we are short of input
        //
        private bool Decode()
        {
            bool eob    = false;
            bool result = false;

            if (Finished())
            {
                return(true);
            }

            if (hasFormatReader)
            {
                if (state == InflaterState.ReadingHeader)
                {
                    if (!formatReader.ReadHeader(input))
                    {
                        return(false);
                    }
                    state = InflaterState.ReadingBFinal;
                }
                else if (state == InflaterState.StartReadingFooter || state == InflaterState.ReadingFooter)
                {
                    if (!formatReader.ReadFooter(input))
                    {
                        return(false);
                    }

                    state = InflaterState.VerifyingFooter;
                    return(true);
                }
            }

            if (state == InflaterState.ReadingBFinal)
            {   // reading bfinal bit
                // Need 1 bit
                if (!input.EnsureBitsAvailable(1))
                {
                    return(false);
                }

                bfinal = input.GetBits(1);
                state  = InflaterState.ReadingBType;
            }

            if (state == InflaterState.ReadingBType)
            {
                // Need 2 bits
                if (!input.EnsureBitsAvailable(2))
                {
                    state = InflaterState.ReadingBType;
                    return(false);
                }

                blockType = (BlockType)input.GetBits(2);
                if (blockType == BlockType.Dynamic)
                {
                    Debug.WriteLineIf(CompressionTracingSwitch.Informational, "Decoding Dynamic Block", "Compression");
                    state = InflaterState.ReadingNumLitCodes;
                }
                else if (blockType == BlockType.Static)
                {
                    Debug.WriteLineIf(CompressionTracingSwitch.Informational, "Decoding Static Block", "Compression");
                    literalLengthTree = HuffmanTree.StaticLiteralLengthTree;
                    distanceTree      = HuffmanTree.StaticDistanceTree;
                    state             = InflaterState.DecodeTop;
                }
                else if (blockType == BlockType.Uncompressed)
                {
                    Debug.WriteLineIf(CompressionTracingSwitch.Informational, "Decoding UnCompressed Block", "Compression");
                    state = InflaterState.UncompressedAligning;
                }
                else
                {
                    throw new InvalidDataException("UnknownBlockType");
                }
            }

            if (blockType == BlockType.Dynamic)
            {
                if (state < InflaterState.DecodeTop)
                {   // we are reading the header
                    result = DecodeDynamicBlockHeader();
                }
                else
                {
                    result = DecodeBlock(out eob);  // this can returns true when output is full
                }
            }
            else if (blockType == BlockType.Static)
            {
                result = DecodeBlock(out eob);
            }
            else if (blockType == BlockType.Uncompressed)
            {
                result = DecodeUncompressedBlock(out eob);
            }
            else
            {
                throw new InvalidDataException("UnknownBlockType");
            }

            //
            // If we reached the end of the block and the block we were decoding had
            // bfinal=1 (final block)
            //
            if (eob && (bfinal != 0))
            {
                if (hasFormatReader)
                {
                    state = InflaterState.StartReadingFooter;
                }
                else
                {
                    state = InflaterState.Done;
                }
            }
            return(result);
        }
예제 #2
0
        //Each block of compressed data begins with 3 header bits
        // containing the following data:
        //    first bit       BFINAL
        //    next 2 bits     BTYPE
        // Note that the header bits do not necessarily begin on a byte
        // boundary, since a block does not necessarily occupy an integral
        // number of bytes.
        // BFINAL is set if and only if this is the last block of the data
        // set.
        // BTYPE specifies how the data are compressed, as follows:
        //    00 - no compression
        //    01 - compressed with fixed Huffman codes
        //    10 - compressed with dynamic Huffman codes
        //    11 - reserved (error)
        // The only difference between the two compressed cases is how the
        // Huffman codes for the literal/length and distance alphabets are
        // defined.
        //
        // This function returns true for success (end of block or output window is full,)
        // false if we are short of input
        //
        private bool Decode()
        {
            bool eob = false;
            bool result;

            if (Finished())
            {
                return(true);
            }

            if (_hasFormatReader)
            {
                if (_state == Inflater64State.ReadingHeader)
                {
                    if (!_formatReader.ReadHeader(_input))
                    {
                        return(false);
                    }
                    _state = Inflater64State.ReadingBFinal;
                }
                else if (_state == Inflater64State.StartReadingFooter || _state == Inflater64State.ReadingFooter)
                {
                    if (!_formatReader.ReadFooter(_input))
                    {
                        return(false);
                    }

                    _state = Inflater64State.VerifyingFooter;
                    return(true);
                }
            }

            if (_state == Inflater64State.ReadingBFinal)
            {
                // reading bfinal bit
                // Need 1 bit
                if (!_input.EnsureBitsAvailable(1))
                {
                    return(false);
                }

                _bfinal = _input.GetBits(1);
                _state  = Inflater64State.ReadingBType;
            }

            if (_state == Inflater64State.ReadingBType)
            {
                // Need 2 bits
                if (!_input.EnsureBitsAvailable(2))
                {
                    _state = Inflater64State.ReadingBType;
                    return(false);
                }

                _blockType = (BlockType)_input.GetBits(2);
                if (_blockType == BlockType.Dynamic)
                {
                    _state = Inflater64State.ReadingNumLitCodes;
                }
                else if (_blockType == BlockType.Static)
                {
                    _literalLengthTree = HuffmanTree.StaticLiteralLengthTree;
                    _distanceTree      = HuffmanTree.StaticDistanceTree;
                    _state             = Inflater64State.DecodeTop;
                }
                else if (_blockType == BlockType.Uncompressed)
                {
                    _state = Inflater64State.UncompressedAligning;
                }
                else
                {
                    throw new InvalidDataException(SR.UnknownBlockType);
                }
            }

            if (_blockType == BlockType.Dynamic)
            {
                if (_state < Inflater64State.DecodeTop)
                {
                    // we are reading the header
                    result = DecodeDynamicBlockHeader();
                }
                else
                {
                    result = DecodeBlock(out eob); // this can returns true when output is full
                }
            }
            else if (_blockType == BlockType.Static)
            {
                result = DecodeBlock(out eob);
            }
            else if (_blockType == BlockType.Uncompressed)
            {
                result = DecodeUncompressedBlock(out eob);
            }
            else
            {
                throw new InvalidDataException(SR.UnknownBlockType);
            }

            //
            // If we reached the end of the block and the block we were decoding had
            // bfinal=1 (final block)
            //
            if (eob && (_bfinal != 0))
            {
                if (_hasFormatReader)
                {
                    _state = Inflater64State.StartReadingFooter;
                }
                else
                {
                    _state = Inflater64State.Done;
                }
            }
            return(result);
        }
예제 #3
0
        //Each block of compressed data begins with 3 header bits
        // containing the following data:
        //    first bit       BFINAL
        //    next 2 bits     BTYPE
        // Note that the header bits do not necessarily begin on a byte
        // boundary, since a block does not necessarily occupy an integral
        // number of bytes.
        // BFINAL is set if and only if this is the last block of the data
        // set.
        // BTYPE specifies how the data are compressed, as follows:
        //    00 - no compression
        //    01 - compressed with fixed Huffman codes
        //    10 - compressed with dynamic Huffman codes
        //    11 - reserved (error)
        // The only difference between the two compressed cases is how the
        // Huffman codes for the literal/length and distance alphabets are
        // defined.
        //
        // This function returns true for success (end of block or output window is full,)
        // false if we are short of input
        //
        private bool Decode()
        {
            var eob    = false;
            var result = false;

            if (Finished())
            {
                return(true);
            }

            if (_hasFormatReader)
            {
                switch (_state)
                {
                case InflaterState.ReadingHeader:
                    if (!_formatReader.ReadHeader(_input))
                    {
                        return(false);
                    }
                    _state = InflaterState.ReadingBFinal;
                    break;

                case InflaterState.ReadingFooter:
                case InflaterState.StartReadingFooter:
                    if (!_formatReader.ReadFooter(_input))
                    {
                        return(false);
                    }
                    _state = InflaterState.VerifyingFooter;
                    return(true);
                }
            }

            if (_state == InflaterState.ReadingBFinal)
            {   // reading bfinal bit
                // Need 1 bit
                if (!_input.EnsureBitsAvailable(1))
                {
                    return(false);
                }

                _bfinal = _input.GetBits(1);
                _state  = InflaterState.ReadingBType;
            }

            if (_state == InflaterState.ReadingBType)
            {
                // Need 2 bits
                if (!_input.EnsureBitsAvailable(2))
                {
                    _state = InflaterState.ReadingBType;
                    return(false);
                }

                _blockType = (BlockType)_input.GetBits(2);
                switch (_blockType)
                {
                case BlockType.Dynamic:
                    _state = InflaterState.ReadingNumLitCodes;
                    break;

                case BlockType.Static:
                    _literalLengthTree = HuffmanTree.StaticLiteralLengthTree;
                    _distanceTree      = HuffmanTree.StaticDistanceTree;
                    _state             = InflaterState.DecodeTop;
                    break;

                case BlockType.Uncompressed:
                    _state = InflaterState.UncompressedAligning;
                    break;

                default:
                    throw new InvalidDataContractException("Unknown block type.");
                }
            }

            switch (_blockType)
            {
            case BlockType.Dynamic:
                result = _state < InflaterState.DecodeTop ? DecodeDynamicBlockHeader() : DecodeBlock(out eob);
                break;

            case BlockType.Static:
                result = DecodeBlock(out eob);
                break;

            case BlockType.Uncompressed:
                result = DecodeUncompressedBlock(out eob);
                break;

            default:
                throw new InvalidDataContractException("Unknown block type.");
            }

            //
            // If we reached the end of the block and the block we were decoding had
            // bfinal=1 (final block)
            //
            if (!eob || (_bfinal == 0))
            {
                return(result);
            }
            _state = _hasFormatReader ? InflaterState.StartReadingFooter : InflaterState.Done;
            return(result);
        }