int Decode(Huffman *h) { int len; /* current number of Bits in code */ int code; /* len Bits being decoded */ int first; /* first code of length len */ int count; /* number of Codes of length len */ int index; /* 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 */ short *next; /* next number of Codes */ bitbuf = this.bitbuf; left = bitcnt; code = first = index = 0; len = 1; next = h->count + 1; while (true) { while (left-- != 0) { code |= bitbuf & 1; bitbuf >>= 1; count = *next++; if (code < first + count) /* if length len, return symbol */ { this.bitbuf = bitbuf; bitcnt = (bitcnt - len) & 7; return(h->symbol[index + (code - first)]); } index += count; /* else update for next length */ first += count; first <<= 1; code <<= 1; len++; } left = (MAXBITS + 1) - len; if (left == 0) { break; } if (incnt == inlen) { throw new InvalidDataException("Output of input"); //longjmp(env, 1); /* out of input */ } //if (incnt == inlen) throw new Exception("Out of length"); bitbuf = inBuffer[incnt++]; if (incnt == incntToJump) { JumpToNextSourceChunk(); } if (left > 8) { left = 8; } } return(-9); /* ran out of Codes */ }
int Construct(Huffman *h, short *length, int n) { int 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 = stackalloc short[MAXBITS + 1]; /* offsets in symbol table for each length */ /* count number of Codes of each length */ for (len = 0; len <= MAXBITS; len++) { h->count[len] = 0; } for (symbol = 0; symbol < n; symbol++) { (h->count[length[symbol]])++; /* assumes lengths are within bounds */ } if (h->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 <= MAXBITS; len++) { left <<= 1; /* one more bit, double Codes left */ left -= h->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 < MAXBITS; len++) { offs[len + 1] = (short)(offs[len] + h->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) { h->symbol[offs[length[symbol]]++] = (short)symbol; } } /* return zero for complete set, positive for incomplete set */ return(left); }
int Codes(Huffman *lencode, Huffman *distcode) { int symbol; /* decoded symbol */ int len; /* length for copy */ uint dist; /* distance for copy */ /* Decode literals and length/distance pairs */ do { symbol = Decode(lencode); if (symbol < 0) { return(symbol); /* invalid symbol */ } if (symbol < 256) /* literal: symbol is the byte */ /* write out the literal */ { if (outBuffer != NIL) { if (outcnt == outlen) { return(1); } outBuffer[outcnt] = (byte)symbol; } outcnt++; } else if (symbol > 256) /* length */ /* get and compute length */ { symbol -= 257; if (symbol >= 29) { return(-9); /* invalid fixed code */ } len = lens[symbol] + Bits(lext[symbol]); /* get and check distance */ symbol = Decode(distcode); if (symbol < 0) { return(symbol); /* invalid symbol */ } dist = (uint)(dists[symbol] + Bits(dext[symbol])); if (dist > outcnt) { return(-10); /* distance too far back */ } /* copy length bytes from distance bytes back */ if (outBuffer != NIL) { if (outcnt + len > outlen) { return(1); } while (len-- != 0) { outBuffer[outcnt] = outBuffer[outcnt - dist]; outcnt++; } } else { outcnt += (uint)len; } } } while (symbol != 256); /* end of block symbol */ /* done with a valid fixed or dynamic block */ return(0); }