AUSAM/source/S/pcat.c
#
/* Expand Huffman coded input to standard output
* Input file format:
* PACKED flag defined below (integer)
* Number of chars in expanded file (float)
* Number of words in expanded tree (integer)
* Tree in 'compressed' form:
* If 0<=byte<=0376, expand by zero padding to left
* If byte=0377, next two bytes for one word
* Terminal nodes: First word is zero; second is character
* Non-terminal nodes: Incremental 0/1 pointers
* Code string for number of characters in expanded file
*/
#define SUF0 '.'
#define SUF1 'z'
#define NNODES 512
struct iobuf
{ int fildes;
int nleft;
char *nextp;
char buf[512];
} buf, obuf;
extern fout;
#define LNAME 80
#define PACKED 017437 /* <US><US> - Unlikely value */
long size;
union {
int hilo[2];
float fsize;
long lsize;
} q;
int tree[1024];
main(argc, argv)
int argc; char *argv[];
{ register int i, k, *t;
int sep, keysize;
char filename[LNAME], *cp;
fout = 2;
obuf.fildes = 1;
obuf.nleft = 512;
obuf.nextp = obuf.buf;
for (k = 1; k<argc; k++)
{ sep = -1; cp = filename;
for (i=0; i < (LNAME-3) && (*cp = argv[k][i]); i++)
if (*cp++ == '/') sep = i;
if (cp[-1]==SUF1 && cp[-2]==SUF0)
{ argv[k][i-2] = '\0'; /* Remove suffix and try again */
k--;
continue;
}
if (i >= (LNAME-3) || (i-sep) > 13)
{ printf ("File name too long -- %s\n",argv[k]);
continue;
}
*cp++ = SUF0; *cp++ = SUF1; *cp = '\0';
if (fopen(filename,&buf) < 0)
{ printf ("Unable to open %s\n", filename);
continue;
}
if (getw(&buf) != PACKED)
{ printf ("Unable to unpack %s\n", filename);
close(buf.fildes);
continue;
}
q.hilo[0] = getw(&buf);
q.hilo[1] = getw(&buf);
if( q.hilo[0] > 040000) /* a float */
size = q.fsize;
else
size = q.lsize; /* a long */
t = tree;
for (keysize = getw(&buf); keysize--; )
{ if ((i = getc(&buf)) == 0377)
*t++ = getw(&buf);
else
*t++ = i;
}
expand();
fflush(&obuf);
close(buf.fildes);
}
}
expand()
{ register int tp, bit, word;
bit = tp = 0;
for (;;)
{ if (bit == 0)
{ word = getw(&buf);
bit = 16;
}
tp =+ tree[tp + (word<0)];
word =<< 1; bit--;
if (tree[tp] == 0)
{ putc(tree[tp+1],&obuf);
tp = 0;
if (--size == 0) return;
}
}
}