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