Annotation of coherent/b/bin/unzip/unshrink.c, revision 1.1.1.1

1.1       root        1: /*---------------------------------------------------------------------------
                      2: 
                      3:   unshrink.c
                      4: 
                      5:   Shrinking is a Dynamic Lempel-Ziv-Welch compression algorithm with partial
                      6:   clearing.
                      7: 
                      8:   ---------------------------------------------------------------------------*/
                      9: 
                     10: 
                     11: #include "unzip.h"
                     12: 
                     13: 
                     14: /*************************************/
                     15: /*  UnShrink Defines, Globals, etc.  */
                     16: /*************************************/
                     17: 
                     18: /*      MAX_BITS        13   (in unzip.h; defines size of global work area)  */
                     19: #define INIT_BITS       9
                     20: #define FIRST_ENT       257
                     21: #define CLEAR           256
                     22: #define GetCode(dest)   READBIT(codesize,dest)
                     23: 
                     24: static void partial_clear __((void));   /* local prototype */
                     25: 
                     26: int codesize, maxcode, maxcodemax, free_ent;
                     27: 
                     28: 
                     29: 
                     30: 
                     31: /*************************/
                     32: /*  Function unShrink()  */
                     33: /*************************/
                     34: 
                     35: void unShrink()
                     36: {
                     37:     register int code;
                     38:     register int stackp;
                     39:     int finchar;
                     40:     int oldcode;
                     41:     int incode;
                     42: 
                     43: 
                     44:     /* decompress the file */
                     45:     codesize = INIT_BITS;
                     46:     maxcode = (1 << codesize) - 1;
                     47:     maxcodemax = HSIZE;         /* (1 << MAX_BITS) */
                     48:     free_ent = FIRST_ENT;
                     49: 
                     50:     code = maxcodemax;
                     51:     do {
                     52:         prefix_of[code] = -1;
                     53:     } while (--code > 255);
                     54: /*
                     55:     OvdL: -Ox with SCO's 3.2.0 cc gives
                     56:     a. warning: overflow in constant multiplication
                     57:     b. segmentation fault (core dumped) when using the executable
                     58:     for (code = maxcodemax; code > 255; code--)
                     59:         prefix_of[code] = -1;
                     60:  */
                     61: 
                     62:     for (code = 255; code >= 0; code--) {
                     63:         prefix_of[code] = 0;
                     64:         suffix_of[code] = (byte) code;
                     65:     }
                     66: 
                     67:     GetCode(oldcode);
                     68:     if (zipeof)
                     69:         return;
                     70:     finchar = oldcode;
                     71: 
                     72:     OUTB(finchar);
                     73: 
                     74:     stackp = HSIZE;
                     75: 
                     76:     while (!zipeof) {
                     77:         GetCode(code);
                     78:         if (zipeof)
                     79:             return;
                     80: 
                     81:         while (code == CLEAR) {
                     82:             GetCode(code);
                     83:             switch (code) {
                     84:                 case 1:
                     85:                     codesize++;
                     86:                     if (codesize == MAX_BITS)
                     87:                         maxcode = maxcodemax;
                     88:                     else
                     89:                         maxcode = (1 << codesize) - 1;
                     90:                     break;
                     91: 
                     92:                 case 2:
                     93:                     partial_clear();
                     94:                     break;
                     95:             }
                     96: 
                     97:             GetCode(code);
                     98:             if (zipeof)
                     99:                 return;
                    100:         }
                    101: 
                    102: 
                    103:         /* special case for KwKwK string */
                    104:         incode = code;
                    105:         if (prefix_of[code] == -1) {
                    106:             stack[--stackp] = (byte) finchar;
                    107:             code = oldcode;
                    108:         }
                    109:         /* generate output characters in reverse order */
                    110:         while (code >= FIRST_ENT) {
                    111:             if (prefix_of[code] == -1) {
                    112:                 stack[--stackp] = (byte) finchar;
                    113:                 code = oldcode;
                    114:             } else {
                    115:                 stack[--stackp] = suffix_of[code];
                    116:                 code = prefix_of[code];
                    117:             }
                    118:         }
                    119: 
                    120:         finchar = suffix_of[code];
                    121:         stack[--stackp] = (byte) finchar;
                    122: 
                    123: 
                    124:         /* and put them out in forward order, block copy */
                    125:         if ((HSIZE - stackp + outcnt) < OUTBUFSIZ) {
                    126:             memcpy(outptr, &stack[stackp], HSIZE - stackp);
                    127:             outptr += HSIZE - stackp;
                    128:             outcnt += HSIZE - stackp;
                    129:             stackp = HSIZE;
                    130:         }
                    131:         /* output byte by byte if we can't go by blocks */
                    132:         else
                    133:             while (stackp < HSIZE)
                    134:                 OUTB(stack[stackp++]);
                    135: 
                    136: 
                    137:         /* generate new entry */
                    138:         code = free_ent;
                    139:         if (code < maxcodemax) {
                    140:             prefix_of[code] = oldcode;
                    141:             suffix_of[code] = (byte) finchar;
                    142: 
                    143:             do
                    144:                 code++;
                    145:             while ((code < maxcodemax) && (prefix_of[code] != -1));
                    146: 
                    147:             free_ent = code;
                    148:         }
                    149:         /* remember previous code */
                    150:         oldcode = incode;
                    151:     }
                    152: }
                    153: 
                    154: 
                    155: 
                    156: /******************************/
                    157: /*  Function partial_clear()  */
                    158: /******************************/
                    159: 
                    160: static void partial_clear()
                    161: {
                    162:     register int pr;
                    163:     register int cd;
                    164: 
                    165:     /* mark all nodes as potentially unused */
                    166:     for (cd = FIRST_ENT; cd < free_ent; cd++)
                    167:         prefix_of[cd] |= 0x8000;
                    168: 
                    169:     /* unmark those that are used by other nodes */
                    170:     for (cd = FIRST_ENT; cd < free_ent; cd++) {
                    171:         pr = prefix_of[cd] & 0x7fff;    /* reference to another node? */
                    172:         if (pr >= FIRST_ENT)    /* flag node as referenced */
                    173:             prefix_of[pr] &= 0x7fff;
                    174:     }
                    175: 
                    176:     /* clear the ones that are still marked */
                    177:     for (cd = FIRST_ENT; cd < free_ent; cd++)
                    178:         if ((prefix_of[cd] & 0x8000) != 0)
                    179:             prefix_of[cd] = -1;
                    180: 
                    181:     /* find first cleared node as next free_ent */
                    182:     cd = FIRST_ENT;
                    183:     while ((cd < maxcodemax) && (prefix_of[cd] != -1))
                    184:         cd++;
                    185:     free_ent = cd;
                    186: }

unix.superglobalmegacorp.com

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