public static unsafe void ProduceLengths( BitSource data, ushort *tree, ushort literalLengthCodeCount, byte distanceCodeCount, byte *literalLengths, byte *distanceLengths) { var valuesToProduce = literalLengthCodeCount + distanceCodeCount; var valuesProduced = 0; byte lastValueProduced = 0; while (valuesProduced < valuesToProduce) { byte codeLength = 0; uint branch = 0; while (true) { var bit = data.CurrentBitValue(); branch = tree[branch * 2 + bit]; if (branch >= TreeNode.Threshold) { // Take lower bits codeLength = (byte)branch; break; } } //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) if (codeLength == 18) { ProduceRepeat(0, 11, bitsAsRepeat: 7); } else if (codeLength == 17) { ProduceRepeat(0, 3, bitsAsRepeat: 3); } else if (codeLength == 16) { ProduceRepeat(lastValueProduced, 3, bitsAsRepeat: 2); } else { ProduceValue(codeLength); } }
private ushort TraverseTree(ushort *tree, BitSource bitsource) { uint branch = 0; uint availableBits = 0; ulong bits = 0; while (branch < TreeNode.Threshold) { ulong consumed = 0; availableBits = (uint)bitsource.AvailableBits(); bits = bitsource.PeekBits(); while (availableBits > consumed && branch < TreeNode.Threshold) { var bit = bits & 1; bits >>= 1; branch = tree[branch * 2 + bit]; consumed++; } bitsource.Consume(consumed); if (branch < TreeNode.Threshold) { var bit = bitsource.CurrentBitValue(); branch = tree[branch * 2 + bit]; } } return((ushort)branch); }