예제 #1
0
        static DecompressorHuffmanTree()
        {
            try
            {
                byte[] lengths;
                int index;

                lengths = new byte[288];
                index = 0;

                while (index < 144)
                {
                    lengths[index++] = 8;
                }

                while (index < 256)
                {
                    lengths[index++] = 9;
                }

                while (index < 280)
                {
                    lengths[index++] = 7;
                }

                while (index < 288)
                {
                    lengths[index++] = 8;
                }

                m_LengthTree = new DecompressorHuffmanTree(lengths);

                lengths = new byte[32];
                index = 0;

                while (index < 32)
                {
                    lengths[index++] = 5;
                }

                m_DistanceTree = new DecompressorHuffmanTree(lengths);
            }
            catch (Exception ex)
            {
                throw new Exception("DecompressorHuffmanTree: fixed trees generation failed", ex);
            }
        }
예제 #2
0
        protected void DecodeDynHeader(out DecompressorHuffmanTree lengthTree, out DecompressorHuffmanTree distanceTree)
        {
            byte[] arrDecoderCodeLengths;
            byte[] arrResultingCodeLengths;

            byte bLastSymbol = 0;
            int iLengthsCount = ReadBits(5);
            int iDistancesCount = ReadBits(5);
            int iCodeLengthsCount = ReadBits(4);

            if (iLengthsCount < 0 || iDistancesCount < 0 || iCodeLengthsCount < 0)
                throw new FormatException("Wrong dynamic huffman codes.");

            iLengthsCount += 257;
            iDistancesCount += 1;

            int iResultingCodeLengthsCount = iLengthsCount + iDistancesCount;
            arrResultingCodeLengths = new byte[iResultingCodeLengthsCount];
            arrDecoderCodeLengths = new byte[19];
            iCodeLengthsCount += 4;
            int iCurrentCode = 0;

            while (iCurrentCode < iCodeLengthsCount)
            {
                int len = ReadBits(3);

                if (len < 0)
                    throw new FormatException("Wrong dynamic huffman codes.");

                arrDecoderCodeLengths[BitUtils.DEF_HUFFMAN_DYNTREE_CODELENGTHS_ORDER[iCurrentCode++]] =
                  (byte)len;
            }

            DecompressorHuffmanTree treeInternalDecoder = new
              DecompressorHuffmanTree(arrDecoderCodeLengths);

            iCurrentCode = 0;

            for (; ; )
            {
                int symbol;
                bool bNeedBreak = false;

                while (((symbol = treeInternalDecoder.UnpackSymbol(this)) & ~15) == 0)
                {
                    arrResultingCodeLengths[iCurrentCode++] = bLastSymbol = (byte)symbol;

                    if (iCurrentCode == iResultingCodeLengthsCount)
                    {
                        bNeedBreak = true;
                        break;
                    }
                }

                if (bNeedBreak) break;

                if (symbol < 0)
                    throw new FormatException("Wrong dynamic huffman codes.");

                if (symbol >= 17)
                {
                    bLastSymbol = 0;
                }
                else if (iCurrentCode == 0)
                {
                    throw new FormatException("Wrong dynamic huffman codes.");
                }

                int m_iRepSymbol = symbol - 16;
                int bits = DEF_HUFFMAN_DYNTREE_REPEAT_BITS[m_iRepSymbol];

                int count = ReadBits(bits);

                if (count < 0)
                    throw new FormatException("Wrong dynamic huffman codes.");

                count += DEF_HUFFMAN_DYNTREE_REPEAT_MINIMUMS[m_iRepSymbol];

                if (iCurrentCode + count > iResultingCodeLengthsCount)
                    throw new FormatException("Wrong dynamic huffman codes.");

                while (count-- > 0)
                {
                    arrResultingCodeLengths[iCurrentCode++] = bLastSymbol;
                }

                if (iCurrentCode == iResultingCodeLengthsCount) break;
            }

            byte[] tempArray = new byte[iLengthsCount];
            Array.Copy(arrResultingCodeLengths, 0, tempArray, 0, iLengthsCount);
            lengthTree = new DecompressorHuffmanTree(tempArray);

            tempArray = new byte[iDistancesCount];
            Array.Copy(arrResultingCodeLengths, iLengthsCount, tempArray, 0, iDistancesCount);
            distanceTree = new DecompressorHuffmanTree(tempArray);

        }
예제 #3
0
        protected bool DecodeBlockHeader()
        {
            if (!m_bCanReadNextBlock)
            {
                return false;
            }

            int bFinalBlock = ReadBits(1);
            if (bFinalBlock == -1)
            {
                return false;
            }

            int blockType = ReadBits(2);
            if (blockType == -1)
            {
                return false;
            }

            m_bCanReadNextBlock = (bFinalBlock == 0);
            switch (blockType)
            {
                case 0:
                    m_bReadingUncompressed = true;

                    SkipToBoundary();
                    int length = ReadInt16Inverted();
                    int lengthComplement = ReadInt16Inverted();

                    if (length != (lengthComplement ^ 0xffff))
                        throw new FormatException("Wrong block length.");

                    if (length > UInt16.MaxValue)
                        throw new FormatException("Uncompressed block length can not be more than 65535.");

                    m_UncompressedDataLength = length;
                    m_CurrentLengthTree = null;
                    m_CurrentDistanceTree = null;
                    break;

                case 1:
                    m_bReadingUncompressed = false;
                    m_UncompressedDataLength = -1;
                    m_CurrentLengthTree = DecompressorHuffmanTree.LengthTree;
                    m_CurrentDistanceTree = DecompressorHuffmanTree.DistanceTree;
                    break;

                case 2:
                    m_bReadingUncompressed = false;
                    m_UncompressedDataLength = -1;
                    DecodeDynHeader(out m_CurrentLengthTree, out m_CurrentDistanceTree);
                    break;

                default:
                    throw new FormatException("Wrong block type.");
            }

            return true;
        }