11 DBigLenCode = 0x3c, /* minimum code for large lenth encoding */
13 DBigLenBase = 1 /* starting items to encode for big lens */
16 static uchar lenval[1 << (DBigLenBits - 1)] =
18 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19 3, 3, 3, 3, 3, 3, 3, 3,
27 static uchar lenbits[] =
33 static uchar offbits[16] =
35 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 12, 13
38 static ushort offbase[16] =
52 unthwackinit(Unthwack *ut)
56 memset(ut, 0, sizeof *ut);
57 for(i = 0; i < DWinBlocks; i++)
58 ut->blocks[i].data = ut->data[i];
62 unthwackstate(Unthwack *ut, uchar *mask)
76 if(ut->blocks[slot].maxoff == 0)
78 bseq = ut->blocks[slot].seq;
81 else if(seq - bseq > MaxSeqMask)
84 m |= 1 << (seq - bseq - 1);
91 * insert this block in it's correct sequence number order.
92 * replace the oldest block, which is always pointed to by ut->slot.
93 * the encoder doesn't use a history at wraparound,
94 * so don't worry about that case.
97 unthwackinsert(Unthwack *ut, int len, ulong seq)
107 if(ut->blocks[slot].seq <= seq || ut->blocks[slot].maxoff == 0)
109 d = ut->blocks[tslot].data;
110 ut->blocks[tslot] = ut->blocks[slot];
111 ut->blocks[slot].data = d;
114 ut->blocks[tslot].seq = seq;
115 ut->blocks[tslot].maxoff = len;
118 if(ut->slot >= DWinBlocks)
121 ut->blocks[ut->slot].seq = ~0UL;
122 ut->blocks[ut->slot].maxoff = 0;
128 unthwackadd(Unthwack *ut, uchar *src, int nsrc, ulong seq)
132 if(nsrc > ThwMaxBlock)
135 tslot = unthwackinsert(ut, nsrc, seq);
139 memmove(ut->blocks[tslot].data, src, nsrc);
145 unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
147 UnthwBlock blocks[CompBlocks], *b, *eblocks;
148 uchar *s, *d, *dmax, *smax, lit;
149 ulong cmask, cseq, bseq, utbits;
150 int i, off, len, bits, slot, use, code, utnbits, overbits, lithist;
152 if(nsrc < 4 || nsrc > ThwMaxBlock){
153 snprint(ut->err, ThwErrLen, "block too small or large");
159 *b = ut->blocks[slot];
164 * set up the history blocks
169 while(cseq != seq && b < blocks + CompBlocks){
175 bseq = ut->blocks[slot].seq;
177 *b = ut->blocks[slot];
192 snprint(ut->err, ThwErrLen, "blocks dropped: seq=%ld cseq=%ld %d cmask=%#lx %#x\n", seq, cseq, src[0], cmask, src[1]);
202 while(src < smax || utnbits - overbits >= MinDecode){
203 while(utnbits <= 24){
215 len = lenval[(utbits >> (utnbits - 5)) & 0x1f];
219 lit = (utbits >> utnbits) & 0xff;
223 lit = (utbits >> utnbits) & 0x7f;
227 lit = (lit << 2) | ((utbits >> utnbits) & 3);
230 lit = (lit << 3) | ((utbits >> utnbits) & 7);
232 lit = (lit - 64) & 0xff;
236 snprint(ut->err, ThwErrLen, "too much output");
240 lithist = (lithist << 1) | (lit < 32) | (lit > 127);
249 utnbits -= lenbits[len];
251 utnbits -= DBigLenBits;
252 code = ((utbits >> utnbits) & ((1 << DBigLenBits) - 1)) - DBigLenCode;
255 bits = (DBigLenBits & 1) ^ 1;
262 snprint(ut->err, ThwErrLen, "len out of range");
265 code |= (utbits >> utnbits) & 1;
271 while(utnbits <= 24){
285 bits = (utbits >> utnbits) & 0xf;
287 bits = offbits[bits];
290 off |= (utbits >> utnbits) & ((1 << bits) - 1);
294 while(off > b->maxoff){
298 snprint(ut->err, ThwErrLen, "offset out of range");
303 || b != blocks && len > off){
304 snprint(ut->err, ThwErrLen, "len out of range");
307 s = b->data + b->maxoff - off;
308 blocks->maxoff += len;
310 for(i = 0; i < len; i++)
314 if(utnbits < overbits){
315 snprint(ut->err, ThwErrLen, "compressed data overrun");
319 len = d - blocks->data;
320 memmove(dst, blocks->data, len);
322 unthwackinsert(ut, len, seq);