示例#1
0
        // Construct the Huffman tree for the bit lengths and return the index in
        // bl_order of the last bit length code to send.
        private static int Build_bl_tree(Deflate s)
        {
            int max_blindex; // index of last bit length code of non zero freq

            // Determine the bit length frequencies for literal and distance trees
            Scan_tree(s, s.DynLTree, s.DynLTree.MaxCode);
            Scan_tree(s, s.DynDTree, s.DynDTree.MaxCode);

            // Build the bit length tree:
            Build_tree(s, s.DynBLTree, StaticBlTreeDesc);

            // opt_len now includes the length of the tree representations, except
            // the lengths of the bit lengths codes and the 5+5+4 bits for the counts.

            // Determine the number of bit length codes to send. The pkzip format
            // requires that at least 4 bit length codes be sent. (appnote.txt says
            // 3 but the actual value used is 4.)
            DynamicTreeDesc blTree = s.DynBLTree;

            for (max_blindex = BLCODES - 1; max_blindex >= 3; max_blindex--)
            {
                if (blTree[GetBitLength(max_blindex)].Len != 0)
                {
                    break;
                }
            }

            // Update opt_len to include the bit length tree and counts
            s.OptLen += (3 * (max_blindex + 1)) + 5 + 5 + 4;

            return(max_blindex);
        }
示例#2
0
        /// <summary>
        /// Construct one Huffman tree and assigns the code bit strings and lengths.
        /// Update the total bit length for the current block.
        /// IN assertion: the field freq is set for all tree elements.
        /// OUT assertions: the fields len and code are set to the optimal bit length
        /// and corresponding code. The length opt_len is updated; static_len is
        /// also updated if stree is not null. The field max_code is set.
        /// </summary>
        /// <param name="s">The data compressor.</param>
        /// <param name="tree">The dynamic tree descriptor.</param>
        /// <param name="stree">The static tree descriptor.</param>
        public static void Build_tree(Deflate s, DynamicTreeDesc tree, StaticTreeDesc stree)
        {
            int     elems = stree.MaxElements;
            int     n, m;          // iterate over heap elements
            var     max_code = -1; // largest code with non zero frequency
            int     node;          // new node being created
            ushort *blCount = s.ConstBuffers.BlCountPointer;
            int *   heap    = s.ConstBuffers.HeapPointer;
            byte *  depth   = s.ConstBuffers.DepthPointer;

            // Construct the initial heap, with least frequent element in
            // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
            // heap[0] is not used.
            s.HeapLen = 0;
            s.HeapMax = HEAPSIZE;

            for (n = 0; n < elems; n++)
            {
                if (tree[n].Freq != 0)
                {
                    heap[++s.HeapLen] = max_code = n;
                    depth[n]          = 0;
                }
                else
                {
                    tree[n].Len = 0;
                }
            }

            // The pkzip format requires that at least one distance code exists,
            // and that at least one bit should be sent even if there is only one
            // possible code. So to avoid special checks later on we force at least
            // two codes of non zero frequency.
            ref CodeData streeCodeRef = ref stree.GetCodeDataReference();
示例#3
0
        /// <summary>
        /// Scan a literal or distance tree to determine the frequencies of the codes
        /// in the bit length tree.
        /// </summary>
        /// <param name="s">The data compressor.</param>
        /// <param name="tree">The tree to be scanned.</param>
        /// <param name="max_code">And its largest code of non zero frequency</param>
        public static void Scan_tree(Deflate s, DynamicTreeDesc tree, int max_code)
        {
            int             n;                       // iterates over all tree elements
            int             prevlen = -1;            // last emitted length
            int             curlen;                  // length of current code
            int             nextlen   = tree[0].Len; // length of next code
            ushort          count     = 0;           // repeat count of the current code
            int             max_count = 7;           // max repeat count
            int             min_count = 4;           // min repeat count
            DynamicTreeDesc blTree    = s.DynBLTree;

            if (nextlen == 0)
            {
                max_count = 138;
                min_count = 3;
            }

            tree[max_code + 1].Len = ushort.MaxValue; // guard

            for (n = 0; n <= max_code; n++)
            {
                curlen  = nextlen;
                nextlen = tree[n + 1].Len;
                if (++count < max_count && curlen == nextlen)
                {
                    continue;
                }
                else if (count < min_count)
                {
                    blTree[curlen].Freq += count;
                }
                else if (curlen != 0)
                {
                    if (curlen != prevlen)
                    {
                        blTree[curlen].Freq++;
                    }

                    blTree[REP36].Freq++;
                }
                else if (count <= 10)
                {
                    blTree[REPZ310].Freq++;
                }
                else
                {
                    blTree[REPZ11138].Freq++;
                }

                count   = 0;
                prevlen = curlen;
                if (nextlen == 0)
                {
                    max_count = 138;
                    min_count = 3;
                }
                else if (curlen == nextlen)
                {
                    max_count = 6;
                    min_count = 3;
                }
                else
                {
                    max_count = 7;
                    min_count = 4;
                }
            }
        }