#include <stdio.h>
-typedef unsigned short int t_freq;
+typedef unsigned long int t_freq;
typedef struct t_freqnode {
unsigned short int symbol;
- unsigned short int freq;
+ t_freq freq;
struct t_freqnode *lchild;
struct t_freqnode *rchild;
} HUFFNODE;
typedef struct t_code {
- unsigned short int code;
+ unsigned long int code;
unsigned char codelength;
} CODE;
+void putbit(char bit, char restart, char flush, FILE *fp)
+{
+ static unsigned long int bits_buffer = 0;
+ static unsigned char bits_used = 0;
+
+ /* me obligan a tirar el output */
+ if ((flush == 1) && (bits_used > 0)) {
+ fwrite(&bits_buffer,sizeof(unsigned long int),1,fp);
+ bits_buffer = 0;
+ bits_used = 0;
+ return;
+ }
+ /* me indican que comienza un nuevo output */
+ if (restart) {
+ bits_buffer = 0;
+ bits_used = 0;
+ }
+ /* inserto el bit en el buffer */
+ bits_buffer = bits_buffer << 1;
+ bits_buffer |= bit;
+ bits_used++;
+
+ /* lleno el buffer, escribo */
+ if (bits_used == 32) {
+ fwrite(&bits_buffer,sizeof(unsigned long int),1,fp);
+ bits_buffer = 0;
+ bits_used = 0;
+ }
+ return;
+}
+
void cpynode(HUFFNODE *node1, HUFFNODE *node2)
{
node1->symbol = node2->symbol;
int rescalefreq(t_freq *freqtable)
{
int i;
- int totalfreq = 0;
+ t_freq totalfreq = 0;
/* Divido por la mitad las frecuencias, asegurando de no perder */
/* frequencias en 1, por ello le sumo 1 antes de partir */
for (i = 0; i < 256; i++) {
- freqtable[i] = (freqtable[i]+1)/2;
+ freqtable[i] = (freqtable[i] << 2) | 1;
totalfreq += freqtable[i];
}
{
/* Locals */
FILE *fp;
- int sumfreq = 0,auxsum = 0;
+ t_freq sumfreq = 0;
int i,symbol;
/* Inicializamos la tabla de frecuencias */
++sumfreq;
/* Si llegue al tope de freq acumulada, halve em */
- if (sumfreq == 4181)
+ if (sumfreq == 14930352)
sumfreq = rescalefreq(freqtable);
}
for (i = 0; i < 256; ++i) {
if (codetable[i].codelength > 0) {
auxcode = codetable[i].code;
- printf("Symbol:%i Freq: %i Code:",i,freqtable[i]);
+ printf("Symbol:%i Freq: %li Code:",i,freqtable[i]);
for (j = codetable[i].codelength-1; j >= 0; --j) {
auxcode = codetable[i].code;
auxcode = auxcode >> j;
if (node->symbol < 256) {
/* Guardo el codigo en la tabla */
table[node->symbol].code = code;
- table[node->symbol].codelength = level;
- /*printf("Found symbol %i with freq %i at depth %i\n",node->symbol,node->freq,level);*/
+ table[node->symbol].codelength = level;
}
else {
code = code << 1;
return lastsymbol;
}
+int encode(CODE *table, char* inputfile, char *outputfile) {
+
+ FILE *fpsource,*fpdest;
+ int symbol,i;
+ char bit;
+ CODE symbolcode;
+
+ /* Abrimos el file */
+ if ((fpsource = fopen(inputfile,"rb")) == NULL) return 0;
+ if ((fpdest = fopen(outputfile,"wb")) == NULL) return 0;
+
+ while (!feof(fpsource)) {
+ /* Levanto un symbolo (byte) */
+ symbol = fgetc(fpsource);
+ if (symbol == EOF) continue;
+
+ /* Cargamos el codigo y lo emitimos */
+ symbolcode = table[symbol];
+ for (i = symbolcode.codelength; i > 0; --i) {
+ bit = (symbolcode.code >> (i-1)) & 1;
+ putbit(bit,0,0,fpdest);
+ }
+ }
+
+ /* Hacemos un flush de lo que haya quedado en el buffer de salida */
+ putbit(0,0,1,fpdest);
+ fclose(fpsource);
+ fclose(fpdest);
+ return 1;
+}
+
int main(int argc, char* argv[])
{
/* Locals */
zerocodes(codetable);
buildcodes(codetable,codetree,0,0);
printcodes(codetable,freqtable);
- /*encode(codetable)*/
+ encode(codetable,argv[1],"output.dat");
return 0;
-
}