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