Commit | Line | Data |
---|---|---|
9b565000 | 1 | /* uncompact.c 4.3 83/06/03 */ |
c3a7147a BS |
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 | } | |
9b565000 | 58 | if (j >= (LNAME - 3) || (j - m) > MAXNAMLEN) { |
c3a7147a BS |
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 | } |