|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)compact.c 4.4 (Berkeley) 8/11/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * Adaptive Huffman code input to output ! 7: * ! 8: * On - line algorithm ! 9: * ! 10: * Does not prepend decoding tree ! 11: * ! 12: * Written by Colin L. Mc Master (UCB) February 28, 1979 ! 13: */ ! 14: ! 15: ! 16: #include "compact.h" ! 17: ! 18: union cio d; ! 19: int bits; ! 20: ! 21: ! 22: main (argc, argv) ! 23: short argc; ! 24: char *argv [ ]; ! 25: { ! 26: register short i, j; ! 27: register int m; ! 28: union cio c; ! 29: short l; ! 30: longint ic, n; ! 31: char *cp, fname [LNAME]; ! 32: ! 33: dir [513] . next = NULL; ! 34: for (head = dir + (j = 513); j--; ) { ! 35: dirp = head--; ! 36: head -> next = dirp; ! 37: } ! 38: bottom = dirp -> pt = dict; ! 39: dict [0] . top [0] = dict [0] . top [1] = dirp; ! 40: dirq = dirp -> next; ! 41: in [EF] . flags = FBIT | SEEN; ! 42: ! 43: for (i = 1; ; i++) { ! 44: ic = oc = 0; ! 45: (bottom -> top [1]) -> next = flist; ! 46: bottom -> top [1] = dirp; ! 47: flist = dirq; ! 48: if (i >= argc) { ! 49: uncfp = stdin; ! 50: cfp = stdout; ! 51: } ! 52: else { ! 53: m = -1; ! 54: cp = fname; ! 55: for (l = 0; l < (LNAME - 3) && (*cp = argv [i][l]); l++) ! 56: if (*cp++ == '/') m = l; ! 57: if (l >= (LNAME - 3) || (l - m) > MAXNAMLEN - 1) { ! 58: fprintf (stderr, "%s: File name too long\n", argv [i]); ! 59: if (i == argc - 1) break; ! 60: continue; ! 61: } ! 62: if ((uncfp = fopen (argv [i], "r")) == NULL) { ! 63: perror (argv [i]); ! 64: if (i == argc - 1) break; ! 65: continue; ! 66: } ! 67: } ! 68: ! 69: fstat (fileno (uncfp), &status); ! 70: if ((status.st_mode & 040000) == 040000) { ! 71: fprintf (stderr, "%s: Can't compact a directory\n", argv [i]); ! 72: if (i < argc) goto closein; ! 73: break; ! 74: } ! 75: ! 76: if ((d . integ = getc (uncfp)) != EOF) { ! 77: ic++; ! 78: if ((c . integ = getc (uncfp)) != EOF) { ! 79: d . chars . hib = c . integ & 0377; ! 80: if ((d . integ &= 0177777) == COMPACTED) { ! 81: fprintf (stderr, "%s: Already compacted.\n", argv [i]); ! 82: if (i < argc) goto closein; ! 83: break; ! 84: } ! 85: if (d . integ == PACKED) { ! 86: fprintf (stderr, "%s: Already packed using program pack. Use unpack.\n", argv [i]); ! 87: if (i < argc) goto closein; ! 88: break; ! 89: } ! 90: if (i < argc) { ! 91: *cp++ = '.'; *cp++ = 'C'; *cp = '\0'; ! 92: if ((cfp = fopen (fname, "w")) == NULL) { ! 93: perror (fname); ! 94: goto closein; ! 95: } ! 96: chmod (fname, status.st_mode); ! 97: } ! 98: c . integ = COMPACTED; ! 99: putc (c . chars . lob, cfp); ! 100: putc (c . chars . hib, cfp); ! 101: if (ferror (cfp)) ! 102: if (i < argc) { ! 103: perror (fname); ! 104: unlink (fname); ! 105: goto closeboth; ! 106: } ! 107: else goto fail; ! 108: bits = 8; ! 109: oc = 2; ! 110: c . integ = d . integ & 0377; ! 111: ! 112: in [NC] . fp = in [EF] . fp = dict [0] . sp [0] . p = bottom = dict + 1; ! 113: bottom -> count [0] = bottom -> count [1] = dict [0] . count [1] = 1; ! 114: dirp -> next = dict [0] . top [1] = bottom -> top [0] = bottom -> top [1] = dirq = NEW; ! 115: dirq -> next = NULL; ! 116: dict [0] . fath . fp = NULL; ! 117: dirq -> pt = bottom -> fath . fp = in [c . integ] . fp = dict; ! 118: in [c . integ] . flags = (FBIT | SEEN); ! 119: in [NC] . flags = SEEN; ! 120: dict [0] . fath . flags = RLEAF; ! 121: bottom -> fath . flags = (LLEAF | RLEAF); ! 122: dict [0] . count [0] = 2; ! 123: ! 124: dict [0] . sp [1] . ch = c . integ; ! 125: bottom -> sp [0] . ch = NC; ! 126: bottom -> sp [1] . ch = EF; ! 127: ! 128: for (c . integ = ((d . integ >> 8) & 0377); c . integ != EOF; c . integ = getc (uncfp)) { ! 129: ic++; ! 130: if (in [c . integ] . flags & SEEN) encode (c . integ); ! 131: else { ! 132: encode (NC); ! 133: uptree (NC); ! 134: insert (c . integ); ! 135: ! 136: m = 0200; ! 137: for (j = 8; j--; m >>= 1) { ! 138: d . integ <<= 1; ! 139: if (m & c . integ) d . integ++; ! 140: ++bits; ! 141: if ((bits &= 017) == 0) { ! 142: putc (d . chars . hib, cfp); ! 143: putc (d . chars . lob, cfp); ! 144: oc += 2; ! 145: } ! 146: } ! 147: } ! 148: if (ferror (cfp)) ! 149: if (i < argc) { ! 150: perror (fname); ! 151: unlink (fname); ! 152: goto closeboth; ! 153: } ! 154: else goto fail; ! 155: uptree (c . integ); ! 156: ! 157: } ! 158: ! 159: if (ferror (uncfp)) ! 160: if (i < argc) { ! 161: perror (argv [i]); ! 162: unlink (fname); ! 163: goto closeboth; ! 164: } ! 165: else goto fail; ! 166: ! 167: encode (EF); ! 168: ! 169: if (bits) { ! 170: d . integ <<= (16 - bits); ! 171: oc++; ! 172: putc (d . chars . hib, cfp); ! 173: if (bits > 8) { ! 174: oc++; ! 175: putc (d . chars . lob, cfp); ! 176: } ! 177: bits = 0; ! 178: } ! 179: } ! 180: else oc = ic; ! 181: } ! 182: ! 183: if (ferror (uncfp) || ferror (cfp)) ! 184: if (i < argc) { ! 185: if (ferror (cfp)) ! 186: perror (fname); ! 187: else ! 188: perror (argv [i]); ! 189: if (oc > 1) { ! 190: unlink (fname); ! 191: goto closeboth; ! 192: } ! 193: goto closein; ! 194: } ! 195: else goto fail; ! 196: else { ! 197: if (oc >= ic) { ! 198: if (i < argc) fprintf (stderr, "%s: ", argv [i]); ! 199: if (i < argc) fprintf (stderr, "Not compacted. "); ! 200: fprintf (stderr, "Does not save bytes.\n"); ! 201: if (i < argc) { ! 202: if (oc > 1) { ! 203: unlink (fname); ! 204: goto closeboth; ! 205: } ! 206: goto closein; ! 207: } ! 208: else break; ! 209: } ! 210: while ((ic - oc) > 21474) { ! 211: ic /= 10; ! 212: oc /= 10; ! 213: } ! 214: n = 100000 * (ic - oc) / ic + 5; ! 215: m = (n % 1000) / 10; ! 216: bits = m % 10 + '0'; ! 217: c . integ = m / 10 + '0'; ! 218: if (i < argc) fprintf (stderr, "%s: ", argv [i]); ! 219: fprintf (stderr, "Compression : %4ld.%c%c%%\n", n / 1000, c . chars . lob, bits); ! 220: } ! 221: ! 222: if (i >= argc) break; ! 223: unlink (argv [i]); ! 224: closeboth : fclose (cfp); ! 225: closein : fclose (uncfp); ! 226: if (i == argc - 1) break; ! 227: for (j = 256; j--; ) in [j] . flags = 0; ! 228: continue; ! 229: fail : fprintf (stderr, "Unsuccessful compact of standard input to standard output.\n"); ! 230: break; ! 231: } ! 232: } ! 233: ! 234: encode (ch) ! 235: int ch; ! 236: { ! 237: ! 238: register struct node *pp; ! 239: register char j; ! 240: union cio c; ! 241: int stack [17], stp, stbits; ! 242: ! 243: c . integ = ch; ! 244: stack [stp = 0] = in [c . integ] . flags & FBIT; ! 245: stbits = 1; ! 246: pp = in [c . integ] . fp; ! 247: ! 248: while (pp -> fath . fp) { ! 249: stack [stp] <<= 1; ! 250: if (pp -> fath . flags & FBIT) stack [stp]++; ! 251: stbits++; ! 252: if ((stbits &= 017) == 0) stp++; ! 253: pp = pp -> fath . fp; ! 254: } ! 255: ! 256: /* pop the output stack */ ! 257: ! 258: for (stp++; stp--; ) { ! 259: for (j = 0; j < stbits; j++) { ! 260: d . integ <<= 1; ! 261: if (stack [stp] & 01) d . integ++; ! 262: ++bits; ! 263: if ((bits &= 017) == 0) { ! 264: putc (d . chars . hib, cfp); ! 265: putc (d . chars . lob, cfp); ! 266: if (ferror (cfp)) return; ! 267: oc += 2; ! 268: } ! 269: stack [stp] >>= 1; ! 270: } ! 271: stbits = 16; ! 272: } ! 273: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.