## diffname port/unthwack.c 1999/1001 ## diff -e /dev/null /n/emeliedump/1999/1001/sys/src/brazil/port/unthwack.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "thwack.h" typedef struct HuffDec HuffDec; struct HuffDec { ulong maxcode[MaxLen]; ulong last[MaxLen]; ulong decode[MaxLen]; }; static HuffDec lentab = { /* 0 1 2 3 4 5 6 */ {0, 0, 0x2, 0, 0xe, 0x1e, 0x3f}, {-1, 0+0, 0x2+1, -1, 0xe+2, 0x1e+5, 0x3f+6}, { 0, 1, 7, 3, 2, 4, 6, 5 }, }; static ulong bitget(Unthwack *ut, int nb); static ulong iomegaget(Unthwack *ut); void unthwackinit(Unthwack *ut) { int i; memset(ut, 0, sizeof *ut); for(i = 0; i < EWinBlocks; i++) ut->blocks[i].data = ut->data[i]; } /* * to speed up, inline bitget */ int unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) { UnthwBlock blocks[CompBlocks], *b, *eblocks; uchar *s, *es, *d, *dmax; ulong cmask, cseq, bseq, utbits, utnbits; int off, len, bits, slot, tslot; if(nsrc < 4 || nsrc > ThwMaxBlock || waserror()) return -1; ut->src = src + 2; ut->smax = src + nsrc; /* * find the correct slot for this block, * the oldest block around. the encoder * doesn't use a history at wraparound, * so don't worry about that case. */ tslot = ut->slot; for(;;){ slot = tslot - 1; if(slot < 0) slot += DWinBlocks; if(ut->blocks[slot].seq <= seq) break; ut->blocks[slot] = ut->blocks[slot]; tslot = slot; } b = blocks; ut->blocks[tslot].seq = seq; ut->blocks[tslot].maxoff = 0; *b = ut->blocks[tslot]; d = b->data; dmax = d + ndst; /* * set up the history blocks */ cseq = seq - src[0]; cmask = src[1]; b++; slot = tslot; while(cseq != seq && b < blocks + CompBlocks){ slot--; if(slot < 0) slot += DWinBlocks; if(slot == ut->slot) break; bseq = ut->blocks[slot].seq; if(bseq == cseq){ *b = ut->blocks[slot]; b++; if(cmask == 0){ cseq = seq; break; } do{ bits = cmask & 1; cseq--; cmask >>= 1; }while(!bits); } } eblocks = b; if(cseq != seq){ print("blocks not in decompression window: cseq=%d seq=%d cmask=%ux nb=%d\n", cseq, seq, cmask, eblocks - blocks); error("unthwack bad window"); } utnbits = 0; utbits = 0; while(ut->src < ut->smax || ut->nbits >= MinDecode){ while(utnbits < 9){ if(ut->src >= ut->smax) error("unthwack eof"); utbits <<= 8; utbits |= *ut->src++; utnbits += 8; } utnbits -= 9; off = (utbits >> utnbits) & ((1 << 9) - 1); bits = off >> 5; if(bits >= MaxOff){ *d++ = off; blocks->maxoff++; continue; } off &= (1 << 5) - 1; if(bits){ bits--; off |= 1 << 5; } bits += OffBase - 5; off <<= bits; while(utnbits < bits){ if(ut->src >= ut->smax) error("unthwack eof"); utbits <<= 8; utbits |= *ut->src++; utnbits += 8; } utnbits -= bits; off |= (utbits >> utnbits) & ((1 << bits) - 1); off++; len = 0; bits = 0; do{ len <<= 1; if(utnbits < 1){ if(ut->src >= ut->smax) error("unthwack eof"); utbits <<= 8; utbits |= *ut->src++; utnbits += 8; } utnbits--; len |= (utbits >> utnbits) & 1; bits++; }while(len > lentab.maxcode[bits]); len = lentab.decode[lentab.last[bits] - len]; if(len == MaxLen - 1){ ut->nbits = utnbits; ut->bits = utbits; len += iomegaget(ut) - 1; utnbits = ut->nbits; utbits = ut->bits; } len += MinMatch; b = blocks; while(off > b->maxoff){ off -= b->maxoff; b++; if(b >= eblocks) error("unthwack offset"); } if(d + len > dmax || b != blocks && len > off) error("unthwack len"); s = b->data + b->maxoff - off; es = s + len; while(s < es) *d++ = *s++; blocks->maxoff += len; } len = d - blocks->data; memmove(dst, blocks->data, len); ut->blocks[tslot].maxoff = len; ut->slot++; if(ut->slot >= DWinBlocks) ut->slot = 0; poperror(); return len; } /* * elias's omega code, modified * for at least 3 bit transmission */ static ulong iomegaget(Unthwack *ut) { ulong v; int b; v = bitget(ut, 3); if((v & 0x4) == 0) return v + 1; for(;;){ b = bitget(ut, 1); if(b == 0) return v + 1; if(v > 16) break; v--; v = (b << v) | bitget(ut, v); } error("unthwack iomegaget"); return ~0; } static ulong bitget(Unthwack *ut, int nb) { int c; while(ut->nbits < nb){ if(ut->src >= ut->smax) error("unthwack eof"); c = *ut->src++; ut->bits <<= 8; ut->bits |= c; ut->nbits += 8; } ut->nbits -= nb; return (ut->bits >> ut->nbits) & ((1 << nb) - 1); } . ## diffname port/unthwack.c 1999/1007 ## diff -e /n/emeliedump/1999/1001/sys/src/brazil/port/unthwack.c /n/emeliedump/1999/1007/sys/src/brazil/port/unthwack.c 210,252d 208d 198a if(utnbits < overbits) return -1; . 192c return -1; . 188c return -1; . 180a . 174,179c code = len - BigLenCode; len = MaxFastLen; bits = 8; use = BigLenBase; while(code >= use){ len += use; code -= use; code <<= 1; utnbits--; code |= (utbits >> utnbits) & 1; use <<= bits & 1; bits++; } len += code; . 168,172d 165c if(src < smax) utbits |= *src++; else overbits += 8; . 160,163c bits++; len = utbits >> (utnbits - bits); }while(bits < BigLenBits && len > lentab.maxcode[bits]); utnbits -= bits; if(bits < BigLenBits) len = lentab.decode[lentab.last[bits] - len]; else{ while(utnbits < MaxLenDecode){ . 158a utbits &= (1 << utnbits) - 1; . 157d 146,152d 131a /* * literal */ . 126c if(src < smax) utbits |= *src++; else overbits += 8; . 121,124c overbits = 0; while(src < smax || utnbits - overbits >= MinDecode){ while(utnbits < MaxOffDecode + BigLenBits){ . 118a smax = src + nsrc; src += 2; . 115,116c print("blocks not in decompression window: cseq=%ld seq=%ld cmask=%lux nb=%ld\n", cseq, seq, cmask, eblocks - blocks); return -1; . 59,61d 56c if(nsrc < 4 || nsrc > ThwMaxBlock) . 52,54c uchar *s, *es, *d, *dmax, *smax; ulong cmask, cseq, bseq, utbits; int off, len, bits, slot, tslot, use, code, utnbits, overbits; . 45,47d 32,34d 28c 6, 5, 8, 7, . 26c 3, 2, . 20,22c /* 0 1 2 3 4 5 6 7 */ {0, 0, 0x2, 0, 0xd, 0x1c, 0x3b, 0x79}, {-1, 0+0, 0x2+1, -1, 0xd+2, 0x1c+4, 0x3b+5, 0x79+7}, . 13,15c ulong maxcode[MaxFastLen]; ulong last[MaxFastLen]; ulong decode[MaxFastLen]; . 2c #include "lib.h" . ## diffname port/unthwack.c 1999/1022 ## diff -e /n/emeliedump/1999/1007/sys/src/brazil/port/unthwack.c /n/emeliedump/1999/1022/sys/src/brazil/port/unthwack.c 142,144d 139,140c bits += OffBase - 1; off = 1 << bits; }else{ bits = OffBase; off = 0; . 137c /* * match; next 3 bits decode offset range */ utnbits -= 4; bits = (utbits >> utnbits) & ((1 << 3) - 1); . 131,133c if(((utbits >> (utnbits - 1)) & 1) == 0){ if(lithist & 0xf){ utnbits -= 9; lit = (utbits >> utnbits) & 0xff; lit &= 255; }else{ utnbits -= 8; lit = (utbits >> utnbits) & 0x7f; if(lit < 32){ if(lit < 24){ utnbits -= 2; lit = (lit << 2) | ((utbits >> utnbits) & 3); }else{ utnbits -= 3; lit = (lit << 3) | ((utbits >> utnbits) & 7); } lit = (lit - 64) & 0xff; } } *d++ = lit; lithist = (lithist << 1) | lit < 32 | lit > 127; . 125,126d 117c while(utnbits <= 24){ . 115a lithist = ~0; . 47,48c uchar *s, *es, *d, *dmax, *smax, lit; ulong cmask, cseq, bseq, utbits, lithist; . 2c #include "../port/lib.h" . ## diffname port/unthwack.c 1999/1111 ## diff -e /n/emeliedump/1999/1022/sys/src/brazil/port/unthwack.c /n/emeliedump/1999/1111/sys/src/9/port/unthwack.c 223a for(i = 0; i < len; i++) d[i] = s[i]; d += len; . 220,222d 208a utnbits -= bits; off |= (utbits >> utnbits) & ((1 << bits) - 1); off++; . 207c /* * offset */ utnbits -= 4; bits = (utbits >> utnbits) & 0xf; off = offbase[bits]; bits = offbits[bits]; . 204a while(utnbits <= 24){ utbits <<= 8; if(src < smax) utbits |= *src++; else overbits += 8; utnbits += 8; } . 201,202c use <<= bits; bits ^= 1; . 182,194c utnbits -= DBigLenBits; code = ((utbits >> utnbits) & ((1 << DBigLenBits) - 1)) - DBigLenCode; len = DMaxFastLen; use = DBigLenBase; bits = (DBigLenBits & 1) ^ 1; . 158,180c if(len < 255) utnbits -= lenbits[len]; . 156c * length . 130c len = lenval[(utbits >> (utnbits - 5)) & 0x1f]; if(len == 0){ . 107c print("blocks not in decompression window: cseq=%ld seq=%ld cmask=%lx nb=%ld\n", cseq, seq, cmask, eblocks - blocks); . 67c ut->blocks[slot] = ut->blocks[tslot]; . 55,57c * insert this block in it's correct sequence number order. * replace the oldest block, which is always pointed to by ut->slot. * the encoder doesn't use a history at wraparound, . 49c int i, off, len, bits, slot, tslot, use, code, utnbits, overbits; . 47c uchar *s, *d, *dmax, *smax, lit; . 43a unthwackadd(Unthwack *ut, uchar *src, int nsrc, ulong seq) { int slot, tslot; if(nsrc > ThwMaxBlock) return -1; #ifndef NOUNCOMP tslot = ut->slot; for(;;){ slot = tslot - 1; if(slot < 0) slot += DWinBlocks; if(ut->blocks[slot].seq <= seq) break; ut->blocks[slot] = ut->blocks[tslot]; tslot = slot; } ut->blocks[tslot].seq = seq; ut->blocks[tslot].maxoff = nsrc; memmove(ut->blocks[tslot].data, src, nsrc); ut->slot++; if(ut->slot >= DWinBlocks) ut->slot = 0; #endif return nsrc; } int . 39c for(i = 0; i < DWinBlocks; i++) . 32a static uchar lenbits[] = { 0, 0, 0, 2, 3, 5, 5, }; static uchar offbits[16] = { 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 12, 13 }; static ushort offbase[16] = { 0, 0x20, 0x40, 0x60, 0x80, 0xc0, 0x100, 0x180, 0x200, 0x300, 0x400, 0x600, 0x800, 0xc00, 0x1000, 0x2000 }; . 20,30c 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 6, 255, 255 . 18c static uchar lenval[1 << (DBigLenBits - 1)] = . 13,15c DMaxFastLen = 7, DBigLenCode = 0x3c, /* minimum code for large lenth encoding */ DBigLenBits = 6, DBigLenBase = 1 /* starting items to encode for big lens */ . 11c enum . 9c /* * don't include compressed blocks */ #define NOUNCOMP . 2c #include "lib.h" . ## diffname port/unthwack.c 1999/1116 ## diff -e /n/emeliedump/1999/1111/sys/src/9/port/unthwack.c /n/emeliedump/1999/1116/sys/src/9/port/unthwack.c 121c d = ut->blocks[tslot].data; ut->blocks[tslot] = ut->blocks[slot]; ut->blocks[slot].data = d; . 68,97d 9,13d ## diffname port/unthwack.c 2000/0912 ## diff -e /n/emeliedump/1999/1116/sys/src/9/port/unthwack.c /n/emeliedump/2000/0912/sys/src/9/port/unthwack.c 192a if(utnbits < 0) return -1; . 172c lithist = (lithist << 1) | (lit < 32) | (lit > 127); . ## diffname port/unthwack.c 2001/0116 ## diff -e /n/emeliedump/2000/0912/sys/src/9/port/unthwack.c /n/emeliedump/2001/0116/sys/src/9/port/unthwack.c 170a if(d >= dmax) return -1; . ## diffname port/unthwack.c 2001/0214 ## diff -e /n/emeliedump/2001/0116/sys/src/9/port/unthwack.c /n/emeliedump/2001/0214/sys/src/9/port/unthwack.c 249,251c unthwackinsert(ut, len, seq); . 247d 128,129c print("blocks dropped: seq=%ld cseq=%ld %d cmask=%#lx %#x\n", seq, cseq, src[0], cmask, src[1]); return -2; . 104d 93,94c ut->blocks[tslot].maxoff = len; ut->slot++; if(ut->slot >= DWinBlocks) ut->slot = 0; ut->blocks[ut->slot].seq = ~0UL; ut->blocks[ut->slot].maxoff = 0; return tslot; } int unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) { UnthwBlock blocks[CompBlocks], *b, *eblocks; uchar *s, *d, *dmax, *smax, lit; ulong cmask, cseq, bseq, utbits; int i, off, len, bits, slot, use, code, utnbits, overbits, lithist; if(nsrc < 4 || nsrc > ThwMaxBlock) return -1; slot = ut->slot; b = blocks; *b = ut->blocks[slot]; . 91d 84c if(ut->blocks[slot].seq <= seq || ut->blocks[slot].maxoff == 0) . 73,78c /* * insert this block in it's correct sequence number order. * replace the oldest block, which is always pointed to by ut->slot. * the encoder doesn't use a history at wraparound, * so don't worry about that case. */ static int unthwackinsert(Unthwack *ut, int len, ulong seq) { uchar *d; int slot, tslot; . 70,71c seq = ~0UL; m = 0; slot = ut->slot; for(;;){ slot--; if(slot < 0) slot += DWinBlocks; if(slot == ut->slot) break; if(ut->blocks[slot].maxoff == 0) continue; bseq = ut->blocks[slot].seq; if(seq == ~0UL) seq = bseq; else if(seq - bseq > MaxSeqMask) break; else m |= 1 << (seq - bseq - 1); } *mask = m; return seq; } . 65,68c ulong bseq, seq; int slot, m; . 62,63c ulong unthwackstate(Unthwack *ut, uchar *mask) . ## diffname port/unthwack.c 2001/0527 ## diff -e /n/emeliedump/2001/0214/sys/src/9/port/unthwack.c /n/emeliedump/2001/0527/sys/src/9/port/unthwack.c 294c ut->slot++; if(ut->slot >= DWinBlocks) ut->slot = 0; . 292a ut->blocks[tslot].maxoff = len; . 217,218d 174,175c print("blocks not in decompression window: cseq=%ld seq=%ld cmask=%lx nb=%ld\n", cseq, seq, cmask, eblocks - blocks); return -1; . 150a slot = tslot; . 141c ut->blocks[tslot].seq = seq; ut->blocks[tslot].maxoff = 0; *b = ut->blocks[tslot]; . 115,139d 108c if(ut->blocks[slot].seq <= seq) . 91,102c /* * insert this block in it's correct sequence number order. * replace the oldest block, which is always pointed to by ut->slot. * the encoder doesn't use a history at wraparound, * so don't worry about that case. */ . 68,89c if(nsrc < 4 || nsrc > ThwMaxBlock) return -1; . 65,66c UnthwBlock blocks[CompBlocks], *b, *eblocks; uchar *s, *d, *dmax, *smax, lit; ulong cmask, cseq, bseq, utbits, lithist; int i, off, len, bits, slot, tslot, use, code, utnbits, overbits; . 62,63c int unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) . ## diffname port/unthwack.c 2001/0609 ## diff -e /n/emeliedump/2001/0527/sys/src/9/port/unthwack.c /n/emeliedump/2001/0609/sys/src/9/port/unthwack.c 247,249c unthwackinsert(ut, len, seq); . 245d 170a if(d >= dmax) return -1; . 128,129c print("blocks dropped: seq=%ld cseq=%ld %d cmask=%#lx %#x\n", seq, cseq, src[0], cmask, src[1]); return -2; . 104d 93,94c ut->blocks[tslot].maxoff = len; ut->slot++; if(ut->slot >= DWinBlocks) ut->slot = 0; ut->blocks[ut->slot].seq = ~0UL; ut->blocks[ut->slot].maxoff = 0; return tslot; } int unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) { UnthwBlock blocks[CompBlocks], *b, *eblocks; uchar *s, *d, *dmax, *smax, lit; ulong cmask, cseq, bseq, utbits; int i, off, len, bits, slot, use, code, utnbits, overbits, lithist; if(nsrc < 4 || nsrc > ThwMaxBlock) return -1; slot = ut->slot; b = blocks; *b = ut->blocks[slot]; . 91d 84c if(ut->blocks[slot].seq <= seq || ut->blocks[slot].maxoff == 0) . 73,78c /* * insert this block in it's correct sequence number order. * replace the oldest block, which is always pointed to by ut->slot. * the encoder doesn't use a history at wraparound, * so don't worry about that case. */ static int unthwackinsert(Unthwack *ut, int len, ulong seq) { uchar *d; int slot, tslot; . 70,71c seq = ~0UL; m = 0; slot = ut->slot; for(;;){ slot--; if(slot < 0) slot += DWinBlocks; if(slot == ut->slot) break; if(ut->blocks[slot].maxoff == 0) continue; bseq = ut->blocks[slot].seq; if(seq == ~0UL) seq = bseq; else if(seq - bseq > MaxSeqMask) break; else m |= 1 << (seq - bseq - 1); } *mask = m; return seq; } . 65,68c ulong bseq, seq; int slot, m; . 62,63c ulong unthwackstate(Unthwack *ut, uchar *mask) .