]> git.llucax.com Git - z.facultad/75.06/jacu.git/commitdiff
Listo Huffman Canonico, con dos nuevos parametros s y m se permite grabar una tabla...
authorAlan Kennedy <kennedya@3dgames.com.ar>
Wed, 23 Jun 2004 22:24:07 +0000 (22:24 +0000)
committerAlan Kennedy <kennedya@3dgames.com.ar>
Wed, 23 Jun 2004 22:24:07 +0000 (22:24 +0000)
src/statichuff/main.c
src/statichuff/main_bychunk.c
src/statichuff/statichuff.c
src/statichuff/statichuff.h

index d7200bb5aeddacd1448957ce30aa13ea61603462..ebb711588504e5ce89ad8347f7ef7183be557552 100644 (file)
@@ -7,11 +7,14 @@ int main(int argc, char* argv[])
        int cflag = 0;
        int dflag = 0;
        int tflag = 0;
+       int mflag = 0;
+       int sflag = 0;
        long int volumesize = 0;
        int ch;
        HUFF_STATE *shuff;
+       char *staticmodel = NULL;
                        
-       while ((ch = getopt(argc, argv, "cdt:")) != -1) { 
+       while ((ch = getopt(argc, argv, "scdm:t:")) != -1) { 
                 
                switch (ch) { 
                        case 'c': cflag = 1; 
@@ -24,13 +27,20 @@ int main(int argc, char* argv[])
                                          volumesize = atoi(optarg);                                      
                                          break; 
                        
-                       default: fprintf(stderr, "Usage: %s [-cdt] sourcefile targetfile\n", argv[0]); 
+                       case 'm': mflag = 1;
+                                         staticmodel = optarg;
+                                         break; 
+                       
+                       case 's': sflag = 1;                                      
+                                         break;
+                       
+                       default: fprintf(stderr, "Usage: %s [-cds] [-t volsizekb] sourcefile targetfile [-m modeldumpfile]\n", argv[0]); 
                                         return(2);
                }
        }
                
        if ( (argc == 1) || (cflag & dflag) || !(cflag | dflag) || ((argc - optind) < 2) ) {
-               fprintf(stderr, "Usage: %s [-cdt] sourcefile targetfile\n", argv[0]); 
+               fprintf(stderr, "Usage: %s [-cds] [-t volsizekb] sourcefile targetfile [-m modeldumpfile]\n", argv[0]); 
                if ((tflag == 1) && (volumesize < 0)) fprintf(stderr,"Error: The volume size must be a non-zero value\n");
                return (2);             
        }
@@ -38,7 +48,9 @@ int main(int argc, char* argv[])
        if (cflag == 1) {
                /* Comprimo */
                shuff = shuff_init_encoder_byfile(argv[optind],argv[optind+1],volumesize*1024);
+               if (mflag == 1) shuff_loadmodel(shuff,staticmodel);
            shuff_encode_file(shuff);
+               if (sflag == 1) shuff_savemodel(shuff);
                shuff_deinit_encoder(shuff);
                free(shuff);
        }
index 12f8028ef5a06d3d506f1e45753bdc16572df44c..f2fca8678b8ce371aa8538e8c9c221d97a2146c1 100644 (file)
@@ -10,10 +10,13 @@ int main(int argc, char* argv[])
        int cflag = 0;
        int dflag = 0;
        int tflag = 0;
+       int sflag = 0;
+       int mflag = 0;
        long int volumesize = 0;
        int lastchunk,i,j,ch,decoded = 0;
+       char *staticmodel;
                        
-       while ((ch = getopt(argc, argv, "cdt:")) != -1) { 
+       while ((ch = getopt(argc, argv, "scdm:t:")) != -1) { 
                 
                switch (ch) { 
                        case 'c': cflag = 1; 
@@ -26,13 +29,20 @@ int main(int argc, char* argv[])
                                          volumesize = atoi(optarg);                                      
                                          break; 
                        
-                       default: fprintf(stderr, "Usage: %s [-cdt] sourcefile targetfile\n", argv[0]); 
+                       case 'm': mflag = 1;
+                                         staticmodel = optarg;
+                                         break; 
+                       
+                       case 's': sflag = 1;                                      
+                                         break;
+                       
+                       default: fprintf(stderr, "Usage: %s [-cds] [-t volsizekb] sourcefile targetfile [-m modeldumpfile]\n", argv[0]); 
                                         return(2);
                }
        }
                
-       if ( (argc == 1) || (cflag & dflag) || !(cflag | dflag) || ((argc - optind) < 2) ) {
-               fprintf(stderr, "Usage: %s [-cdt] sourcefile targetfile\n", argv[0]); 
+       if ( (argc == 1) || (cflag & dflag) || !(cflag | dflag) || ((argc - optind) < 2) || (mflag & sflag)) {
+               fprintf(stderr, "Usage: %s [-cds] [-t volsizekb] sourcefile targetfile [-m modeldumpfile]\n", argv[0]); 
                if ((tflag == 1) && (volumesize < 0)) fprintf(stderr,"Error: The volume size must be a non-zero value\n");
                return (2);             
        }
@@ -40,6 +50,7 @@ int main(int argc, char* argv[])
        if (cflag == 1) {
                /* Inicio un compresor huffman estatico por chunks */
                if ((shuff = shuff_init_encoder_bychunk(argv[optind+1],volumesize*1024)) == NULL) return 0;
+               if (mflag == 1) shuff_loadmodel(shuff,staticmodel);
                
                /* Comprimo por chunks */               
                if ((fp = fopen(argv[optind],"rb")) == NULL) return 1;          
@@ -56,7 +67,8 @@ int main(int argc, char* argv[])
                        shuff_scanfreq_chunk(shuff,chunk,i);                    
                }
                /* Le indico al huffman que efectivamente comprima los chunks */
-               shuff_encode_file(shuff);
+               shuff_encode_file(shuff);               
+               if (sflag == 1) shuff_savemodel(shuff);         
                
                /* De init encoder */
                shuff_deinit_encoder(shuff);
index 2e2764ac351ac9ca5b95a1bdf5ce40120b3a59f1..000f0bab7f1c0820f1555f75e420c2d172e19d32 100644 (file)
@@ -70,15 +70,17 @@ int shuff_scanfreq_chunk(HUFF_STATE *chunkshuff, char* chunk, int chunksize)
        int i = 0;
        unsigned char symbol = 0;       
                
-       /* Contamos las frecuencias del chunk*/ 
-       for (i = 0; i < chunksize; ++i) {                               
-               symbol = chunk[i];              
-               chunkshuff->freqtable[symbol] += 1;
-               chunkshuff->sumfreq += 1;
+       /* Contamos las frecuencias del chunk a menos que se use un canonico */ 
+       if (!chunkshuff->canonic) {
+               for (i = 0; i < chunksize; ++i) {                               
+                       symbol = chunk[i];              
+                       chunkshuff->freqtable[symbol] += 1;
+                       chunkshuff->sumfreq += 1;
                                
-               /* Si llegue al tope de freq acumulada, halve em */
-               if (chunkshuff->sumfreq == 14930352) 
-                       chunkshuff->sumfreq = shuff_rescalefreq(chunkshuff->freqtable);
+                       /* Si llegue al tope de freq acumulada, halve em */
+                       if (chunkshuff->sumfreq == 14930352) 
+                               chunkshuff->sumfreq = shuff_rescalefreq(chunkshuff->freqtable);
+               }
        }
        
        /* Dumpeamos el chunk en el temporal homero */
@@ -273,7 +275,8 @@ int shuff_encode_file(HUFF_STATE *shuff)
        SHUFFCODE *codetable = (SHUFFCODE*)malloc(sizeof(SHUFFCODE)*256);
        
        /* Veo si debo armar una freqtable o si esta preloaded */
-       if (!shuff->preloadfreq) if (!shuff_scanfreq(shuff->sourcefile,shuff->freqtable)) return 0;
+       if ((!shuff->canonic) && (!shuff->bychunk)) 
+               if (!shuff_scanfreq(shuff->sourcefile,shuff->freqtable)) return 0;
        
        /* Genero el arbol de huffman */
        shuff->codetree = shuff_buildtree(shuff->freqtable);
@@ -396,7 +399,7 @@ HUFF_STATE *shuff_init_decoder(char *inputfile, char *outputfile)
        /* Levanto cuantos bytes debo decodificar y la freqtable */
        if ((shuff->decoderfp = vfopen(shuff->sourcefile,"r",0)) == NULL) return NULL;  
        vfread(&(shuff->bytesleft),sizeof(unsigned long int),1,shuff->decoderfp);
-       vfread(shuff->freqtable,sizeof(unsigned long int),256,shuff->decoderfp);                
+       vfread(shuff->freqtable,sizeof(t_freq),256,shuff->decoderfp);           
        /* Armo el arbol de huffman que uso para decodificar */
        shuff->codetree = shuff_buildtree(shuff->freqtable);
        
@@ -418,7 +421,7 @@ HUFF_STATE *shuff_init_encoder_byfile(char *inputfile, char *outputfile, long vo
        strcpy(fshuff->targetfile,outputfile);
        fshuff->volsize = volsize;
        fshuff->bychunk = 0;
-       fshuff->preloadfreq = 0;        
+       fshuff->canonic = 0;    
        fshuff->freqtable = (t_freq*)malloc(sizeof(t_freq)*256);
        for (i = 0; i < 256; ++i) fshuff->freqtable[i] = 0;     
        fshuff->sumfreq = 0;            
@@ -442,7 +445,7 @@ HUFF_STATE *shuff_init_encoder_bychunk(char *outputfile, long volsize)
        strcat(cshuff->sourcefile,"~"); 
        cshuff->volsize = volsize;
        cshuff->bychunk = 1;
-       cshuff->preloadfreq = 1;                
+       cshuff->canonic = 0;
        cshuff->freqtable = (t_freq*)malloc(sizeof(t_freq)*256);        
        for (i = 0; i < 256; ++i) cshuff->freqtable[i] = 0;     
        cshuff->sumfreq = 0;    
@@ -454,6 +457,45 @@ HUFF_STATE *shuff_init_encoder_bychunk(char *outputfile, long volsize)
        return cshuff;
 }
 
+int shuff_loadmodel(HUFF_STATE *shuff, char *modelfile) {
+
+       FILE *fp;
+       
+       if ((shuff) && (shuff->freqtable) && (modelfile)) {
+               /* Cargo el modelo de disco */
+               if ((fp = fopen(modelfile,"r")) == NULL) return 0;
+               if (fread(shuff->freqtable,sizeof(t_freq),256,fp) != 256) return 0;
+               shuff->canonic = 1;
+               if (fp) fclose(fp);             
+               return 1;
+       }       
+       return 0;       
+}
+
+int shuff_savemodel(HUFF_STATE *shuff) {
+
+       FILE *fp;
+       char *auxfilename;
+       char *stopchar;
+       
+       if ((shuff) && (shuff->targetfile) && (shuff->freqtable)) {
+               /* Preparo el nombre del archivo con la tabla */
+               auxfilename = (char*)malloc(strlen(shuff->targetfile)+1);               
+               stopchar = strrchr(shuff->targetfile,'.');              
+               strncpy(auxfilename,shuff->targetfile,stopchar - shuff->targetfile);
+               auxfilename[stopchar - shuff->targetfile] = 0;
+               strcat(auxfilename,".ftb");
+               
+               /* Lo creamos y dumpeamos la tabla de frecuencias (modelo) */
+               if ((fp = fopen(auxfilename,"w")) == NULL) return 0;
+               fwrite(shuff->freqtable,sizeof(t_freq),256,fp);
+               if (fp) fclose(fp);
+                               
+               return 1;
+       }       
+       return 0;
+}
+
 void shuff_deinit_encoder(HUFF_STATE *shuff)
 {
        /* Libero mallocs y cierro archivos */
index 2ae1a60ab8cf96538fbf2b19736a8f42431026ae..97e8f4cc2026c2488397066201c6649c66993ed5 100644 (file)
@@ -27,7 +27,7 @@ typedef struct t_huff {
        char *targetfile; /* Nombre del archivo comprimido */
        long volsize; /* Tamanio de volumen para multivol */
        char bychunk; /* 0 works byfile, 1 works bychunk */
-       char preloadfreq; /* 1 Freqtable has been preloaded (bychunk | canonic) */
+       char canonic; /* 1 Huffman Canonico con preloaded freqtable */
        t_freq *freqtable; /* Tabla de frecuencias */
        t_freq sumfreq; /* Frecuencia total acumulada */
        SHUFFNODE *codetree; /* Puntero al arbol de codigos prefijos */         
@@ -44,5 +44,9 @@ void shuff_deinit_encoder(HUFF_STATE *shuff);
 void shuff_deinit_decoder(HUFF_STATE *shuff);
 int shuff_encode_file(HUFF_STATE *shuff);
 int shuff_decode_file(HUFF_STATE *shuff);
+int shuff_scanfreq_chunk(HUFF_STATE *chunkshuff, char* chunk, int chunksize);
+int shuff_decode_chunk(HUFF_STATE *shuff, char *chunk, int chunksize, int *decodedbytes);
+int shuff_savemodel(HUFF_STATE *shuff);
+int shuff_loadmodel(HUFF_STATE *shuff, char *modelfile);
 
 #endif /* _STATICHUFF_H_ */