12 DBigLenCode = 0x3c, /* minimum code for large lenth encoding */
14 DBigLenBase = 1 /* starting items to encode for big lens */
17 static uchar lenval[1 << (DBigLenBits - 1)] =
19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20 3, 3, 3, 3, 3, 3, 3, 3,
28 static uchar lenbits[] =
34 static uchar offbits[16] =
36 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 12, 13
39 static ushort offbase[16] =
53 unthwackinit(Unthwack *ut)
57 memset(ut, 0, sizeof *ut);
58 for(i = 0; i < DWinBlocks; i++)
59 ut->blocks[i].data = ut->data[i];
63 unthwackstate(Unthwack *ut, uchar *mask)
77 if(ut->blocks[slot].maxoff == 0)
79 bseq = ut->blocks[slot].seq;
82 else if(seq - bseq > MaxSeqMask)
85 m |= 1 << (seq - bseq - 1);
92 * insert this block in it's correct sequence number order.
93 * replace the oldest block, which is always pointed to by ut->slot.
94 * the encoder doesn't use a history at wraparound,
95 * so don't worry about that case.
98 unthwackinsert(Unthwack *ut, int len, ulong seq)
108 if(ut->blocks[slot].seq <= seq || ut->blocks[slot].maxoff == 0)
110 d = ut->blocks[tslot].data;
111 ut->blocks[tslot] = ut->blocks[slot];
112 ut->blocks[slot].data = d;
115 ut->blocks[tslot].seq = seq;
116 ut->blocks[tslot].maxoff = len;
119 if(ut->slot >= DWinBlocks)
122 ut->blocks[ut->slot].seq = ~0UL;
123 ut->blocks[ut->slot].maxoff = 0;
129 unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
131 UnthwBlock blocks[CompBlocks], *b, *eblocks;
132 uchar *s, *d, *dmax, *smax, lit;
133 ulong cmask, cseq, bseq, utbits;
134 int i, off, len, bits, slot, use, code, utnbits, overbits, lithist;
136 if(nsrc < 4 || nsrc > ThwMaxBlock)
141 *b = ut->blocks[slot];
146 * set up the history blocks
151 while(cseq != seq && b < blocks + CompBlocks){
157 bseq = ut->blocks[slot].seq;
159 *b = ut->blocks[slot];
174 print("unthwack: blocks dropped: seq=%ld cseq=%ld %d cmask=%#lx %#x\n",
175 seq, cseq, src[0], cmask, src[1]);
185 while(src < smax || utnbits - overbits >= MinDecode){
186 while(utnbits <= 24){
198 len = lenval[(utbits >> (utnbits - 5)) & 0x1f];
202 lit = (utbits >> utnbits) & 0xff;
206 lit = (utbits >> utnbits) & 0x7f;
210 lit = (lit << 2) | ((utbits >> utnbits) & 3);
213 lit = (lit << 3) | ((utbits >> utnbits) & 7);
215 lit = (lit - 64) & 0xff;
221 lithist = (lithist << 1) | (lit < 32) | (lit > 127);
230 utnbits -= lenbits[len];
232 utnbits -= DBigLenBits;
233 code = ((utbits >> utnbits) & ((1 << DBigLenBits) - 1)) - DBigLenCode;
236 bits = (DBigLenBits & 1) ^ 1;
244 code |= (utbits >> utnbits) & 1;
250 while(utnbits <= 24){
264 bits = (utbits >> utnbits) & 0xf;
266 bits = offbits[bits];
269 off |= (utbits >> utnbits) & ((1 << bits) - 1);
273 while(off > b->maxoff){
280 || b != blocks && len > off)
282 s = b->data + b->maxoff - off;
283 blocks->maxoff += len;
285 for(i = 0; i < len; i++)
289 if(utnbits < overbits)
292 len = d - blocks->data;
293 memmove(dst, blocks->data, len);
295 unthwackinsert(ut, len, seq);