private void BuildLength()

in src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs [475:579]


			private 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]]);
				//					}
				//				}
			}