Annotation of coherent/b/bin/unzip/unshrink.c, revision 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.