/* huffenc.c - Don Yang (uguu.org) 09/13/01 */ #include #include #include #include #include #include"hufftree.h" struct { unsigned char bit[HUFFMAN_TREE_DEPTH]; int length; } Table[256]; static void HuffmanEncode(FILE *infile, FILE *outfile, int size); static void InitTable(void); static void InitTableEntries(int index, char *string); static void SetEntry(int index, char *string, int length); /******************************************************************** main */ int main(int argc, char **argv) { FILE *infile, *outfile; struct stat info; int size; InitTable(); if( argc < 3 ) return printf("%s \n", *argv); if( stat(argv[1], &info) ) return printf("Can not stat %s\n", argv[1]); size = (int)info.st_size; if( (infile = fopen(argv[1], "rb")) == NULL ) return printf("Can not open %s\n", argv[1]); if( (outfile = fopen(argv[2], "wb+")) == NULL ) { fclose(infile); return printf("Can not create %s\n", argv[2]); } fwrite(&size, sizeof(int), 1, outfile); HuffmanEncode(infile, outfile, size); fclose(infile); fclose(outfile); return 0; } /* main() */ /*********************************************************** HuffmanEncode */ static void HuffmanEncode(FILE *infile, FILE *outfile, int size) { int bit, byte, c, i, j; for(i = bit = byte = 0; i < size && (c = fgetc(infile)) != EOF; i++) { for(j = 0; j < Table[c].length; j++) { byte |= ((unsigned)Table[c].bit[j]) << (bit++); if( bit > 7 ) { fputc(byte, outfile); bit = byte = 0; } } } if( bit > 0 ) fputc(byte, outfile); } /* HuffmanEncode() */ /*************************************************************** InitTable */ static void InitTable(void) { char string[HUFFMAN_TREE_DEPTH]; string[0] = 0; InitTableEntries(0, string); } /* InitTable() */ /******************************************************** InitTableEntries */ static void InitTableEntries(int index, char *string) { size_t x; int i; x = strlen(string); string[x] = 1; string[x + 1] = 0; if( (i = Left[index]) <= 0 ) SetEntry(-i, string, x + 1); else InitTableEntries(i, string); string[x] = 2; if( (i = Right[index]) <= 0 ) SetEntry(-i, string, x + 1); else InitTableEntries(i, string); string[x] = 0; } /* InitTableEntries() */ /**************************************************************** SetEntry */ static void SetEntry(int index, char *string, int length) { int i; Table[index].length = length; for(i = 0; i < length; i++) Table[index].bit[i] = (unsigned char)(string[i] - 1); } /* SetEntry() */