Annotation of coherent/g/usr/bin/gzip/unlzw.c, revision 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.