Ejemplo n.º 1
0
        /// <summary>
        /// Write the tree to output file
        /// </summary>
        /// <param name="blTree">The bl tree.</param>
        public void WriteTree(DeflateTree blTree)
        {
            for (int code = 0; code < MaxUsedCodes;)
            {
                // current code length
                int codeLen = _codeLength[code];

                // scan the code array for equal code lengths
                int count = 1;
                for (code++; code < MaxUsedCodes && codeLen == _codeLength[code]; code++)
                {
                    count++;
                }

                // less than three equal code length
                if (count < 3)
                {
                    // write the first code length to output file
                    blTree.WriteSymbol(codeLen);

                    // write the second code length to output file
                    if (count > 1)
                    {
                        blTree.WriteSymbol(codeLen);
                    }
                    continue;
                }

                // Used code. Code length is other than zero.
                if (codeLen != 0)
                {
                    // write the code length to output file
                    blTree.WriteSymbol(codeLen);

                    // reduce the count by one
                    count--;

                    // for every full block of 6 repeats add one REP_3_6 code and two bits of 1 (11)
                    for (int index = count / 6; index > 0; index--)
                    {
                        blTree.WriteSymbol(RepeatSymbol_3_6);
                        _writeBits(6 - 3, 2);
                    }

                    // get the remainder
                    if ((count = count % 6) == 0)
                    {
                        continue;
                    }

                    // remainder is less than 3
                    if (count < 3)
                    {
                        // write the code length to output file
                        blTree.WriteSymbol(codeLen);
                        if (count > 1)
                        {
                            blTree.WriteSymbol(codeLen);
                        }
                        continue;
                    }

                    // remainder is beween 3 to 5
                    blTree.WriteSymbol(RepeatSymbol_3_6);
                    _writeBits(count - 3, 2);
                    continue;
                }

                // code length is zero and count is 3 or more
                // for every full block of 138 repeats add one REP_11_138 code plus 7 bits of 1
                for (int index = count / 138; index > 0; index--)
                {
                    blTree.WriteSymbol(RepeatSymbol_11_138);
                    _writeBits(138 - 11, 7);
                }

                // get the remainder
                if ((count = count % 138) == 0)
                {
                    continue;
                }

                // remainder is less than 3
                if (count < 3)
                {
                    // write the code length to output file
                    blTree.WriteSymbol(codeLen);
                    if (count > 1)
                    {
                        blTree.WriteSymbol(codeLen);
                    }
                    continue;
                }

                // remainder is beween 3 to 10
                if (count <= 10)
                {
                    blTree.WriteSymbol(RepeatSymbol_3_10);
                    _writeBits(count - 3, 3);
                    continue;
                }

                // remainder is beween 11 to 137
                blTree.WriteSymbol(RepeatSymbol_11_138);
                _writeBits(count - 11, 7);
            }
        }
Ejemplo n.º 2
0
        ////////////////////////////////////////////////////////////////////
        // calculate Bit Length frequency
        ///	0 - 15: Represent code lengths of 0 - 15
        //	16: Copy the previous code length 3 - 6 times.
        //		The next 2 bits indicate repeat length
        //		(0 = 3, ... , 3 = 6)
        //		Example:  Codes 8, 16 (+2 bits 11), 16 (+2 bits 10) will expand to
        //		12 code lengths of 8 (1 + 6 + 5)
        //	17: Repeat a code length of 0 for 3 - 10 times. (3 bits of length)
        //	18: Repeat a code length of 0 for 11 - 138 times. (7 bits of length)
        ////////////////////////////////////////////////////////////////////
        public Int32 CalcBLFreq(DeflateTree blTree)
        {
            int extraBits = 0;

            for (int code = 0; code < MaxUsedCodes;)
            {
                // current code length
                int codeLen = _codeLength[code];

                // scan the code array for equal code lengths
                int count = 1;
                for (code++; code < MaxUsedCodes && codeLen == _codeLength[code]; code++)
                {
                    count++;
                }

                // less than three equal code length
                if (count < 3)
                {
                    blTree.CodeFreq[codeLen] += (short)count;
                    continue;
                }

                // code length is other than zero
                if (codeLen != 0)
                {
                    // add one to the frequency of the code itself
                    blTree.CodeFreq[codeLen]++;

                    // reduce the count by one
                    count--;

                    // for every full block of 6 repeats add one REP_3_6 code
                    blTree.CodeFreq[RepeatSymbol_3_6] += count / 6;
                    extraBits += 2 * (count / 6);

                    // get the remainder
                    if ((count = count % 6) == 0)
                    {
                        continue;
                    }

                    // remainder is less than 3
                    if (count < 3)
                    {
                        blTree.CodeFreq[codeLen] += count;
                        continue;
                    }

                    // remainder is beween 3 to 5
                    blTree.CodeFreq[RepeatSymbol_3_6]++;
                    extraBits += 2;
                    continue;
                }

                // code length is zero and count is 3 or more
                // for every full block of 138 repeats add one REP_11_138 code
                blTree.CodeFreq[RepeatSymbol_11_138] += count / 138;
                extraBits += 7 * (count / 138);

                // get the remainder
                if ((count = count % 138) == 0)
                {
                    continue;
                }

                // remainder is less than 3
                if (count < 3)
                {
                    blTree.CodeFreq[codeLen] += count;
                    continue;
                }

                // remainder is beween 3 to 10
                if (count <= 10)
                {
                    blTree.CodeFreq[RepeatSymbol_3_10]++;
                    extraBits += 3;
                    continue;
                }

                // remainder is beween 11 to 137
                blTree.CodeFreq[RepeatSymbol_11_138]++;
                extraBits += 7;
            }
            return(extraBits);
        }