Annotation of coherent/g/usr/bin/gzip/unlzw.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.