1*14544Ssam #ifndef lint
2*14544Ssam static char sccsid[] = "@(#)uncompact.c	4.4 (Berkeley) 08/11/83";
3*14544Ssam #endif
4*14544Ssam 
510922Sshannon /*
610922Sshannon  *  Uncompact adaptive Huffman code input to output
710922Sshannon  *
810922Sshannon  *  On - line algorithm
910922Sshannon  *
1010922Sshannon  *  Input file does not contain decoding tree
1110922Sshannon  *
1210922Sshannon  *  Written by Colin L. Mc Master (UCB) February 14, 1979
1310922Sshannon  */
1410922Sshannon 
1510922Sshannon #include "compact.h"
1610922Sshannon 
1710922Sshannon 
1810922Sshannon main (argc, argv)
1910922Sshannon short argc;
2010922Sshannon char *argv [ ];
2110922Sshannon {
2210922Sshannon 	register short i;
2310922Sshannon 	register struct node *p;
2410922Sshannon 	register short j;
2510922Sshannon 	register int m;
2610922Sshannon 	union cio c, d;
2710922Sshannon 	char b;
2810922Sshannon 	longint ic, n;
2910922Sshannon 	char fname [LNAME], *cp;
3010922Sshannon 
3110922Sshannon 	dir [513] . next = NULL;
3210922Sshannon 	for (head = dir + (j = 513); j--; ) {
3310922Sshannon 		dirp = head--;
3410922Sshannon 		head -> next = dirp;
3510922Sshannon 	}
3610922Sshannon 	bottom = dirp -> pt = dict;
3710922Sshannon 	dict [0] . top [0] = dict [0] . top [1] = dirp;
3810922Sshannon 	dirq = dirp -> next;
3910922Sshannon 	in [EF] . flags = FBIT | SEEN;
4010922Sshannon 
4110922Sshannon 	for (i = 1; ; i++) {
4210922Sshannon 		ic = oc = 0;
4310922Sshannon 		(bottom -> top [1]) -> next = flist;
4410922Sshannon 		bottom -> top [1] = dirp;
4510922Sshannon 		flist = dirq;
4610922Sshannon 		if (i >= argc) {
4710922Sshannon 			uncfp = stdout;
4810922Sshannon 			cfp = stdin;
4910922Sshannon 		}
5010922Sshannon 		else {
5110922Sshannon 			m = -1;
5210922Sshannon 			cp = fname;
5310922Sshannon 			for (j = 0; j < (LNAME - 3) && (*cp = argv [i][j]); j++)
5410922Sshannon 				if (*cp++ == '/') m = j;
5510922Sshannon 			if (cp [-1] == 'C' && cp [-2] == '.') cp [-2] = 0;
5610922Sshannon 			else {
5710922Sshannon 				fprintf (stderr, "%s: File name must end with \".C\"\n", argv [i]);
5810922Sshannon 				if (i == argc - 1) break;
5910922Sshannon 				continue;
6010922Sshannon 			}
6112903Sedward 			if (j >= (LNAME - 3) || (j - m) > MAXNAMLEN) {
6210922Sshannon 				fprintf (stderr, "File name too long -- %s\n", argv [i]);
6310922Sshannon 				if (i == argc - 1) break;
6410922Sshannon 				continue;
6510922Sshannon 			}
6610922Sshannon 			if ((cfp = fopen (argv [i], "r")) == NULL) {
6710922Sshannon 				perror (argv [i]);
6810922Sshannon 				if (i == argc - 1) break;
6910922Sshannon 				continue;
7010922Sshannon 			}
7110922Sshannon 			if ((uncfp = fopen (fname, "w")) == NULL) {
7210922Sshannon 				perror (fname);
7310922Sshannon 				fclose (cfp);
7410922Sshannon 				if (i == argc - 1) break;
7510922Sshannon 				continue;
7610922Sshannon 			}
7710922Sshannon 			fstat (fileno (cfp), &status);
7810922Sshannon 			chmod (fname, status.st_mode & 07777);
7910922Sshannon 		}
8010922Sshannon 
8110922Sshannon 		if ((c . integ = getc (cfp)) != EOF) {
8210922Sshannon 			if ((d . integ = getc (cfp)) != EOF) {
8310922Sshannon 				c . chars . hib = d . integ & 0377;
8410922Sshannon 				c . integ &= 0177777;
8510922Sshannon 				if (c . integ != COMPACTED) goto notcompact;
8610922Sshannon 				if ((c . integ = getc (cfp)) != EOF) {
8710922Sshannon 					putc (c . chars . lob, uncfp);
8810922Sshannon 					ic = 3;
8910922Sshannon 
9010922Sshannon 					in [NC] . fp = in [EF] . fp = dict [0] . sp [0] . p = bottom = dict + 1;
9110922Sshannon 					bottom -> count [0] = bottom -> count [1] = dict [0] . count [1] = 1;
9210922Sshannon 					dirp -> next = dict [0] . top [1] = bottom -> top [0] = bottom -> top [1] = dirq = NEW;
9310922Sshannon 					dirq -> next = NULL;
9410922Sshannon 					dict [0] . fath . fp = NULL;
9510922Sshannon 					dirq -> pt = bottom -> fath . fp = in [c . integ] . fp = dict;
9610922Sshannon 					in [c . integ] . flags = (FBIT | SEEN);
9710922Sshannon 					in [NC] . flags = SEEN;
9810922Sshannon 					dict [0] . fath . flags = RLEAF;
9910922Sshannon 					bottom -> fath . flags = (LLEAF | RLEAF);
10010922Sshannon 					dict [0] . count [0] = 2;
10110922Sshannon 
10210922Sshannon 					dict [0] . sp [1] . ch = c . integ;
10310922Sshannon 					bottom -> sp [0] . ch = NC;
10410922Sshannon 					bottom -> sp [1] . ch = EF;
10510922Sshannon 
10610922Sshannon 					p = dict;
10710922Sshannon 					while ((c . integ = getc (cfp)) != EOF) {
10810922Sshannon 						ic++;
10910922Sshannon 						for (m = 0200; m; ) {
11010922Sshannon 							b = (m & c . integ ? 1 : 0);
11110922Sshannon 							m >>= 1;
11210922Sshannon 							if (p -> fath . flags & (b ? RLEAF : LLEAF)) {
11310922Sshannon 								d . integ = p -> sp [b] . ch;
11410922Sshannon 								if (d . integ == EF) break;
11510922Sshannon 								if (d . integ == NC) {
11610922Sshannon 									uptree (NC);
11710922Sshannon 									d . integ = 0;
11810922Sshannon 									for (j = 8; j--; m >>= 1) {
11910922Sshannon 										if (m == 0) {
12010922Sshannon 											c . integ = getc (cfp);
12110922Sshannon 											ic++;
12210922Sshannon 											m = 0200;
12310922Sshannon 										}
12410922Sshannon 										d . integ <<= 1;
12510922Sshannon 										if (m & c . integ) d . integ++;
12610922Sshannon 									}
12710922Sshannon 									insert (d . integ);
12810922Sshannon 								}
12910922Sshannon 								uptree (d . integ);
13010922Sshannon 								putc (d . chars . lob, uncfp);
13110922Sshannon 								oc++;
13210922Sshannon 								p = dict;
13310922Sshannon 							}
13410922Sshannon 							else p = p -> sp [b] . p;
13510922Sshannon 						}
13610922Sshannon 					}
13710922Sshannon 				}
13810922Sshannon 			}
13910922Sshannon 			else goto notcompact;
14010922Sshannon 		}
14110922Sshannon 		else {
14210922Sshannon 			notcompact : if (i < argc) {
14310922Sshannon 					     fprintf (stderr, "%s: ", argv [i]);
14410922Sshannon 					     unlink (fname);
14510922Sshannon 				     }
14610922Sshannon 				     if (c . integ == PACKED) fprintf (stderr, "File is packed. Use unpack.\n");
14710922Sshannon 				     else fprintf (stderr, "Not a compacted file.\n");
14810922Sshannon 				     if (i >= argc) break;
14910922Sshannon 				     goto closeboth;
15010922Sshannon 		}
15110922Sshannon 
15210922Sshannon 		if (ferror (uncfp) || ferror (cfp))
15310922Sshannon 			if (i < argc) {
15410922Sshannon 				if (ferror (uncfp))
15510922Sshannon 					perror (fname);
15610922Sshannon 				else
15710922Sshannon 					perror (argv [i]);
15810922Sshannon 				fprintf (stderr, "Unable to uncompact %s\n", argv [i]);
15910922Sshannon 				unlink (fname);
16010922Sshannon 				goto closeboth;
16110922Sshannon 			}
16210922Sshannon 			    if (i >= argc) break;
16310922Sshannon 			    fprintf (stderr, "%s uncompacted to %s\n", argv [i], fname);
16410922Sshannon 			    unlink (argv [i]);
16510922Sshannon 		closeboth : fclose (cfp);
16610922Sshannon 		closein   : fclose (uncfp);
16710922Sshannon 			    if (i == argc - 1) break;
16810922Sshannon 			    for (j = 256; j--; ) in [j] . flags = 0;
16910922Sshannon 			    continue;
17010922Sshannon 		fail 	  : fprintf (stderr, "Unsuccessful uncompact of standard input to standard output.\n");
17110922Sshannon 		            break;
17210922Sshannon 	}
17310922Sshannon }
174