Example #1
0
            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);
                    }
                }
Example #2
0
        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);
        }