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

Defined functions

encode defined in line 232; used 3 times
main defined in line 18; never used

Defined variables

bits defined in line 15; used 11 times
d defined in line 14; used 17 times
Last modified: 1983-07-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1087
Valid CSS Valid XHTML 1.0 Strict