Annotation of 43BSD/old/compact/compact.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)compact.c  4.7 (Berkeley) 8/25/84";
                      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: #include <strings.h>
                     15: #include "compact.h"
                     16: 
                     17: union  cio d;
                     18: union  cio c;
                     19: int    bits;
                     20: char   *infname;                       /* input file's name */
                     21: char   fname[MAXPATHLEN+1];            /* output file's name */
                     22: struct stat ucfstatus;                 /* uncompacted file status */
                     23: 
                     24: int    verbose = 0;
                     25: 
                     26: main(argc, argv)
                     27:        int argc;
                     28:        char *argv[];
                     29: {
                     30:        register short j;
                     31: 
                     32:        argc--, argv++;
                     33:        if (argc > 0 && strcmp(*argv, "-v") == 0) {
                     34:                verbose++;
                     35:                argc--, argv++;
                     36:        }
                     37:        dir[513].next = NULL;
                     38:        for (head = dir + (j = 513); j--; ) {
                     39:                dirp = head--;
                     40:                head->next = dirp;
                     41:        }
                     42:        bottom = dirp->pt = dict;
                     43:        dict[0].sons[LEFT].top = dict[0].sons[RIGHT].top = dirp;
                     44:        dirq = dirp->next;
                     45:        in[EF].flags = FBIT | SEEN;
                     46:        if (argc == 0)
                     47:                exit(compact("-"));
                     48:        for (j = 0; j < argc; j++) {
                     49:                if (verbose && argc > 0)
                     50:                        printf("%s: ", argv[j]);
                     51:                if (compact(argv[j]))
                     52:                        exit(1);
                     53:        }
                     54:        exit(0);
                     55: }
                     56: 
                     57: /*
                     58:  * Compact a single file ("-" implies stdin).
                     59:  */
                     60: compact(file)
                     61:        char *file;
                     62: {
                     63:        int j, ignore;
                     64:        FILE *setup();
                     65: 
                     66:        for (j = 256; j--; )
                     67:                in[j].flags = 0;
                     68:        bottom->sons[RIGHT].top->next = flist;
                     69:        bottom->sons[RIGHT].top = dirp;
                     70:        flist = dirq;
                     71:        cfp = uncfp = NULL;
                     72:        if (strcmp(file, "-") != 0) {
                     73:                char *cp, *tp;
                     74: 
                     75:                /* verify .C suffix fits */
                     76:                cp = rindex(file, '/');
                     77:                if (cp == 0)
                     78:                        cp = file;
                     79:                else
                     80:                        cp++;
                     81:                tp = index(cp, '\0');
                     82:                if (tp - cp > MAXNAMLEN || strlen(file) + 2 >= MAXPATHLEN) {
                     83:                        fprintf(stderr, "%s: File name too long\n", file);
                     84:                        goto bad;
                     85:                }
                     86:                uncfp = fopen(file, "r");
                     87:                if (uncfp == NULL) {
                     88:                        fprintf(stderr, "compact: "), perror(file);
                     89:                        goto bad;
                     90:                }
                     91:                fstat(fileno(uncfp), &ucfstatus);
                     92:                if ((ucfstatus.st_mode & S_IFMT) != S_IFREG) {
                     93:                        fprintf(stderr, "%s: Not a regular file.\n", file);
                     94:                        goto bad;
                     95:                }
                     96:        } else
                     97:                uncfp = stdin;
                     98:        infname = file;
                     99: 
                    100:        cfp = setup(uncfp, &ignore);
                    101:        if (cfp == NULL) {
                    102:                if (ignore)
                    103:                        goto done;
                    104:                goto bad;
                    105:        }
                    106:        if (compress(uncfp, cfp)) {
                    107:                if (cfp != stdout)
                    108:                        (void) unlink(fname);
                    109:                goto bad2;
                    110:        }
                    111:        encode(EF);
                    112:        if (bits) {
                    113:                d.integ <<= 16 - bits;
                    114:                putc(d.chars.hib, cfp);
                    115:                if (bits > 8)
                    116:                        putc(d.chars.lob, cfp);
                    117:                bits = 0;
                    118:        }
                    119:        fflush(cfp);
                    120:        if (ferror(uncfp) || ferror(cfp)) {
                    121:                if (cfp != stdout) {
                    122:                        fprintf(stderr, "compact: ");
                    123:                        if (ferror(cfp))
                    124:                                perror(fname);
                    125:                        else
                    126:                                perror(infname);
                    127:                        (void) unlink(fname);
                    128:                }
                    129:                goto bad;
                    130:        }
                    131:        if (cfp != stdout) {
                    132:                struct stat cfstatus;
                    133:                longint csize, ucsize;
                    134: 
                    135:                (void) fstat(fileno(cfp), &cfstatus);
                    136:                csize = cfstatus.st_size;
                    137:                ucsize = ucfstatus.st_size;
                    138:                if (csize >= ucsize) {
                    139:                        fprintf("%s: ", infname);
                    140:                        (void) unlink(fname);
                    141:                        printf("Not compacted, does not save bytes.\n");
                    142:                        goto done;
                    143:                }
                    144:                if (verbose) {
                    145:                        FILE *fd;
                    146:                        longint n, m;
                    147: 
                    148:                        while (ucsize - csize > 21474) {
                    149:                                ucsize /= 10;
                    150:                                csize /= 10;
                    151:                        }
                    152:                        n = 100000 * (ucsize - csize) / ucsize + 5;
                    153:                        m = (n % 1000) / 10;
                    154:                        bits = m % 10 + '0';
                    155:                        c.integ = m / 10 + '0';
                    156:                        printf("%ld.%c%c%% compression\n",
                    157:                            n / 1000, c.chars.lob, bits);
                    158:                }
                    159:                if (unlink(infname) < 0)
                    160:                        fprintf(stderr, "compact: "), perror(infname);
                    161:        }
                    162: done:
                    163:        if (cfp != NULL && cfp != stdout)
                    164:                fclose(cfp);
                    165:        if (uncfp != NULL)
                    166:                fclose(uncfp);
                    167:        return (0);
                    168: bad2:
                    169:        fprintf(stderr, "compact: ");
                    170:        if (cfp != stdout)
                    171:                perror(infname);
                    172:        else
                    173:                fprintf(stderr,
                    174:            "Unsuccessful compact of standard input to standard output.\n");
                    175: bad:
                    176:        if (cfp != NULL && cfp != stdout)
                    177:                fclose(cfp);
                    178:        if (uncfp != NULL)
                    179:                fclose(uncfp);
                    180:        return (1);
                    181: }
                    182: 
                    183: encode(ch)
                    184:        int ch;
                    185: {
                    186:        register struct node *pp;
                    187:        int stack[17];
                    188:        register int stbits = 1, *sp = &stack[0], rbits = bits;
                    189:        register union cio *dp = &d;
                    190:        union cio c;
                    191: 
                    192:        c.integ = ch;
                    193:        *sp = in[ch].flags & FBIT;
                    194:        pp = in[ch].fp;
                    195: 
                    196:        while (pp->fath.fp) {
                    197:                *sp <<= 1;
                    198:                if (pp->fath.flags & FBIT)
                    199:                        (*sp)++;
                    200:                stbits++;
                    201:                if ((stbits &= 017) == 0)
                    202:                        sp++;
                    203:                pp = pp->fath.fp;
                    204:        }
                    205: 
                    206:        /* pop the output stack */
                    207:        do {
                    208:                while (stbits-- > 0) {
                    209:                        dp->integ <<= 1;
                    210:                        if (*sp & 01)
                    211:                                dp->integ++;
                    212:                        ++rbits;
                    213:                        if ((rbits &= 017) == 0) {
                    214:                                putc(dp->chars.hib, cfp);
                    215:                                putc(dp->chars.lob, cfp);
                    216:                                if (ferror(cfp))
                    217:                                        goto done;
                    218:                        }
                    219:                        *sp >>= 1;
                    220:                }
                    221:                stbits = 16;
                    222:        } while (--sp >= &stack[0]);
                    223: done:
                    224:        bits = rbits;
                    225: }
                    226: 
                    227: compress(uncfp, cfp)
                    228:        register FILE *uncfp, *cfp;
                    229: {
                    230:        register union cio *dp = &d;
                    231:        register union cio *cp = &c;
                    232: 
                    233:        cp->integ = (dp->integ >> 8) & 0377;
                    234:        for (; cp->integ != EOF; cp->integ = getc(uncfp)) {
                    235:                if ((in[cp->integ].flags & SEEN) == 0) {
                    236:                        register short j, m;
                    237: 
                    238:                        encode(NC);
                    239:                        uptree(NC);
                    240:                        insert(cp->integ);
                    241: 
                    242:                        m = 0200;
                    243:                        for (j = 8; j--; m >>= 1) {
                    244:                                dp->integ <<= 1;
                    245:                                if (m & cp->integ)
                    246:                                        dp->integ++;
                    247:                                ++bits;
                    248:                                if ((bits &= 017) == 0) {
                    249:                                        putc(dp->chars.hib, cfp);
                    250:                                        putc(dp->chars.lob, cfp);
                    251:                                }
                    252:                        }
                    253:                } else
                    254:                        encode(cp->integ);
                    255:                if (ferror(cfp)) {
                    256:                        perror(fname);
                    257:                        return (1);
                    258:                }
                    259:                uptree(cp->integ);
                    260:        }
                    261:        if (ferror(uncfp)) {
                    262:                perror(infname);
                    263:                return (1);
                    264:        }
                    265:        return (0);
                    266: }
                    267: 
                    268: FILE *
                    269: setup(uncfp, ignore)
                    270:        FILE *uncfp;
                    271:        int *ignore;
                    272: {
                    273:        FILE *cfp = NULL;
                    274:        register union cio *dp = &d;
                    275:        register union cio *cp = &c;
                    276: 
                    277:        dp->integ = getc(uncfp);
                    278:        if (*ignore = (dp->integ == EOF))
                    279:                goto bad;
                    280:        cp->integ = getc(uncfp);
                    281:        if (*ignore = (cp->integ == EOF))
                    282:                goto bad;
                    283:        dp->chars.hib = cp->integ & 0377;
                    284:        if ((dp->integ &= 0177777) == COMPACTED) {
                    285:                fprintf(stderr, "%s: Already compacted.\n", infname);
                    286:                *ignore = 1;
                    287:                goto bad;
                    288:        }
                    289:        if (dp->integ == PACKED) {
                    290:                fprintf(stderr,
                    291:                    "%s: Already packed using pack program, use unpack.\n",
                    292:                    infname);
                    293:                *ignore = 1;
                    294:                goto bad;
                    295:        }
                    296:        if (strcmp(infname, "-") != 0) {
                    297:                sprintf(fname, "%s.C", infname);
                    298:                cfp = fopen(fname, "w");
                    299:                if (cfp == NULL)
                    300:                        goto bad2;
                    301:                (void) fchmod(fileno(cfp), ucfstatus.st_mode);
                    302:        } else
                    303:                cfp = stdout;
                    304:        cp->integ = COMPACTED;
                    305:        putc(cp->chars.lob, cfp);
                    306:        putc(cp->chars.hib, cfp);
                    307:        if (ferror(cfp))
                    308:                goto bad2;
                    309:        bits = 8;
                    310:        cp->integ = dp->integ & 0377;
                    311: 
                    312:        in[NC].fp = in[EF].fp = dict[0].sons[LEFT].sp.p = bottom = dict + 1;
                    313:        bottom->sons[LEFT].count = bottom->sons[RIGHT].count =
                    314:            dict[0].sons[RIGHT].count = 1;
                    315:        dirp->next = dict[0].sons[RIGHT].top = bottom->sons[LEFT].top =
                    316:            bottom->sons[RIGHT].top = dirq = NEW;
                    317:        dirq->next = NULL;
                    318:        dict[0].fath.fp = NULL;
                    319:        dirq->pt = bottom->fath.fp = in[cp->integ].fp = dict;
                    320:        in[cp->integ].flags = (FBIT | SEEN);
                    321:        in[NC].flags = SEEN;
                    322:        dict[0].fath.flags = RLEAF;
                    323:        bottom->fath.flags = (LLEAF | RLEAF);
                    324:        dict[0].sons[LEFT].count = 2;
                    325: 
                    326:        dict[0].sons[RIGHT].sp.ch = cp->integ;
                    327:        bottom->sons[LEFT].sp.ch = NC;
                    328:        bottom->sons[RIGHT].sp.ch = EF;
                    329:        return (cfp);
                    330: bad2:
                    331:        if (cfp && cfp != stdout) {
                    332:                fprintf(stderr, "compact: "), perror(fname);
                    333:                (void) unlink(fname);
                    334:        }
                    335: bad:
                    336:        if (cfp && cfp != stdout)
                    337:                fclose(cfp);
                    338:        return (NULL);
                    339: }

unix.superglobalmegacorp.com

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