rewrite and speed up
[unix-history] / usr / src / old / compact / uncompact / uncompact.c
CommitLineData
524aa063 1#ifndef lint
3e76178c 2static char sccsid[] = "@(#)uncompact.c 4.6 (Berkeley) %G%";
524aa063
SL
3#endif
4
c3a7147a
BS
5/*
6 * Uncompact adaptive Huffman code input to output
7 *
8 * On - line algorithm
9 *
10 * Input file does not contain decoding tree
11 *
12 * Written by Colin L. Mc Master (UCB) February 14, 1979
13 */
c3a7147a 14#include "compact.h"
3e76178c
SL
15#include <strings.h>
16
17union cio c;
18union cio d;
19char *infname; /* input file's name */
20char fname[MAXPATHLEN+1]; /* output file's name */
21struct stat status; /* compacted file status */
c3a7147a 22
3e76178c 23int verbose = 0;
c3a7147a 24
3e76178c
SL
25main(argc, argv)
26 int argc;
27 char *argv[];
c3a7147a 28{
c3a7147a 29 register short j;
c3a7147a 30
3e76178c
SL
31 argc--, argv++;
32 if (argc > 0 && strcmp(*argv, "-v") == 0) {
33 verbose++;
34 argc--, argv++;
35 }
36 dir[513].next = NULL;
c3a7147a
BS
37 for (head = dir + (j = 513); j--; ) {
38 dirp = head--;
3e76178c 39 head->next = dirp;
c3a7147a 40 }
3e76178c
SL
41 bottom = dirp->pt = dict;
42 dict[0].top[LEFT] = dict[0].top[RIGHT] = dirp;
43 dirq = dirp->next;
44 in[EF].flags = FBIT | SEEN;
45 if (argc == 0)
46 exit(uncompact("-"));
47 for (j = 0; j < argc; j++) {
48 if (uncompact(argv[j]))
49 exit(1);
50 if (verbose && argc > 0)
51 printf("%s uncompacted to %s\n", argv[j], fname);
52 }
53 exit(0);
54}
c3a7147a 55
3e76178c
SL
56uncompact(file)
57 char *file;
58{
59 int ignore;
60 FILE *setup();
61
62 bottom->top[1]->next = flist;
63 bottom->top[1] = dirp;
64 flist = dirq;
65 if (strcmp(file, "-") != 0) {
66 char *cp;
67
68 strcpy(fname, file);
69 cp = rindex(fname, '.');
70 if (cp == 0 || strcmp(cp, ".C") != 0) {
71 fprintf(stderr,
72 "uncompact: %s: File must have .C suffix.\n", file);
73 return;
c3a7147a 74 }
3e76178c
SL
75 *cp = '\0';
76 cfp = fopen(file, "r");
77 if (cfp == NULL) {
78 fprintf(stderr, "uncompact: "), perror(file);
79 return;
c3a7147a 80 }
3e76178c
SL
81 (void) fstat(fileno(cfp), &status);
82 } else
83 cfp = stdin;
84 infname = file;
85 uncfp = setup(cfp, &ignore);
86 if (uncfp == NULL) {
87 if (ignore)
88 goto done;
89 goto bad;
90 }
91 decompress(cfp, uncfp);
92 fflush(uncfp);
93 if (ferror(uncfp) || ferror(cfp)) {
94 if (uncfp != stdout) {
95 if (ferror(uncfp))
96 perror(fname);
97 else
98 perror(infname);
99 (void) unlink(fname);
100 }
101 goto bad;
102 }
103 if (uncfp != stdout && unlink(infname) < 0)
104 fprintf(stderr, "uncompact: "), perror(infname);
105done:
106 if (uncfp != NULL && uncfp != stdout)
107 fclose(uncfp);
108 if (cfp != NULL)
109 fclose(cfp);
110 return (0);
111bad:
112 fprintf(stderr, "uncompact: ");
113 if (strcmp(infname, "-") != 0)
114 perror(infname);
115 else
116 fprintf(stderr,
117 "Unsuccessful uncompact of standard input to standard output.\n");
118 return (1);
119}
120
121decompress(cfp, uncfp)
122 register FILE *cfp, *uncfp;
123{
124 register struct node *p;
125 register short j;
126 register int m;
127 register struct cio *dp = &d;
128 char b;
c3a7147a 129
3e76178c
SL
130 p = dict;
131 while ((c.integ = getc (cfp)) != EOF) {
132 for (m = 0200; m; ) {
133 b = (m & c.integ ? 1 : 0);
134 m >>= 1;
135 if (p->fath.flags & (b ? RLEAF : LLEAF)) {
136 dp->integ = p->sp[b].ch;
137 if (dp->integ == EF)
138 break;
139 if (dp->integ == NC) {
140 uptree(NC);
141 dp->integ = 0;
142 for (j = 8; j--; m >>= 1) {
143 if (m == 0) {
144 c.integ = getc(cfp);
145 m = 0200;
c3a7147a 146 }
3e76178c
SL
147 dp->integ <<= 1;
148 if (m & c.integ)
149 dp->integ++;
c3a7147a 150 }
3e76178c 151 insert(dp->integ);
c3a7147a 152 }
3e76178c
SL
153 uptree(dp->integ);
154 putc(dp->chars.lob, uncfp);
155 p = dict;
156 } else
157 p = p->sp[b].p;
c3a7147a 158 }
3e76178c
SL
159 }
160}
161
162FILE *
163setup(cfp, ignore)
164 FILE *cfp;
165 int *ignore;
166{
167 FILE *uncfp = NULL;
168 register union cio *dp = &d;
169 register union cio *cp = &c;
170
171 dp->integ = getc(cfp);
172 if (*ignore = (dp->integ == EOF))
173 goto bad;
174 cp->integ = getc(cfp);
175 if (*ignore = (cp->integ == EOF))
176 goto bad;
177 dp->chars.hib = cp->integ & 0377;
178 if ((dp->integ &= 0177777) != COMPACTED) {
179 if (dp->integ == PACKED)
180 fprintf(stderr, "%s: File is packed, use unpack.\n",
181 infname);
182 else
183 fprintf(stderr, "%s: Not a compacted file.\n", infname);
184 *ignore = 1;
185 goto bad;
186 }
187 if (strcmp(infname, "-") != 0) {
188 uncfp = fopen(fname, "w");
189 if (uncfp == NULL) {
190 perror(fname);
191 goto bad;
c3a7147a 192 }
3e76178c
SL
193 (void) fchmod(fileno(uncfp), status.st_mode);
194 } else
195 uncfp = stdout;
196 cp->integ = getc(cfp);
197 if (cp->integ == EOF)
198 goto bad;
199 putc(cp->chars.lob, uncfp);
200
201 in[NC].fp = in[EF].fp = dict[0].sp[LEFT].p = bottom = dict + 1;
202 bottom->count[LEFT] = bottom->count[RIGHT] =
203 dict[0].count[RIGHT] = 1;
204 dirp->next = dict[0].top[RIGHT] = bottom->top[LEFT] =
205 bottom->top[RIGHT] = dirq = NEW;
206 dirq->next = NULL;
207 dict[0].fath.fp = NULL;
208 dirq->pt = bottom->fath.fp = in[cp->integ].fp = dict;
209 in[cp->integ].flags = (FBIT | SEEN);
210 in[NC].flags = SEEN;
211 dict[0].fath.flags = RLEAF;
212 bottom->fath.flags = (LLEAF | RLEAF);
213 dict[0].count[LEFT] = 2;
c3a7147a 214
3e76178c
SL
215 dict[0].sp[RIGHT].ch = cp->integ;
216 bottom->sp[LEFT].ch = NC;
217 bottom->sp[RIGHT].ch = EF;
218 return (uncfp);
219bad:
220 if (uncfp && uncfp != stdout) {
221 perror(fname);
222 (void) unlink(fname);
223 fclose(uncfp);
c3a7147a 224 }
3e76178c 225 return (NULL);
c3a7147a 226}