Blast.Blast.Decode C# (CSharp) Method

Decode() private method

Decode a code from the stream using huffman table h. Return the symbol or a negative value if there is an error. If all of the lengths are zero, i.e. an empty code, or if the code is incomplete and an invalid code is received, then -9 is returned after reading MAXBITS bits.

Format notes:

The codes as stored in the compressed data are bit-reversed relative to a simple integer ordering of codes of the same lengths. Hence below the bits are pulled from the compressed data one at a time and used to build the code value reversed from what is in the stream in order to permit simple integer comparisons for decoding. The first code for the shortest length is all ones. Subsequent codes of the same length are simply integer decrements of the previous code. When moving up a length, a one bit is appended to the code. For a complete code, the last code of the longest length will be all zeros. To support this ordering, the bits pulled during decoding are inverted to apply the more "natural" ordering starting with all zeros and incrementing.
private Decode ( HuffmanTable h ) : int
h HuffmanTable
return int
        private int Decode(HuffmanTable h)
        {
            int len = 1;			// current number of bits in code
            int code = 0;		   // len bits being decoded
            int first = 0;		  // first code of length len
            int count;		  // number of codes of length len
            int index = 0;		  // index of first code of length len in symbol table
            int bitbuf;		 // bits from stream
            int left;		   // bits left in next or left to process
            int next = 1;		   // next number of codes

            bitbuf = this._bitBuffer;
            left = this._bitBufferCount;

            while (true)
            {
                while (left-- > 0)
                {
                    code |= (bitbuf & 1) ^ 1;
                    bitbuf >>= 1;
                    count = h.count[next++];
                    if (code < first + count)
                    {
                        this._bitBuffer = bitbuf;
                        this._bitBufferCount = (this._bitBufferCount - len) & 7;

                        return h.symbol[index + (code - first)];
                    }
                    index += count;
                    first += count;
                    first <<= 1;
                    code <<= 1;
                    len++;
                }
                left = (MAX_BITS + 1) - len;

                if (left == 0)
                {
                    break;
                }

                bitbuf = ConsumeByte();
                if (left > 8)
                {
                    left = 8;
                }
            }

            return -9;
        }