1: /*
2: * Adaptive Huffman code input to output
3: *
4: * On - line algorithm
5: *
6: * Does not prepend decoding tree
7: *
8: * Written by Colin L. Mc Master (UCB) February 28, 1979
9: */
10:
11:
12: #include "compact.h"
13:
14: union cio d;
15: int bits;
16:
17:
18: main (argc, argv)
19: short argc;
20: char *argv [ ];
21: {
22: register short i, j;
23: register int m;
24: union cio c;
25: short l;
26: longint ic, n;
27: char *cp, fname [LNAME];
28:
29: dir [513] . next = NULL;
30: for (head = dir + (j = 513); j--; ) {
31: dirp = head--;
32: head -> next = dirp;
33: }
34: bottom = dirp -> pt = dict;
35: dict [0] . top [0] = dict [0] . top [1] = dirp;
36: dirq = dirp -> next;
37: in [EF] . flags = FBIT | SEEN;
38:
39: for (i = 1; ; i++) {
40: ic = oc = 0;
41: (bottom -> top [1]) -> next = flist;
42: bottom -> top [1] = dirp;
43: flist = dirq;
44: if (i >= argc) {
45: uncfp = stdin;
46: cfp = stdout;
47: }
48: else {
49: m = -1;
50: cp = fname;
51: for (l = 0; l < (LNAME - 3) && (*cp = argv [i][l]); l++)
52: if (*cp++ == '/') m = l;
53: if (l >= (LNAME - 3) || (l - m) > 13) {
54: fprintf (stderr, "%s: File name too long\n", argv [i]);
55: if (i == argc - 1) break;
56: continue;
57: }
58: if ((uncfp = fopen (argv [i], "r")) == NULL) {
59: perror (argv [i]);
60: if (i == argc - 1) break;
61: continue;
62: }
63: }
64:
65: fstat (fileno (uncfp), &status);
66: if ((status.st_mode & 040000) == 040000) {
67: fprintf (stderr, "%s: Can't compact a directory\n", argv [i]);
68: if (i < argc) goto closein;
69: break;
70: }
71:
72: if ((d . integ = getc (uncfp)) != EOF) {
73: ic++;
74: if ((c . integ = getc (uncfp)) != EOF) {
75: d . chars . hib = c . integ & 0377;
76: if ((d . integ &= 0177777) == COMPACTED) {
77: fprintf (stderr, "%s: Already compacted.\n", argv [i]);
78: if (i < argc) goto closein;
79: break;
80: }
81: if (d . integ == PACKED) {
82: fprintf (stderr, "%s: Already packed using program pack. Use unpack.\n", argv [i]);
83: if (i < argc) goto closein;
84: break;
85: }
86: if (i < argc) {
87: *cp++ = '.'; *cp++ = 'C'; *cp = '\0';
88: if ((cfp = fopen (fname, "w")) == NULL) {
89: perror (fname);
90: goto closein;
91: }
92: chmod (fname, status.st_mode);
93: }
94: c . integ = COMPACTED;
95: putc (c . chars . lob, cfp);
96: putc (c . chars . hib, cfp);
97: if (ferror (cfp))
98: if (i < argc) {
99: perror (fname);
100: unlink (fname);
101: goto closeboth;
102: }
103: else goto fail;
104: bits = 8;
105: oc = 2;
106: c . integ = d . integ & 0377;
107:
108: in [NC] . fp = in [EF] . fp = dict [0] . sp [0] . p = bottom = dict + 1;
109: bottom -> count [0] = bottom -> count [1] = dict [0] . count [1] = 1;
110: dirp -> next = dict [0] . top [1] = bottom -> top [0] = bottom -> top [1] = dirq = NEW;
111: dirq -> next = NULL;
112: dict [0] . fath . fp = NULL;
113: dirq -> pt = bottom -> fath . fp = in [c . integ] . fp = dict;
114: in [c . integ] . flags = (FBIT | SEEN);
115: in [NC] . flags = SEEN;
116: dict [0] . fath . flags = RLEAF;
117: bottom -> fath . flags = (LLEAF | RLEAF);
118: dict [0] . count [0] = 2;
119:
120: dict [0] . sp [1] . ch = c . integ;
121: bottom -> sp [0] . ch = NC;
122: bottom -> sp [1] . ch = EF;
123:
124: for (c . integ = ((d . integ >> 8) & 0377); c . integ != EOF; c . integ = getc (uncfp)) {
125: ic++;
126: if (in [c . integ] . flags & SEEN) encode (c . integ);
127: else {
128: encode (NC);
129: uptree (NC);
130: insert (c . integ);
131:
132: m = 0200;
133: for (j = 8; j--; m >>= 1) {
134: d . integ <<= 1;
135: if (m & c . integ) d . integ++;
136: ++bits;
137: if ((bits &= 017) == 0) {
138: putc (d . chars . hib, cfp);
139: putc (d . chars . lob, cfp);
140: oc += 2;
141: }
142: }
143: }
144: if (ferror (cfp))
145: if (i < argc) {
146: perror (fname);
147: unlink (fname);
148: goto closeboth;
149: }
150: else goto fail;
151: uptree (c . integ);
152:
153: }
154:
155: if (ferror (uncfp))
156: if (i < argc) {
157: perror (argv [i]);
158: unlink (fname);
159: goto closeboth;
160: }
161: else goto fail;
162:
163: encode (EF);
164:
165: if (bits) {
166: d . integ <<= (16 - bits);
167: oc++;
168: putc (d . chars . hib, cfp);
169: if (bits > 8) {
170: oc++;
171: putc (d . chars . lob, cfp);
172: }
173: bits = 0;
174: }
175: }
176: else oc = ic;
177: }
178:
179: if (ferror (uncfp) || ferror (cfp))
180: if (i < argc) {
181: if (ferror (cfp))
182: perror (fname);
183: else
184: perror (argv [i]);
185: if (oc > 1) {
186: unlink (fname);
187: goto closeboth;
188: }
189: goto closein;
190: }
191: else goto fail;
192: else {
193: if (oc >= ic) {
194: if (i < argc) fprintf (stderr, "%s: ", argv [i]);
195: if (i < argc) fprintf (stderr, "Not compacted. ");
196: fprintf (stderr, "Does not save bytes.\n");
197: if (i < argc) {
198: if (oc > 1) {
199: unlink (fname);
200: goto closeboth;
201: }
202: goto closein;
203: }
204: else break;
205: }
206: while ((ic - oc) > 21474) {
207: ic /= 10;
208: oc /= 10;
209: }
210: n = 100000 * (ic - oc) / ic + 5;
211: m = (n % 1000) / 10;
212: bits = m % 10 + '0';
213: c . integ = m / 10 + '0';
214: if (i < argc) fprintf (stderr, "%s: ", argv [i]);
215: fprintf (stderr, "Compression : %4ld.%c%c%%\n", n / 1000, c . chars . lob, bits);
216: }
217:
218: if (i >= argc) break;
219: fclose (cfp);
220: unlink (argv [i]);
221: goto closein;
222: closeboth : fclose (cfp);
223: closein : fclose (uncfp);
224: if (i == argc - 1) break;
225: for (j = 256; j--; ) in [j] . flags = 0;
226: continue;
227: fail : fprintf (stderr, "Unsuccessful compact of standard input to standard output.\n");
228: break;
229: }
230: }
231:
232: encode (ch)
233: int ch;
234: {
235:
236: register struct node *pp;
237: register char j;
238: union cio c;
239: int stack [17], stp, stbits;
240:
241: c . integ = ch;
242: stack [stp = 0] = in [c . integ] . flags & FBIT;
243: stbits = 1;
244: pp = in [c . integ] . fp;
245:
246: while (pp -> fath . fp) {
247: stack [stp] <<= 1;
248: if (pp -> fath . flags & FBIT) stack [stp]++;
249: stbits++;
250: if ((stbits &= 017) == 0) stp++;
251: pp = pp -> fath . fp;
252: }
253:
254: /* pop the output stack */
255:
256: for (stp++; stp--; ) {
257: for (j = 0; j < stbits; j++) {
258: d . integ <<= 1;
259: if (stack [stp] & 01) d . integ++;
260: ++bits;
261: if ((bits &= 017) == 0) {
262: putc (d . chars . hib, cfp);
263: putc (d . chars . lob, cfp);
264: if (ferror (cfp)) return;
265: oc += 2;
266: }
267: stack [stp] >>= 1;
268: }
269: stbits = 16;
270: }
271: }
Defined functions
main
defined in line
18;
never used
Defined variables
bits
defined in line
15; used 11 times
d
defined in line
14; used 17 times