1*10922Sshannon /* uncompact.c 4.1 83/02/11 */ 2*10922Sshannon /* 3*10922Sshannon * Uncompact adaptive Huffman code input to output 4*10922Sshannon * 5*10922Sshannon * On - line algorithm 6*10922Sshannon * 7*10922Sshannon * Input file does not contain decoding tree 8*10922Sshannon * 9*10922Sshannon * Written by Colin L. Mc Master (UCB) February 14, 1979 10*10922Sshannon */ 11*10922Sshannon 12*10922Sshannon #include "compact.h" 13*10922Sshannon 14*10922Sshannon 15*10922Sshannon main (argc, argv) 16*10922Sshannon short argc; 17*10922Sshannon char *argv [ ]; 18*10922Sshannon { 19*10922Sshannon register short i; 20*10922Sshannon register struct node *p; 21*10922Sshannon register short j; 22*10922Sshannon register int m; 23*10922Sshannon union cio c, d; 24*10922Sshannon char b; 25*10922Sshannon longint ic, n; 26*10922Sshannon char fname [LNAME], *cp; 27*10922Sshannon 28*10922Sshannon dir [513] . next = NULL; 29*10922Sshannon for (head = dir + (j = 513); j--; ) { 30*10922Sshannon dirp = head--; 31*10922Sshannon head -> next = dirp; 32*10922Sshannon } 33*10922Sshannon bottom = dirp -> pt = dict; 34*10922Sshannon dict [0] . top [0] = dict [0] . top [1] = dirp; 35*10922Sshannon dirq = dirp -> next; 36*10922Sshannon in [EF] . flags = FBIT | SEEN; 37*10922Sshannon 38*10922Sshannon for (i = 1; ; i++) { 39*10922Sshannon ic = oc = 0; 40*10922Sshannon (bottom -> top [1]) -> next = flist; 41*10922Sshannon bottom -> top [1] = dirp; 42*10922Sshannon flist = dirq; 43*10922Sshannon if (i >= argc) { 44*10922Sshannon uncfp = stdout; 45*10922Sshannon cfp = stdin; 46*10922Sshannon } 47*10922Sshannon else { 48*10922Sshannon m = -1; 49*10922Sshannon cp = fname; 50*10922Sshannon for (j = 0; j < (LNAME - 3) && (*cp = argv [i][j]); j++) 51*10922Sshannon if (*cp++ == '/') m = j; 52*10922Sshannon if (cp [-1] == 'C' && cp [-2] == '.') cp [-2] = 0; 53*10922Sshannon else { 54*10922Sshannon fprintf (stderr, "%s: File name must end with \".C\"\n", argv [i]); 55*10922Sshannon if (i == argc - 1) break; 56*10922Sshannon continue; 57*10922Sshannon } 58*10922Sshannon if (j >= (LNAME - 3) || (j - m) > 15) { 59*10922Sshannon fprintf (stderr, "File name too long -- %s\n", argv [i]); 60*10922Sshannon if (i == argc - 1) break; 61*10922Sshannon continue; 62*10922Sshannon } 63*10922Sshannon if ((cfp = fopen (argv [i], "r")) == NULL) { 64*10922Sshannon perror (argv [i]); 65*10922Sshannon if (i == argc - 1) break; 66*10922Sshannon continue; 67*10922Sshannon } 68*10922Sshannon if ((uncfp = fopen (fname, "w")) == NULL) { 69*10922Sshannon perror (fname); 70*10922Sshannon fclose (cfp); 71*10922Sshannon if (i == argc - 1) break; 72*10922Sshannon continue; 73*10922Sshannon } 74*10922Sshannon fstat (fileno (cfp), &status); 75*10922Sshannon chmod (fname, status.st_mode & 07777); 76*10922Sshannon } 77*10922Sshannon 78*10922Sshannon if ((c . integ = getc (cfp)) != EOF) { 79*10922Sshannon if ((d . integ = getc (cfp)) != EOF) { 80*10922Sshannon c . chars . hib = d . integ & 0377; 81*10922Sshannon c . integ &= 0177777; 82*10922Sshannon if (c . integ != COMPACTED) goto notcompact; 83*10922Sshannon if ((c . integ = getc (cfp)) != EOF) { 84*10922Sshannon putc (c . chars . lob, uncfp); 85*10922Sshannon ic = 3; 86*10922Sshannon 87*10922Sshannon in [NC] . fp = in [EF] . fp = dict [0] . sp [0] . p = bottom = dict + 1; 88*10922Sshannon bottom -> count [0] = bottom -> count [1] = dict [0] . count [1] = 1; 89*10922Sshannon dirp -> next = dict [0] . top [1] = bottom -> top [0] = bottom -> top [1] = dirq = NEW; 90*10922Sshannon dirq -> next = NULL; 91*10922Sshannon dict [0] . fath . fp = NULL; 92*10922Sshannon dirq -> pt = bottom -> fath . fp = in [c . integ] . fp = dict; 93*10922Sshannon in [c . integ] . flags = (FBIT | SEEN); 94*10922Sshannon in [NC] . flags = SEEN; 95*10922Sshannon dict [0] . fath . flags = RLEAF; 96*10922Sshannon bottom -> fath . flags = (LLEAF | RLEAF); 97*10922Sshannon dict [0] . count [0] = 2; 98*10922Sshannon 99*10922Sshannon dict [0] . sp [1] . ch = c . integ; 100*10922Sshannon bottom -> sp [0] . ch = NC; 101*10922Sshannon bottom -> sp [1] . ch = EF; 102*10922Sshannon 103*10922Sshannon p = dict; 104*10922Sshannon while ((c . integ = getc (cfp)) != EOF) { 105*10922Sshannon ic++; 106*10922Sshannon for (m = 0200; m; ) { 107*10922Sshannon b = (m & c . integ ? 1 : 0); 108*10922Sshannon m >>= 1; 109*10922Sshannon if (p -> fath . flags & (b ? RLEAF : LLEAF)) { 110*10922Sshannon d . integ = p -> sp [b] . ch; 111*10922Sshannon if (d . integ == EF) break; 112*10922Sshannon if (d . integ == NC) { 113*10922Sshannon uptree (NC); 114*10922Sshannon d . integ = 0; 115*10922Sshannon for (j = 8; j--; m >>= 1) { 116*10922Sshannon if (m == 0) { 117*10922Sshannon c . integ = getc (cfp); 118*10922Sshannon ic++; 119*10922Sshannon m = 0200; 120*10922Sshannon } 121*10922Sshannon d . integ <<= 1; 122*10922Sshannon if (m & c . integ) d . integ++; 123*10922Sshannon } 124*10922Sshannon insert (d . integ); 125*10922Sshannon } 126*10922Sshannon uptree (d . integ); 127*10922Sshannon putc (d . chars . lob, uncfp); 128*10922Sshannon oc++; 129*10922Sshannon p = dict; 130*10922Sshannon } 131*10922Sshannon else p = p -> sp [b] . p; 132*10922Sshannon } 133*10922Sshannon } 134*10922Sshannon } 135*10922Sshannon } 136*10922Sshannon else goto notcompact; 137*10922Sshannon } 138*10922Sshannon else { 139*10922Sshannon notcompact : if (i < argc) { 140*10922Sshannon fprintf (stderr, "%s: ", argv [i]); 141*10922Sshannon unlink (fname); 142*10922Sshannon } 143*10922Sshannon if (c . integ == PACKED) fprintf (stderr, "File is packed. Use unpack.\n"); 144*10922Sshannon else fprintf (stderr, "Not a compacted file.\n"); 145*10922Sshannon if (i >= argc) break; 146*10922Sshannon goto closeboth; 147*10922Sshannon } 148*10922Sshannon 149*10922Sshannon if (ferror (uncfp) || ferror (cfp)) 150*10922Sshannon if (i < argc) { 151*10922Sshannon if (ferror (uncfp)) 152*10922Sshannon perror (fname); 153*10922Sshannon else 154*10922Sshannon perror (argv [i]); 155*10922Sshannon fprintf (stderr, "Unable to uncompact %s\n", argv [i]); 156*10922Sshannon unlink (fname); 157*10922Sshannon goto closeboth; 158*10922Sshannon } 159*10922Sshannon if (i >= argc) break; 160*10922Sshannon fprintf (stderr, "%s uncompacted to %s\n", argv [i], fname); 161*10922Sshannon unlink (argv [i]); 162*10922Sshannon closeboth : fclose (cfp); 163*10922Sshannon closein : fclose (uncfp); 164*10922Sshannon if (i == argc - 1) break; 165*10922Sshannon for (j = 256; j--; ) in [j] . flags = 0; 166*10922Sshannon continue; 167*10922Sshannon fail : fprintf (stderr, "Unsuccessful uncompact of standard input to standard output.\n"); 168*10922Sshannon break; 169*10922Sshannon } 170*10922Sshannon } 171