internal void DownHeap(short[] tree, int nodeIndex) { int index = nodeIndex << 1; int nodeIndex1 = this.Heap[nodeIndex]; for (; index <= this.HeapLength; index <<= 1) { if (index < this.HeapLength && DeflateCompressor.IsSmaller(tree, this.Heap[index + 1], this.Heap[index], this.Depth)) { ++index; } if (!DeflateCompressor.IsSmaller(tree, nodeIndex1, this.Heap[index], this.Depth)) { this.Heap[nodeIndex] = this.Heap[index]; nodeIndex = index; } else { break; } } this.Heap[nodeIndex] = nodeIndex1; }
internal void BuildTree(DeflateCompressor manager) { short[] dynamicTree = this.DynamicTree; short[] treeCodes = this.StaticTree.TreeCodes; int elements = this.StaticTree.Elements; int maxCode = -1; manager.HeapLength = 0; manager.HeapMax = Tree.HeapSize; for (int index = 0; index < elements; ++index) { if (dynamicTree[index * 2] != (short)0) { manager.Heap[++manager.HeapLength] = maxCode = index; manager.Depth[index] = (sbyte)0; } else { dynamicTree[index * 2 + 1] = (short)0; } } while (manager.HeapLength < 2) { int[] heap = manager.Heap; int index1 = ++manager.HeapLength; int num1; if (maxCode >= 2) { num1 = 0; } else { maxCode = num1 = maxCode + 1; } int num2 = num1; heap[index1] = num1; int index2 = num2; dynamicTree[index2 * 2] = (short)1; manager.Depth[index2] = (sbyte)0; --manager.OptimalLength; if (treeCodes != null) { manager.StaticLength -= (int)treeCodes[index2 * 2 + 1]; } } this.MaxCode = maxCode; for (int nodeIndex = manager.HeapLength / 2; nodeIndex >= 1; --nodeIndex) { manager.DownHeap(dynamicTree, nodeIndex); } int index3 = elements; do { int index1 = manager.Heap[1]; manager.Heap[1] = manager.Heap[manager.HeapLength--]; manager.DownHeap(dynamicTree, 1); int index2 = manager.Heap[1]; manager.Heap[--manager.HeapMax] = index1; manager.Heap[--manager.HeapMax] = index2; dynamicTree[index3 * 2] = (short)((int)dynamicTree[index1 * 2] + (int)dynamicTree[index2 * 2]); manager.Depth[index3] = (sbyte)((int)Math.Max((byte)manager.Depth[index1], (byte)manager.Depth[index2]) + 1); dynamicTree[index1 * 2 + 1] = dynamicTree[index2 * 2 + 1] = (short)index3; manager.Heap[1] = index3++; manager.DownHeap(dynamicTree, 1); }while (manager.HeapLength >= 2); manager.Heap[--manager.HeapMax] = manager.Heap[1]; this.GenerateBitLengths(manager); Tree.GenerateCodes(dynamicTree, maxCode, manager.BitLengthCount); }
private void GenerateBitLengths(DeflateCompressor manager) { short[] dynamicTree = this.DynamicTree; short[] treeCodes = this.StaticTree.TreeCodes; int[] extraBits = this.StaticTree.ExtraBits; int extraBase = this.StaticTree.ExtraBase; int maxLength = this.StaticTree.MaxLength; int num1 = 0; for (int index = 0; index <= 15; ++index) { manager.BitLengthCount[index] = (short)0; } dynamicTree[manager.Heap[manager.HeapMax] * 2 + 1] = (short)0; int index1; for (index1 = manager.HeapMax + 1; index1 < Tree.HeapSize; ++index1) { int num2 = manager.Heap[index1]; int index2 = (int)dynamicTree[(int)dynamicTree[num2 * 2 + 1] * 2 + 1] + 1; if (index2 > maxLength) { index2 = maxLength; ++num1; } dynamicTree[num2 * 2 + 1] = (short)index2; if (num2 <= this.MaxCode) { ++manager.BitLengthCount[index2]; int num3 = 0; if (num2 >= extraBase) { num3 = extraBits[num2 - extraBase]; } short num4 = dynamicTree[num2 * 2]; manager.OptimalLength += (int)num4 * (index2 + num3); if (treeCodes != null) { manager.StaticLength += (int)num4 * ((int)treeCodes[num2 * 2 + 1] + num3); } } } if (num1 == 0) { return; } do { int index2 = maxLength - 1; while (manager.BitLengthCount[index2] == (short)0) { --index2; } --manager.BitLengthCount[index2]; manager.BitLengthCount[index2 + 1] = (short)((int)manager.BitLengthCount[index2 + 1] + 2); --manager.BitLengthCount[maxLength]; num1 -= 2; }while (num1 > 0); for (int index2 = maxLength; index2 != 0; --index2) { int num2 = (int)manager.BitLengthCount[index2]; while (num2 != 0) { int num3 = manager.Heap[--index1]; if (num3 <= this.MaxCode) { int index3 = num3 * 2; int index4 = index3 + 1; if ((int)dynamicTree[index4] != index2) { manager.OptimalLength = (int)((long)manager.OptimalLength + ((long)index2 - (long)dynamicTree[index4]) * (long)dynamicTree[index3]); dynamicTree[index4] = (short)index2; } --num2; } } } }