From: Alan Kennedy Date: Sat, 19 Jun 2004 05:33:28 +0000 (+0000) Subject: Encodeo, pero me falta guardar la de frecuencias, y ver como marco el fin de archivo... X-Git-Tag: svn_import~156 X-Git-Url: https://git.llucax.com/z.facultad/75.06/jacu.git/commitdiff_plain/4620669a5d0ff5d3d07d1bec9d04f9b09a9cda16?ds=sidebyside;hp=c85503d1a07d56f61d4fb85696212118c0c470cd Encodeo, pero me falta guardar la de frecuencias, y ver como marco el fin de archivo, es decir como hago el output del ultimo buffer de 32 bits que es lo que utilizo para hacer output de bits (se va llenando y cuando se llena se emite. Al fin del archivo, se fuerza un flush de lo que haya dentro). Sidenote: Ahora los codigos son maximo 32 bits, con 16 bits andaba para atras, igualmente no se si esta encodeando joya, pero al menos comprime y no expande. Limo los detalles y me mando con el decompresor que es bastante zonzo asi encuentro la verdad Scully --- diff --git a/src/statichuff/statichuff.c b/src/statichuff/statichuff.c index 7503511..e91a367 100644 --- a/src/statichuff/statichuff.c +++ b/src/statichuff/statichuff.c @@ -1,20 +1,51 @@ #include -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; @@ -56,12 +87,12 @@ HUFFNODE *buildlist(t_freq *freqtable, int *nonzerofreqs) 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]; } @@ -72,7 +103,7 @@ int scanfreq(char *inputfile, t_freq *freqtable) { /* Locals */ FILE *fp; - int sumfreq = 0,auxsum = 0; + t_freq sumfreq = 0; int i,symbol; /* Inicializamos la tabla de frecuencias */ @@ -89,7 +120,7 @@ int scanfreq(char *inputfile, t_freq *freqtable) ++sumfreq; /* Si llegue al tope de freq acumulada, halve em */ - if (sumfreq == 4181) + if (sumfreq == 14930352) sumfreq = rescalefreq(freqtable); } @@ -106,7 +137,7 @@ void printcodes(CODE *codetable,t_freq *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; @@ -134,8 +165,7 @@ void buildcodes(CODE *table, HUFFNODE *node, int level, int code) 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; @@ -172,6 +202,37 @@ HUFFNODE *buildtree(HUFFNODE *list, int listcount) 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 */ @@ -193,8 +254,7 @@ int main(int argc, char* argv[]) zerocodes(codetable); buildcodes(codetable,codetree,0,0); printcodes(codetable,freqtable); - /*encode(codetable)*/ + encode(codetable,argv[1],"output.dat"); return 0; - }