home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
datafiles
/
text
/
drdobb
/
drdobbscompress.lha
/
huffd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-20
|
2KB
|
122 lines
/* HUFFMAN DECODING PROG */
#include <stdio.h>
#include <stdlib.h>
typedef unsigned int BYTECOUNTER;
struct htree {
unsigned char ch;
BYTECOUNTER cnt;
struct htree *parent;
struct htree *right;
struct htree *left;
};
struct htree ht[512];
struct htree *root;
void buildtree(void)
{
int treect = 256;
int i;
while (1) {
struct htree *h1 = NULL, *h2 = NULL;
for (i=0; i<treect; i++) {
if (ht+i != h1) {
if (ht[i].cnt>0 && ht[i].parent == NULL) {
if (h1==NULL || ht[i].cnt<h1->cnt) {
if (h2==NULL || h1->cnt<h2->cnt)
h2 = h1;
h1 = ht+i;
}
else if (h2==NULL || ht[i].cnt <h2->cnt)
h2 = ht+i;
}
}
}
if (h2==NULL) {
root = h1;
break;
}
h1->parent = ht+treect;
h2->parent = ht+treect;
ht[treect].cnt = h1->cnt + h2->cnt;
ht[treect].right = h1;
ht[treect].left = h2;
treect++;
}
}
static int decompress(FILE *fi,struct htree *root);
void main(int argc,char *argv[])
{
FILE *fi,*fo;
unsigned char c;
BYTECOUNTER bytectr;
int count;
if (argc < 3) {
printf("usage: huffd infile outfile\n");
exit(1);
}
if ((fi=fopen(argv[1],"rb"))==NULL) {
printf("Cannot open input file %s\n",argv[1]);
exit(1);
}
if ((fo=fopen(argv[2],"wb"))==NULL) {
printf("Cannot open output file %s\n",argv[2]);
exit(1);
}
fread(&bytectr,sizeof bytectr,1,fi);
for (count=0;count<256;count++) {
c=fgetc(fi);
ht[count].cnt=(BYTECOUNTER)c;
#ifdef DEBUG
fprintf(stderr," %3u",ht[count].cnt);
#endif
ht[count].ch=count;
}
buildtree();
while (bytectr--)
fputc(decompress(fi,root),fo);
fclose(fo);
fclose(fi);
}
static int in8;
static int ct8 = 8;
static int inbit(FILE *fi)
{
int obit;
if (ct8==8) {
in8 = fgetc(fi);
ct8 = 0;
}
obit = in8 & 0x80;
in8 <<= 1;
ct8++;
return obit;
}
static int decompress(FILE *fi,struct htree *h)
{
while (h->right != NULL)
if (inbit(fi))
h = h->left;
else
h = h->right;
return h->ch;
}