/* File: EXPAND.C - BDS C source code for ZTYPE. Date: July 28, 1990 Author: Copyright 1990 by Carson Wilson, Sysop, Antelope Freeway RAS, 312/764-5162, Chicago. Derived from UNZIP20.ZIP, Copyright 1989 by Samuel H. Smith. */ #include #include /* ----------------------------------------------------------- */ void unReduce() /* expand probabilisticly reduced data */ { int lchar, nchar, ix, z; int follow, bitsneeded; char ExState; char V; char Len; char L_table[5]; char D_shift[5]; char D_mask[5]; char B_table[256]; int op, i, offset; char lop[4], ltemp[4]; int soutcnt; int x, j; int factor; char followers[256][32]; char Slen[256]; L_table[0] = 0; L_table[1] = 127; L_table[2] = 63; L_table[3] = 31; L_table[4] = 15; D_shift[0] = 0; D_shift[1] = 7; D_shift[2] = 6; D_shift[3] = 5; D_shift[4] = 4; D_mask[0] = 0; D_mask[1] = 1; D_mask[2] = 3; D_mask[3] = 7; D_mask[4] = 15; B_table[0] = 8; B_table[1] = B_table[2] = 1; B_table[3] = B_table[4] = 2; setmem(B_table+5,4,3); setmem(B_table+9,8,4); setmem(B_table+17,16,5); setmem(B_table+33,32,6); setmem(B_table+65,64,7); setmem(B_table+129,127,8); factor = lrec.compression_method - 1; ExState = 0; lchar = 0; /* initialize tables */ for (x = 255; x >= 0; x--) { READ6B(Slen[x]); for (j = 0; j < Slen[x]; j++) { READ8B(followers[x][j]); } } while ((long(1,long(2,lres,outpos,outcnt),lrec.uncompressed_size) == -1) && (!zipeof)) { if (Slen[lchar] == 0) READ8B(nchar) else { READ1B(nchar); if (nchar != 0) READ8B(nchar) else { bitsneeded = B_table[Slen[lchar]]; READBIT(bitsneeded,follow); nchar = followers[lchar][follow]; } } /* expand the resulting byte */ switch (ExState) { case 0: if (nchar != DLE) OUTB4(nchar) else ExState = 1; break; case 1: if (nchar != 0) { V = nchar; Len = V & L_table[factor]; if (Len == L_table[factor]) ExState = 2; else ExState = 3; } else { OUTB4(DLE); ExState = 0; } break; case 2: Len += nchar; ExState = 3; break; case 3: i = Len + 3; offset = (((V >> D_shift[factor]) & D_mask[factor]) << 8) + nchar + 1; /* op = (outpos + outcnt) - offset */ long(0,ltemp,offset); /* ltemp = offset */ long(2,lop,outpos,outcnt); /* lop = outpos+outcnt */ long(3,lop,lop,ltemp); /* lop -= ltemp */ if (lop[0] & 0x80) { /* negative? */ /* special case- before start of file */ op = (lop[3] + (lop[2] << 8)); /* op = lop */ /* note: truncation assumes < 32k of nulls */ op |= 0x80; /* add sign */ while ((op < 0) && (i > 0)) { OUTB4(0); op++; i--; } } /* normal copy of data from output buffer */ long(0,ltemp,FOURK); /* ltemp = FOURK */ long(6,lop,lop,ltemp); /* lop %= ltemp */ ix = (lop[3] + (lop[2] << 8)); /* ix = lop */ soutcnt = (outcnt[3] + (outcnt[2] << 8)); /* do a block memory copy if possible */ if ( ((ix+i) < FOURK) && ((soutcnt+i) < FOURK) ) { cpymem(&outbuf[ix],outptr,i); outptr += i; soutcnt += i; long(0,outcnt,soutcnt); } else /* otherwise copy byte by byte */ while (i--) { OUTB4(outbuf[ix++]); if (ix >= FOURK) ix = 0; } ExState = 0; break; } /* store character for next iteration */ lchar = nchar; } }