|
|
1.1 ! root 1: /* unlzw.c -- decompress files in LZW format. ! 2: * The code in this file is directly derived from the public domain 'compress' ! 3: * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, ! 4: * Ken Turkowski, Dave Mack and Peter Jannesen. ! 5: * ! 6: * This is a temporary version which will be rewritten in some future version ! 7: * to accomodate in-memory decompression. ! 8: */ ! 9: ! 10: #ifndef lint ! 11: static char rcsid[] = "$Id: unlzw.c,v 0.11 1993/02/24 18:23:13 jloup Exp $"; ! 12: #endif ! 13: ! 14: #include "tailor.h" ! 15: #include "gzip.h" ! 16: #include "lzw.h" ! 17: ! 18: #include <stdio.h> ! 19: ! 20: #ifdef HAVE_UNISTD_H ! 21: # include <sys/types.h> ! 22: # include <unistd.h> ! 23: #endif ! 24: ! 25: typedef unsigned char char_type; ! 26: typedef long code_int; ! 27: typedef unsigned long count_int; ! 28: typedef unsigned short count_short; ! 29: typedef unsigned long cmp_code_int; ! 30: ! 31: #define MAXCODE(n) (1L << (n)) ! 32: ! 33: #ifndef REGISTERS ! 34: # define REGISTERS 2 ! 35: #endif ! 36: #define REG1 ! 37: #define REG2 ! 38: #define REG3 ! 39: #define REG4 ! 40: #define REG5 ! 41: #define REG6 ! 42: #define REG7 ! 43: #define REG8 ! 44: #define REG9 ! 45: #define REG10 ! 46: #define REG11 ! 47: #define REG12 ! 48: #define REG13 ! 49: #define REG14 ! 50: #define REG15 ! 51: #define REG16 ! 52: #if REGISTERS >= 1 ! 53: # undef REG1 ! 54: # define REG1 register ! 55: #endif ! 56: #if REGISTERS >= 2 ! 57: # undef REG2 ! 58: # define REG2 register ! 59: #endif ! 60: #if REGISTERS >= 3 ! 61: # undef REG3 ! 62: # define REG3 register ! 63: #endif ! 64: #if REGISTERS >= 4 ! 65: # undef REG4 ! 66: # define REG4 register ! 67: #endif ! 68: #if REGISTERS >= 5 ! 69: # undef REG5 ! 70: # define REG5 register ! 71: #endif ! 72: #if REGISTERS >= 6 ! 73: # undef REG6 ! 74: # define REG6 register ! 75: #endif ! 76: #if REGISTERS >= 7 ! 77: # undef REG7 ! 78: # define REG7 register ! 79: #endif ! 80: #if REGISTERS >= 8 ! 81: # undef REG8 ! 82: # define REG8 register ! 83: #endif ! 84: #if REGISTERS >= 9 ! 85: # undef REG9 ! 86: # define REG9 register ! 87: #endif ! 88: #if REGISTERS >= 10 ! 89: # undef REG10 ! 90: # define REG10 register ! 91: #endif ! 92: #if REGISTERS >= 11 ! 93: # undef REG11 ! 94: # define REG11 register ! 95: #endif ! 96: #if REGISTERS >= 12 ! 97: # undef REG12 ! 98: # define REG12 register ! 99: #endif ! 100: #if REGISTERS >= 13 ! 101: # undef REG13 ! 102: # define REG13 register ! 103: #endif ! 104: #if REGISTERS >= 14 ! 105: # undef REG14 ! 106: # define REG14 register ! 107: #endif ! 108: #if REGISTERS >= 15 ! 109: # undef REG15 ! 110: # define REG15 register ! 111: #endif ! 112: #if REGISTERS >= 16 ! 113: # undef REG16 ! 114: # define REG16 register ! 115: #endif ! 116: ! 117: #ifndef BYTEORDER ! 118: # define BYTEORDER 0000 ! 119: #endif ! 120: ! 121: #ifndef NOALLIGN ! 122: # define NOALLIGN 0 ! 123: #endif ! 124: ! 125: ! 126: union bytes { ! 127: long word; ! 128: struct { ! 129: #if BYTEORDER == 4321 ! 130: char_type b1; ! 131: char_type b2; ! 132: char_type b3; ! 133: char_type b4; ! 134: #else ! 135: #if BYTEORDER == 1234 ! 136: char_type b4; ! 137: char_type b3; ! 138: char_type b2; ! 139: char_type b1; ! 140: #else ! 141: # undef BYTEORDER ! 142: int dummy; ! 143: #endif ! 144: #endif ! 145: } bytes; ! 146: }; ! 147: ! 148: #if BYTEORDER == 4321 && NOALLIGN == 1 ! 149: # define input(b,o,c,n,m){ \ ! 150: (c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \ ! 151: (o) += (n); \ ! 152: } ! 153: #else ! 154: # define input(b,o,c,n,m){ \ ! 155: REG1 char_type *p = &(b)[(o)>>3]; \ ! 156: (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \ ! 157: ((long)(p[2])<<16))>>((o)&0x7))&(m); \ ! 158: (o) += (n); \ ! 159: } ! 160: #endif ! 161: ! 162: #ifndef MAXSEG_64K ! 163: /* DECLARE(ush, tab_prefix, (1<<BITS)); -- prefix code */ ! 164: # define tab_prefixof(i) tab_prefix[i] ! 165: # define clear_tab_prefixof() memzero(tab_prefix, 256); ! 166: #else ! 167: /* DECLARE(ush, tab_prefix0, (1<<(BITS-1)); -- prefix for even codes */ ! 168: /* DECLARE(ush, tab_prefix1, (1<<(BITS-1)); -- prefix for odd codes */ ! 169: ush *tab_prefix[2]; ! 170: # define tab_prefixof(i) tab_prefix[(i)&1][(i)>>1] ! 171: # define clear_tab_prefixof() \ ! 172: memzero(tab_prefix0, 128), \ ! 173: memzero(tab_prefix1, 128); ! 174: #endif ! 175: #define de_stack ((char_type *)(&d_buf[DIST_BUFSIZE-1])) ! 176: #define tab_suffixof(i) tab_suffix[i] ! 177: ! 178: int block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 */ ! 179: ! 180: /* ============================================================================ ! 181: * Decompress in to out. This routine adapts to the codes in the ! 182: * file building the "string" table on-the-fly; requiring no table to ! 183: * be stored in the compressed file. ! 184: * IN assertions: the buffer inbuf contains already the beginning of ! 185: * the compressed data, from offsets iptr to insize-1 included. ! 186: * The magic header has already been checked and skipped. ! 187: * bytes_in and bytes_out have been initialized. ! 188: */ ! 189: void unlzw(in, out) ! 190: int in, out; /* input and output file descriptors */ ! 191: { ! 192: REG2 char_type *stackp; ! 193: REG3 code_int code; ! 194: REG4 int finchar; ! 195: REG5 code_int oldcode; ! 196: REG6 code_int incode; ! 197: REG7 long inbits; ! 198: REG8 long posbits; ! 199: REG9 int outpos; ! 200: /* REG10 int insize; (global) */ ! 201: REG11 unsigned bitmask; ! 202: REG12 code_int free_ent; ! 203: REG13 code_int maxcode; ! 204: REG14 code_int maxmaxcode; ! 205: REG15 int n_bits; ! 206: REG16 int rsize; ! 207: ! 208: #ifdef MAXSEG_64K ! 209: tab_prefix[0] = tab_prefix0; ! 210: tab_prefix[1] = tab_prefix1; ! 211: #endif ! 212: maxbits = get_byte(); ! 213: block_mode = maxbits & BLOCK_MODE; ! 214: if ((maxbits & LZW_RESERVED) != 0) { ! 215: WARN((stderr, "%s: warning, unknown flags 0x%x\n", ! 216: ifname, maxbits & LZW_RESERVED)); ! 217: } ! 218: maxbits &= BIT_MASK; ! 219: maxmaxcode = MAXCODE(maxbits); ! 220: ! 221: if (maxbits > BITS) { ! 222: fprintf(stderr, ! 223: "%s: compressed with %d bits, can only handle %d bits\n", ! 224: ifname, maxbits, BITS); ! 225: exit_code = ERROR; ! 226: return; ! 227: } ! 228: rsize = insize; ! 229: maxcode = MAXCODE(n_bits = INIT_BITS)-1; ! 230: bitmask = (1<<n_bits)-1; ! 231: oldcode = -1; ! 232: finchar = 0; ! 233: outpos = 0; ! 234: posbits = inptr<<3; ! 235: ! 236: free_ent = ((block_mode) ? FIRST : 256); ! 237: ! 238: clear_tab_prefixof(); /* Initialize the first 256 entries in the table. */ ! 239: ! 240: for (code = 255 ; code >= 0 ; --code) { ! 241: tab_suffixof(code) = (char_type)code; ! 242: } ! 243: do { ! 244: REG1 int i; ! 245: int e; ! 246: int o; ! 247: ! 248: resetbuf: ! 249: e = insize-(o = (posbits>>3)); ! 250: ! 251: for (i = 0 ; i < e ; ++i) { ! 252: inbuf[i] = inbuf[i+o]; ! 253: } ! 254: insize = e; ! 255: posbits = 0; ! 256: ! 257: if (insize < INBUF_EXTRA) { ! 258: if ((rsize = read(in, inbuf+insize, INBUFSIZ)) == EOF) { ! 259: read_error(); ! 260: } ! 261: insize += rsize; ! 262: } ! 263: inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 : ! 264: ((long)insize<<3)-(n_bits-1)); ! 265: ! 266: while (inbits > posbits) { ! 267: if (free_ent > maxcode) { ! 268: posbits = ((posbits-1) + ! 269: ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3))); ! 270: ++n_bits; ! 271: if (n_bits == maxbits) { ! 272: maxcode = maxmaxcode; ! 273: } else { ! 274: maxcode = MAXCODE(n_bits)-1; ! 275: } ! 276: bitmask = (1<<n_bits)-1; ! 277: goto resetbuf; ! 278: } ! 279: input(inbuf,posbits,code,n_bits,bitmask); ! 280: ! 281: if (oldcode == -1) { ! 282: outbuf[outpos++] = (char_type)(finchar = (int)(oldcode=code)); ! 283: continue; ! 284: } ! 285: if (code == CLEAR && block_mode) { ! 286: clear_tab_prefixof(); ! 287: free_ent = FIRST - 1; ! 288: posbits = ((posbits-1) + ! 289: ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3))); ! 290: maxcode = MAXCODE(n_bits = INIT_BITS)-1; ! 291: bitmask = (1<<n_bits)-1; ! 292: goto resetbuf; ! 293: } ! 294: incode = code; ! 295: stackp = de_stack; ! 296: ! 297: if (code >= free_ent) { /* Special case for KwKwK string. */ ! 298: if (code > free_ent) { ! 299: ! 300: REG1 char_type *p; ! 301: ! 302: posbits -= n_bits; ! 303: p = &inbuf[posbits>>3]; ! 304: ! 305: fprintf(stderr, ! 306: "code:%ld free_ent:%ld n_bits:%d insize:%u\n", ! 307: code, free_ent, n_bits, insize); ! 308: fprintf(stderr, ! 309: "posbits:%ld inbuf:%02X %02X %02X %02X %02X\n", ! 310: posbits, p[-1],p[0],p[1],p[2],p[3]); ! 311: if (!test && outpos > 0 ! 312: && write(out, outbuf, outpos) != outpos) { ! 313: write_error(); ! 314: } ! 315: error("Corrupt input. Use zcat to recover some data."); ! 316: } ! 317: *--stackp = (char_type)finchar; ! 318: code = oldcode; ! 319: } ! 320: ! 321: while ((cmp_code_int)code >= (cmp_code_int)256) { ! 322: /* Generate output characters in reverse order */ ! 323: *--stackp = tab_suffixof(code); ! 324: code = tab_prefixof(code); ! 325: } ! 326: *--stackp = (char_type)(finchar = tab_suffixof(code)); ! 327: ! 328: /* And put them out in forward order */ ! 329: { ! 330: REG1 int i; ! 331: ! 332: if (outpos+(i = (de_stack-stackp)) >= OUTBUFSIZ) { ! 333: do { ! 334: if (i > OUTBUFSIZ-outpos) i = OUTBUFSIZ-outpos; ! 335: ! 336: if (i > 0) { ! 337: memcpy(outbuf+outpos, stackp, i); ! 338: outpos += i; ! 339: } ! 340: if (outpos >= OUTBUFSIZ) { ! 341: if (!test && write(out, outbuf, outpos) != outpos){ ! 342: write_error(); ! 343: } ! 344: outpos = 0; ! 345: } ! 346: stackp+= i; ! 347: } while ((i = (de_stack-stackp)) > 0); ! 348: } else { ! 349: memcpy(outbuf+outpos, stackp, i); ! 350: outpos += i; ! 351: } ! 352: } ! 353: ! 354: if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */ ! 355: ! 356: tab_prefixof(code) = (unsigned short)oldcode; ! 357: tab_suffixof(code) = (char_type)finchar; ! 358: free_ent = code+1; ! 359: } ! 360: oldcode = incode; /* Remember previous code. */ ! 361: } ! 362: bytes_in += rsize; ! 363: ! 364: } while (rsize != 0); ! 365: ! 366: if (!test && outpos > 0 && write(out, outbuf, outpos) != outpos) { ! 367: write_error(); ! 368: } ! 369: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.