private int Construct(byte[] rep)
{
short symbol;// current symbol when stepping through length[]
int len;// current length when stepping through h->count[]
int left;// number of possible codes left of current length
short[] offs = new short[MAX_BITS + 1]; // offsets in symbol table for each length
short[] length = new short[256]; // code lengths
int n;
// convert compact repeat counts into symbol bit length list
symbol = 0;
for (int ri = 0; ri < rep.Length; ri++)
{
len = rep[ri];
left = (len >> 4) + 1;
len &= 0xf;
do
{
length[symbol++] = (short)len;
} while (--left > 0);
}
// count number of codes of each length
n = symbol;
for (len = 0; len <= MAX_BITS; len++)
{
this.count[len] = 0;
}
for (symbol = 0; symbol < n; symbol++)
{
(this.count[length[symbol]])++;// assumes lengths are within bounds
}
if (this.count[0] == n)// no codes!
{
return 0; // complete, but decode() will fail
}
// check for an over-subscribed or incomplete set of lengths
left = 1; // one possible code of zero length
for (len = 1; len <= MAX_BITS; len++)
{
left <<= 1; // one more bit, double codes left
left -= this.count[len]; // deduct count from possible codes
if (left < 0)
{
return left; // over-subscribed--return negative
}
} // left > 0 means incomplete
// generate offsets into symbol table for each length for sorting
offs[1] = 0;
for (len = 1; len < MAX_BITS; len++)
{
offs[len + 1] = (short)(offs[len] + this.count[len]);
}
//
// put symbols in table sorted by length, by symbol order within each
// length
//
for (symbol = 0; symbol < n; symbol++)
{
if (length[symbol] != 0)
{
this.symbol[offs[length[symbol]]++] = symbol;
}
}
// return zero for complete set, positive for incomplete set
return left;
}