int CHuffmanEncode(struct CHuffman *ch) { bit_file_t bfpOut; int i; unsigned char c; bfpOut.buf = ch->outBuf; bfpOut.bufLen = ch->outLen; bfpOut.mode = BF_WRITE; BitFileInit(&bfpOut); /* read characters from file and write them to encoded file */ for (i = 0; i < ch->inLen; i++) { c = ch->inBuf[i]; /* write encoded symbols */ if (BitFilePutBits(&bfpOut, BitArrayGetBits(ch->canonicalList[c].code), ch->canonicalList[c].codeLen) == EOF) { fprintf(stderr, "buffer full writing\n"); exit(1); } } /* now write EOF */ if (BitFilePutBits(&bfpOut, BitArrayGetBits(ch->canonicalList[EOF_CHAR].code), ch->canonicalList[EOF_CHAR].codeLen) == EOF) { fprintf(stderr, "buffer full writing\n"); exit(1); } /* clean up */ BitFileClose(&bfpOut); ch->outIndex = bfpOut.bufPos; return 0; }
/**************************************************************************** * Function : HuffmanEncodeFile * Description: This routine genrates a huffman tree optimized for a file * and writes out an encoded version of that file. * Parameters : inFile - Open file pointer for file to encode (must be * rewindable). * outFile - Open file pointer for file receiving encoded data * Effects : File is Huffman encoded * Returned : 0 for success, -1 for failure. errno will be set in the * event of a failure. Either way, inFile and outFile will * be left open. ****************************************************************************/ int HuffmanEncodeFile(FILE *inFile, FILE *outFile) { huffman_node_t *huffmanTree; /* root of huffman tree */ code_list_t codeList[NUM_CHARS]; /* table for quick encode */ bit_file_t *bOutFile; int c; /* validate input and output files */ if ((NULL == inFile) || (NULL == outFile)) { errno = ENOENT; return -1; } bOutFile = MakeBitFile(outFile, BF_WRITE); if (NULL == bOutFile) { perror("Making Output File a BitFile"); return -1; } /* build tree */ if ((huffmanTree = GenerateTreeFromFile(inFile)) == NULL) { outFile = BitFileToFILE(bOutFile); return -1; } /* build a list of codes for each symbol */ /* initialize code list */ for (c = 0; c < NUM_CHARS; c++) { codeList[c].code = NULL; codeList[c].codeLen = 0; } if (0 != MakeCodeList(huffmanTree, codeList)) { outFile = BitFileToFILE(bOutFile); return -1; } /* write out encoded file */ /* write header for rebuilding of tree */ WriteHeader(huffmanTree, bOutFile); /* read characters from file and write them to encoded file */ rewind(inFile); /* start another pass on the input file */ while((c = fgetc(inFile)) != EOF) { BitFilePutBits(bOutFile, BitArrayGetBits(codeList[c].code), codeList[c].codeLen); } /* now write EOF */ BitFilePutBits(bOutFile, BitArrayGetBits(codeList[EOF_CHAR].code), codeList[EOF_CHAR].codeLen); /* free the code list */ for (c = 0; c < NUM_CHARS; c++) { if (codeList[c].code != NULL) { BitArrayDestroy(codeList[c].code); } } /* clean up */ outFile = BitFileToFILE(bOutFile); /* make file normal again */ FreeHuffmanTree(huffmanTree); /* free allocated memory */ return 0; }