1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/* FreeDOS Edit Help Compiler
Part of the FreeDOS Project
Originally part of D-Flat, by Dr. Dobbs Journal
Modified by Joe Cosentino 2002.
*/
/* I N C L U D E S /////////////////////////////////////////////////////// */
#include "dflat.h"
#include "htree.h"
/* G L O B A L S ///////////////////////////////////////////////////////// */
extern struct htree *ht;
extern int root;
extern int treect;
static int lastchar='\n';
static int ct8;
static char out8;
/* P R O T O T Y P E S /////////////////////////////////////////////////// */
static void compress(FILE *, int, int);
static void outbit(FILE *, int);
/* F U N C T I O N S ///////////////////////////////////////////////////// */
static int fgetcx(FILE *fi)
{
int c;
/* Bypass comments */
if ((c=fgetc(fi))==';' && lastchar=='\n')
do
{
while (c != '\n' && c != EOF)
c=fgetc(fi);
}
while (c==';');
lastchar=c;
return c;
}
/* Compress a character value into a bit stream */
static void compress(FILE *fo, int h, int child)
{
if (ht[h].parent != -1)
compress(fo, ht[h].parent, h);
if (child)
{
if (child == ht[h].right)
outbit(fo, 0);
else if (child == ht[h].left)
outbit(fo, 1);
}
}
/* Collect and write bits to the compressed output file */
static void outbit(FILE *fo, int bit)
{
if (ct8==8 || bit==-1)
{
while (ct8<8)
{
out8 <<= 1;
ct8++;
}
fputc(out8, fo);
ct8=0;
}
out8=(out8 << 1) | bit;
ct8++;
}
void main(int argc, char *argv[])
{
FILE *fi, *fo;
int c;
BYTECOUNTER bytectr = 0;
if (argc < 3)
{
printf("Syntax: HUFFC infile outfile\n");
exit(1);
}
if ((fi = fopen(argv[1], "rb")) == NULL)
{
printf("Cannot open %s\n", argv[1]);
exit(1);
}
if ((fo = fopen(argv[2], "wb")) == NULL)
{
printf("Cannot open %s\n", argv[2]);
fclose(fi);
exit(1);
}
ht = calloc(256, sizeof(struct htree));
/* Read the input file and count character frequency */
while ((c = fgetcx(fi)) != EOF)
{
c &= 255;
ht[c].cnt++;
bytectr++;
}
/* Build the huffman tree */
buildtree();
/* Write the byte count to the output file */
fwrite(&bytectr, sizeof bytectr, 1, fo);
/* Write the tree count to the output file */
fwrite(&treect, sizeof treect, 1, fo);
/* Write the root offset to the output file */
fwrite(&root, sizeof root, 1, fo);
/* Write the tree to the output file */
for (c=256;c<treect;c++)
{
int lf=ht[c].left,rt=ht[c].right;
fwrite(&lf, sizeof lf, 1, fo);
fwrite(&rt, sizeof rt, 1, fo);
}
/* Compress the file */
fseek(fi, 0L, 0);
while ((c = fgetcx(fi)) != EOF)
compress(fo, (c & 255), 0);
outbit(fo, -1);
fclose(fi);
fclose(fo);
free(ht);
exit(0);
}
|