ICSharpCode.SharpZipLib.Zip.Compression.DeflaterHuffman.Tree.BuildLength C# (CSharp) Method

BuildLength() public method

public BuildLength ( int childs ) : void
childs int
return void
            void BuildLength(int[] childs)
            {
                this.length = new byte[freqs.Length];
                int numNodes = childs.Length / 2;
                int numLeafs = (numNodes + 1) / 2;
                int overflow = 0;

                for (int i = 0; i < maxLength; i++) {
                    bl_counts[i] = 0;
                }

                // First calculate optimal bit lengths
                int[] lengths = new int[numNodes];
                lengths[numNodes - 1] = 0;

                for (int i = numNodes - 1; i >= 0; i--) {
                    if (childs[2 * i + 1] != -1) {
                        int bitLength = lengths[i] + 1;
                        if (bitLength > maxLength) {
                            bitLength = maxLength;
                            overflow++;
                        }
                        lengths[childs[2 * i]] = lengths[childs[2 * i + 1]] = bitLength;
                    } else {
                        // A leaf node
                        int bitLength = lengths[i];
                        bl_counts[bitLength - 1]++;
                        this.length[childs[2 * i]] = (byte)lengths[i];
                    }
                }

                //				if (DeflaterConstants.DEBUGGING) {
                //					//Console.WriteLine("Tree "+freqs.Length+" lengths:");
                //					for (int i=0; i < numLeafs; i++) {
                //						//Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
                //						                  + " len: "+length[childs[2*i]]);
                //					}
                //				}

                if (overflow == 0) {
                    return;
                }

                int incrBitLen = maxLength - 1;
                do {
                    // Find the first bit length which could increase:
                    while (bl_counts[--incrBitLen] == 0) {
                    }

                    // Move this node one down and remove a corresponding
                    // number of overflow nodes.
                    do {
                        bl_counts[incrBitLen]--;
                        bl_counts[++incrBitLen]++;
                        overflow -= 1 << (maxLength - 1 - incrBitLen);
                    } while (overflow > 0 && incrBitLen < maxLength - 1);
                } while (overflow > 0);

                /* We may have overshot above.  Move some nodes from maxLength to
                * maxLength-1 in that case.
                */
                bl_counts[maxLength - 1] += overflow;
                bl_counts[maxLength - 2] -= overflow;

                /* Now recompute all bit lengths, scanning in increasing
                * frequency.  It is simpler to reconstruct all lengths instead of
                * fixing only the wrong ones. This idea is taken from 'ar'
                * written by Haruhiko Okumura.
                *
                * The nodes were inserted with decreasing frequency into the childs
                * array.
                */
                int nodePtr = 2 * numLeafs;
                for (int bits = maxLength; bits != 0; bits--) {
                    int n = bl_counts[bits - 1];
                    while (n > 0) {
                        int childPtr = 2 * childs[nodePtr++];
                        if (childs[childPtr + 1] == -1) {
                            // We found another leaf
                            length[childs[childPtr]] = (byte)bits;
                            n--;
                        }
                    }
                }
                //				if (DeflaterConstants.DEBUGGING) {
                //					//Console.WriteLine("*** After overflow elimination. ***");
                //					for (int i=0; i < numLeafs; i++) {
                //						//Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
                //						                  + " len: "+length[childs[2*i]]);
                //					}
                //				}
            }