Exemplo n.º 1
0
/****************************************************************************
*   Function   : EncodeFile
*   Description: This function uses the provide Huffman tree to encode
*                the file passed as a parameter.
*   Parameters : ht - pointer to root of tree
*                inFile - file to encode
*                outFile - where to output results (NULL -> stdout)
*   Effects    : inFile is encoded and the code plus the results are
*                written to outFile.
*   Returned   : None
****************************************************************************/
void EncodeFile(huffman_node_t *ht, char *inFile, char *outFile)
{
    code_list_t codeList[NUM_CHARS];    /* table for quick encode */
    FILE *fpIn, *fpOut;
    int c, i, bitCount;
    char bitBuffer;

    /* open binary input and output files */
    if ((fpIn = fopen(inFile, "rb")) == NULL)
    {
        perror(inFile);
        exit(EXIT_FAILURE);
    }

    if (outFile == NULL)
    {
        fpOut = stdout;
    }
    else
    {
        if ((fpOut = fopen(outFile, "wb")) == NULL)
        {
            perror(outFile);
            FreeHuffmanTree(ht);
            exit(EXIT_FAILURE);
        }
    }

    WriteHeader(ht, fpOut);         /* write header for rebuilding of tree */
    MakeCodeList(ht, codeList);     /* convert code to easy to use list */

    /* write encoded file 1 byte at a time */
    bitBuffer = 0;
    bitCount = 0;

    while((c = fgetc(fpIn)) != EOF)
    {

        /* shift in bits */
        for(i = 0; i < codeList[c].codeLen; i++)
        {
            bitCount++;
            bitBuffer = (bitBuffer << 1) |
                (TestBit256(codeList[c].code, i) == 1);

            if (bitCount == 8)
            {
                /* we have a byte in the buffer */
                fputc(bitBuffer, fpOut);
                bitCount = 0;
            }
        }
    }

    /* now handle spare bits */
    if (bitCount != 0)
    {
        bitBuffer <<= 8 - bitCount;
        fputc(bitBuffer, fpOut);
    }

    fclose(fpIn);
    fclose(fpOut);
}
Exemplo n.º 2
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;
}