]> git.llucax.com Git - z.facultad/75.06/jacu.git/blobdiff - src/statichuff/statichuff.c
Reestructuracion
[z.facultad/75.06/jacu.git] / src / statichuff / statichuff.c
index 750351151c9bcd155b40b40d5d3ae3889721235d..e91a367b1bba115a4f763cd417f2d1de9ed7f3cb 100644 (file)
@@ -1,20 +1,51 @@
 
 #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;
@@ -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;
-
 }