Ejemplo n.º 1
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);

        }