Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/****************************************************************************
*   Function   : WriteHeader
*   Description: This function writes the each symbol contained in a tree
*                as well as its number of occurrences in the original file
*                to the specified output file.  If the same algorithm that
*                produced the original tree is used with these counts, an
*                exact copy of the tree will be produced.
*   Parameters : ht - pointer to root of huffman tree
*                bfp - pointer to open binary file to write to.
*   Effects    : Symbol values and symbol counts are written to a file.
*   Returned   : None
****************************************************************************/
static void WriteHeader(huffman_node_t *ht, bit_file_t *bfp)
{
    unsigned int i;

    for(;;)
    {
        /* follow this branch all the way left */
        while (ht->left != NULL)
        {
            ht = ht->left;
        }

        if ((ht->value != COMPOSITE_NODE) &&
                (ht->value != EOF_CHAR))
        {
            /* write symbol and count to header */
            BitFilePutChar(ht->value, bfp);
            BitFilePutBits(bfp, (void *)&(ht->count), 8 * sizeof(count_t));
        }

        while (ht->parent != NULL)
        {
            if (ht != ht->parent->right)
            {
                ht = ht->parent->right;
                break;
            }
            else
            {
                /* parent's right tried, go up one level yet */
                ht = ht->parent;
            }
        }

        if (ht->parent == NULL)
        {
            /* we're at the top with nowhere to go */
            break;
        }
    }

    /* now write end of table char 0 count 0 */
    BitFilePutChar(0, bfp);
    for(i = 0; i < sizeof(count_t); i++)
    {
        BitFilePutChar(0, bfp);
    }
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
/***************************************************************************
*   Function   : main
*   Description: This function demonstrates the usage of each of the bit
*                bit file functions.
*   Parameters : argc - the number command line arguments (not used)
*   Parameters : argv - array of command line arguments (not used)
*   Effects    : Writes bit file, reads back results, printing them to
*                stdout.
*   Returned   : EXIT_SUCCESS
***************************************************************************/
int main(int argc, char *argv[])
{
    bit_file_t *bfp;
    FILE *fp;
    int i, numCalls, value;

    if (argc < 2)
    {
        numCalls = NUM_CALLS;
    }
    else
    {
        numCalls = atoi(argv[1]);
    }

    /* create bit file for writing */
    bfp = BitFileOpen("testfile", BF_WRITE);

    if (bfp == NULL)
    {
         perror("opening file");
         return (EXIT_FAILURE);
    }

    /* write chars */
    value = (int)'A';
    for (i = 0; i < numCalls; i++)
    {
        printf("writing char %c\n", value);
        if(BitFilePutChar(value, bfp) == EOF)
        {
            perror("writing char");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }

        value++;
    }

    /* write single bits */
    value = 0;
    for (i = 0; i < numCalls; i++)
    {
        printf("writing bit %d\n", value);
        if(BitFilePutBit(value, bfp) == EOF)
        {
            perror("writing bit");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }

        value = 1 - value;
    }

    /* write ints as bits */
    value = 0x11111111;
    for (i = 0; i < numCalls; i++)
    {
        printf("writing bits %0X\n", (unsigned int)value);
        if(BitFilePutBits(bfp, &value,
            (unsigned int)(8 * sizeof(int))) == EOF)
        {
            perror("writing bits");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }

        value += 0x11111111;
    }

    /* close bit file */
    if (BitFileClose(bfp) != 0)
    {
         perror("closing file");
         return (EXIT_FAILURE);
    }
    else
    {
        printf("closed file\n");
    }

    /* reopen file for appending */
    bfp = BitFileOpen("testfile", BF_APPEND);

    if (bfp == NULL)
    {
         perror("opening file");
         return (EXIT_FAILURE);
    }

    /* append some chars */
    value = (int)'A';
    for (i = 0; i < numCalls; i++)
    {
        printf("appending char %c\n", value);
        if(BitFilePutChar(value, bfp) == EOF)
        {
            perror("appending char");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }

        value++;
    }

    /* write some bits from an integer */
    value = 0x111;
    for (i = 0; i < numCalls; i++)
    {
        printf("writing 12 bits from an integer %03X\n", (unsigned int)value);
        if(BitFilePutBitsInt(bfp, &value, 12, sizeof(value)) == EOF)
        {
            perror("writing bits from an integer");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }

        value += 0x111;
    }

    /* convert to normal file */
    fp = BitFileToFILE(bfp);

    if (fp == NULL)
    {
         perror("converting to stdio FILE");
         return (EXIT_FAILURE);
    }
    else
    {
        printf("converted to stdio FILE\n");
    }

    /* append some chars */
    value = (int)'a';
    for (i = 0; i < numCalls; i++)
    {
        printf("appending char %c\n", value);
        if(fputc(value, fp) == EOF)
        {
            perror("appending char to FILE");
            if (fclose(fp) == EOF)
            {
                 perror("closing stdio FILE");
            }
            return (EXIT_FAILURE);
        }

        value++;
    }

    /* close file */
    if (fclose(fp) == EOF)
    {
         perror("closing stdio FILE");
         return (EXIT_FAILURE);
    }

    /* now read back writes */

    /* open bit file */
    bfp = BitFileOpen("testfile", BF_READ);

    if (bfp == NULL)
    {
         perror("reopening file");
         return (EXIT_FAILURE);
    }

    /* read chars */
    for (i = 0; i < numCalls; i++)
    {
        value = BitFileGetChar(bfp);
        if(value == EOF)
        {
            perror("reading char");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }
        else
        {
            printf("read %c\n", value);
        }
    }

    /* read single bits */
    for (i = 0; i < numCalls; i++)
    {
        value = BitFileGetBit(bfp);
        if(value == EOF)
        {
            perror("reading bit");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }
        else
        {
            printf("read bit %d\n", value);
        }
    }

    /* read ints as bits */
    for (i = 0; i < numCalls; i++)
    {
        if(BitFileGetBits(bfp, &value, (unsigned int)(8 * sizeof(int))) == EOF)
        {
            perror("reading bits");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }
        else
        {
            printf("read bits %0X\n", (unsigned int)value);
        }
    }

    if (BitFileByteAlign(bfp) == EOF)
    {
        fprintf(stderr, "failed to align file\n");
        if (0 != BitFileClose(bfp))
        {
            perror("closing bitfile");
        }
        return (EXIT_FAILURE);
    }
    else
    {
        printf("byte aligning file\n");
    }

    /* read appended characters */
    for (i = 0; i < numCalls; i++)
    {
        value = BitFileGetChar(bfp);
        if(value == EOF)
        {
            perror("reading char");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }
        else
        {
            printf("read %c\n", value);
        }
    }

    /* read some bits into an integer */
    for (i = 0; i < numCalls; i++)
    {
        value = 0;
        if(BitFileGetBitsInt(bfp, &value, 12, sizeof(value)) == EOF)
        {
            perror("reading bits from an integer");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }
        else
        {
            printf("read 12 bits into an integer %03X\n", (unsigned int)value);
        }
    }

    /* convert to stdio FILE */
    fp = BitFileToFILE(bfp);

    if (fp == NULL)
    {
         perror("converting to stdio FILE");
         return (EXIT_FAILURE);
    }
    else
    {
        printf("converted to stdio FILE\n");
    }

    /* read append some chars */
    value = (int)'a';
    for (i = 0; i < numCalls; i++)
    {
        value = fgetc(fp);
        if(value == EOF)
        {
            perror("stdio reading char");
            if (0 != BitFileClose(bfp))
            {
                perror("closing bitfile");
            }
            return (EXIT_FAILURE);
        }
        else
        {
            printf("stdio read %c\n", value);
        }
    }

    /* close file */
    if (fclose(fp) == EOF)
    {
         perror("closing stdio FILE");
         return (EXIT_FAILURE);
    }

    return(EXIT_SUCCESS);
}