From 4ca9e227315aa797216a3eb0ea7d72e9db203143 Mon Sep 17 00:00:00 2001 From: Alan Kennedy Date: Wed, 23 Jun 2004 06:34:38 +0000 Subject: [PATCH 1/1] Safe upload, minimo cambio de nuevo al API, still working on decompression per chunk --- src/statichuff/main.c | 8 +- src/statichuff/main_bychunk.c | 2 +- src/statichuff/statichuff.c | 223 ++++++++++++++++++---------------- src/statichuff/statichuff.h | 20 +-- 4 files changed, 131 insertions(+), 122 deletions(-) diff --git a/src/statichuff/main.c b/src/statichuff/main.c index 65a1c3d..d7200bb 100644 --- a/src/statichuff/main.c +++ b/src/statichuff/main.c @@ -37,17 +37,17 @@ int main(int argc, char* argv[]) if (cflag == 1) { /* Comprimo */ - shuff = shuff_init_static_byfile(argv[optind],argv[optind+1],volumesize*1024); + shuff = shuff_init_encoder_byfile(argv[optind],argv[optind+1],volumesize*1024); shuff_encode_file(shuff); - shuff_deinit_static_byfile(shuff); + shuff_deinit_encoder(shuff); free(shuff); } if (dflag == 1) { /* Descomprimo */ - shuff = shuff_init_static_byfile(argv[optind],argv[optind+1],0); + shuff = shuff_init_decoder(argv[optind],argv[optind+1]); shuff_decode_file(shuff); - shuff_deinit_static_byfile(shuff); + shuff_deinit_decoder(shuff); free(shuff); } diff --git a/src/statichuff/main_bychunk.c b/src/statichuff/main_bychunk.c index 54ce628..5ce8016 100644 --- a/src/statichuff/main_bychunk.c +++ b/src/statichuff/main_bychunk.c @@ -53,7 +53,7 @@ int main(int argc, char* argv[]) i++; } /* Comprimo el chunk con huffman estatico */ - shuff_encode_chunk(shuff,chunk,i,0); + shuff_scanfreq_chunk(shuff,chunk,i); } /* Le indico al huffman que efectivamente comprima los chunks */ shuff_encode_file(shuff); diff --git a/src/statichuff/statichuff.c b/src/statichuff/statichuff.c index 32b3e8d..28b932d 100644 --- a/src/statichuff/statichuff.c +++ b/src/statichuff/statichuff.c @@ -1,6 +1,5 @@ #include "statichuff.h" -#include "../vfile/vfile.h" #include void putbit(char bit, char restart, char flush, VFILE *fp) @@ -263,101 +262,20 @@ int shuff_encode_symbols(HUFF_STATE *shuff, SHUFFCODE *ctable) return 1; } -int shuff_encode_chunk(HUFF_STATE *chunkshuff, char *chunk, int chunksize, int process) -{ - int i; - - if (!process) { - /* Scaneo las frecuencias de este chunk */ - shuff_scanfreq_chunk(chunkshuff,chunk,chunksize); - } - else { - /* Ya tengo la tabla y el archivo temporal, paso al huffman by file */ - return 0; - } - - return 1; -} - -HUFF_STATE *shuff_init_static_byfile(char *inputfile, char *outputfile, long volsize) -{ - /* Locals */ - HUFF_STATE *fshuff = (HUFF_STATE*)malloc(sizeof(HUFF_STATE)); - int i; - - /* Inicializo la estructura para trabajar con Huff Static by File */ - fshuff->tmpfp = NULL; - fshuff->sourcefile = (char*)malloc(sizeof(char)*(strlen(inputfile)+1)); - fshuff->targetfile = (char*)malloc(sizeof(char)*(strlen(outputfile)+1)); - strcpy(fshuff->sourcefile,inputfile); - strcpy(fshuff->targetfile,outputfile); - fshuff->preloadfreq = 0; - fshuff->volsize = volsize; - fshuff->sumfreq = 0; - fshuff->freqtable = (t_freq*)malloc(sizeof(t_freq)*256); - for (i = 0; i < 256; ++i) fshuff->freqtable[i] = 0; - - return fshuff; -} - -HUFF_STATE *shuff_init_static_bychunk(char *outputfile, long volsize) -{ - /* Locals */ - HUFF_STATE *cshuff = (HUFF_STATE*)malloc(sizeof(HUFF_STATE)); - FILE *fp; - int i; - - /* Inicializo la estructura para trabajar con Huff Static by Chunks */ - cshuff->sourcefile = (char*)malloc(sizeof(char)*(strlen(outputfile)+2)); - cshuff->targetfile = (char*)malloc(sizeof(char)*(strlen(outputfile)+1)); - strcpy(cshuff->targetfile,outputfile); - strcpy(cshuff->sourcefile,outputfile); - strcat(cshuff->sourcefile,"~"); - cshuff->volsize = volsize; - cshuff->preloadfreq = 1; - cshuff->sumfreq = 0; - cshuff->freqtable = (t_freq*)malloc(sizeof(t_freq)*256); - for (i = 0; i < 256; ++i) cshuff->freqtable[i] = 0; - - /* Abrimos un archivo temporal para ir tirando los chunks */ - if ((cshuff->tmpfp = fopen(cshuff->sourcefile,"w")) == NULL) return NULL; - - return cshuff; -} - -void shuff_deinit_static_byfile(HUFF_STATE *fshuff) -{ - /* Libero mallocs y cierro archivos */ - free(fshuff->freqtable); - free(fshuff->sourcefile); - free(fshuff->targetfile); -} - -void shuff_deinit_static_bychunk(HUFF_STATE *cshuff) -{ - /* Libero mallocs y cierro archivos */ - free(cshuff->freqtable); - free(cshuff->sourcefile); - free(cshuff->targetfile); - fclose(cshuff->tmpfp); -} - int shuff_encode_file(HUFF_STATE *shuff) { - /* Locals */ - SHUFFNODE *codetree; + /* Locals */ SHUFFCODE *codetable = (SHUFFCODE*)malloc(sizeof(SHUFFCODE)*256); - int i; /* Veo si debo armar una freqtable o si esta preloaded */ if (!shuff->preloadfreq) if (!shuff_scanfreq(shuff->sourcefile,shuff->freqtable)) return 0; /* Genero el arbol de huffman */ - codetree = shuff_buildtree(shuff->freqtable); + shuff->codetree = shuff_buildtree(shuff->freqtable); /* Armo la tabla de codigos prefijos para el encoder */ shuff_zerocodes(codetable); - shuff_buildcodes(codetable,codetree,0,0); + shuff_buildcodes(codetable,shuff->codetree,0,0); /*shuff_printcodes(codetable,shuff->freqtable);*/ /* Encodeo byte per byte */ @@ -366,8 +284,6 @@ int shuff_encode_file(HUFF_STATE *shuff) /* Free up memory baby yeah */ free(codetable); - /* Destruyo el arbol recursivamente TODO */ - return 1; } @@ -390,43 +306,134 @@ SHUFFNODE *shuff_decode_symbols(SHUFFNODE *entrynode, unsigned long int buffer, int shuff_decode_file(HUFF_STATE *shuff) { - SHUFFNODE *codetree,*currnode; - unsigned long int bytesleft,codebuffer; - VFILE *fpsource; + SHUFFNODE *currnode; + unsigned long int codebuffer; FILE *fpdest; unsigned short int decoded_symbol; - int bitsleft,freqcount = 0; + int bitsleft; - /* Levanto cuantos bytes decodeo y la freq table */ - if ((fpsource = vfopen(shuff->sourcefile,"r",0)) == NULL) return 0; - if ((fpdest = fopen(shuff->targetfile,"w")) == NULL) return 0; - vfread(&bytesleft,sizeof(unsigned long int),1,fpsource); - vfread(shuff->freqtable,sizeof(unsigned long int),256,fpsource); - codetree = shuff_buildtree(shuff->freqtable); - currnode = codetree; + /* Levanto cuantos bytes decodeo y la freq table */ + if ((fpdest = fopen(shuff->targetfile,"w")) == NULL) return 0; + currnode = shuff->codetree; - while (!vfeof(fpsource) && (bytesleft > 0)) { + while (!vfeof(shuff->decoderfp) && (shuff->bytesleft > 0)) { /* Leo un buffer de 32 bits */ - if (vfread(&codebuffer,sizeof(unsigned long int),1,fpsource) != 1) continue; + if (vfread(&codebuffer,sizeof(unsigned long int),1,shuff->decoderfp) != 1) continue; bitsleft = sizeof(unsigned long int) * 8; /* Proceso el buffer sacando simbolos hasta que se me agote */ - while ((bitsleft > 0) && (bytesleft > 0)) { + while ((bitsleft > 0) && (shuff->bytesleft > 0)) { currnode = shuff_decode_symbols(currnode,codebuffer,&bitsleft,&decoded_symbol); /* Si obtuve un symbolo valido lo emito*/ if (decoded_symbol != 256) { fputc(decoded_symbol,fpdest); - currnode = codetree; - --bytesleft; + currnode = shuff->codetree; + --(shuff->bytesleft); } } } - - vfclose(fpsource); - fclose(fpdest); - - /* Libero el arbol recursivamente TODO */ + + fclose(fpdest); return 1; } + +HUFF_STATE *shuff_init_decoder(char *inputfile, char *outputfile) +{ + /* Locals */ + HUFF_STATE *shuff = (HUFF_STATE*)malloc(sizeof(HUFF_STATE)); + shuff->freqtable = (t_freq*)malloc(sizeof(t_freq)*256); + + /* Init fields */ + shuff->coderfp = NULL; + shuff->targetfile = NULL; + shuff->sourcefile = (char*)malloc(sizeof(char)*(strlen(inputfile)+1)); + strcpy(shuff->sourcefile,inputfile); + if (outputfile != NULL) { + shuff->targetfile = (char*)malloc(sizeof(char)*(strlen(outputfile)+1)); + strcpy(shuff->targetfile,outputfile); + } + + /* Levanto cuantos bytes decodeo y la freq table */ + if ((shuff->decoderfp = vfopen(shuff->sourcefile,"r",0)) == NULL) return 0; + vfread(&(shuff->bytesleft),sizeof(unsigned long int),1,shuff->decoderfp); + vfread(shuff->freqtable,sizeof(unsigned long int),256,shuff->decoderfp); + shuff->codetree = shuff_buildtree(shuff->freqtable); + + return shuff; +} + +HUFF_STATE *shuff_init_encoder_byfile(char *inputfile, char *outputfile, long volsize) +{ + /* Locals */ + HUFF_STATE *fshuff = (HUFF_STATE*)malloc(sizeof(HUFF_STATE)); + int i; + + /* Inicializo la estructura para trabajar con Huff Static by File */ + fshuff->coderfp = NULL; + fshuff->decoderfp = NULL; + fshuff->sourcefile = (char*)malloc(sizeof(char)*(strlen(inputfile)+1)); + fshuff->targetfile = (char*)malloc(sizeof(char)*(strlen(outputfile)+1)); + strcpy(fshuff->sourcefile,inputfile); + strcpy(fshuff->targetfile,outputfile); + fshuff->volsize = volsize; + fshuff->preloadfreq = 0; + fshuff->freqtable = (t_freq*)malloc(sizeof(t_freq)*256); + for (i = 0; i < 256; ++i) fshuff->freqtable[i] = 0; + fshuff->sumfreq = 0; + fshuff->bytesleft = 0; + fshuff->codetree = NULL; + + return fshuff; +} + +HUFF_STATE *shuff_init_encoder_bychunk(char *outputfile, long volsize) +{ + /* Locals */ + HUFF_STATE *cshuff = (HUFF_STATE*)malloc(sizeof(HUFF_STATE)); + int i; + + /* Inicializo la estructura para trabajar con Huff Static by Chunks */ + cshuff->decoderfp = NULL; + cshuff->sourcefile = (char*)malloc(sizeof(char)*(strlen(outputfile)+2)); + cshuff->targetfile = (char*)malloc(sizeof(char)*(strlen(outputfile)+1)); + strcpy(cshuff->targetfile,outputfile); + strcpy(cshuff->sourcefile,outputfile); + strcat(cshuff->sourcefile,"~"); + cshuff->volsize = volsize; + cshuff->preloadfreq = 1; + cshuff->freqtable = (t_freq*)malloc(sizeof(t_freq)*256); + for (i = 0; i < 256; ++i) cshuff->freqtable[i] = 0; + cshuff->sumfreq = 0; + cshuff->bytesleft = 0; + cshuff->codetree = NULL; + + /* Abrimos un archivo temporal para ir tirando los chunks */ + if ((cshuff->coderfp = fopen(cshuff->sourcefile,"w")) == NULL) return NULL; + + return cshuff; +} + +void shuff_deinit_encoder(HUFF_STATE *shuff) +{ + /* Libero mallocs y cierro archivos */ + free(shuff->freqtable); + free(shuff->sourcefile); + free(shuff->targetfile); + if (shuff->coderfp != NULL) fclose(shuff->coderfp); + if (shuff->decoderfp != NULL) vfclose(shuff->decoderfp); + + /* Destruyo recursivamente el arbol de codigos */ +} + +void shuff_deinit_decoder(HUFF_STATE *shuff) +{ + /* Libero mallocs y cierro archivos */ + free(shuff->freqtable); + free(shuff->sourcefile); + if (shuff->targetfile != NULL) free(shuff->targetfile); + if (shuff->decoderfp != NULL) vfclose(shuff->decoderfp); + + /* Destruyo recursivamente el arbol de codigos */ +} diff --git a/src/statichuff/statichuff.h b/src/statichuff/statichuff.h index 08da37e..5bc1645 100644 --- a/src/statichuff/statichuff.h +++ b/src/statichuff/statichuff.h @@ -4,6 +4,7 @@ #include #include +#include "../vfile/vfile.h" typedef unsigned long int t_freq; @@ -20,21 +21,22 @@ typedef struct t_code { } SHUFFCODE; typedef struct t_huff { - FILE *tmpfp; /* filepointer al temporal para un shuff_bychunk */ + FILE *coderfp; /* filepointer usado en el coder de bychunk */ + VFILE *decoderfp; /* filepointer usado en ambos decoders */ char *sourcefile; /* Nombre del archivo a comprimir */ char *targetfile; /* Nombre del archivo comprimido */ + long volsize; /* Tamanio de volumen para multivol */ + char preloadfreq; /* 1 Freqtable preloaded (bychunk | canonico) - 0 byfile */ t_freq *freqtable; /* Tabla de frecuencias */ t_freq sumfreq; /* Frecuencia total acumulada */ - long volsize; /* Tamanio de volumen para multivol */ - char preloadfreq; /* 1 freqtable preloaded (bychunk|canonico) - 0 byfile */ - + SHUFFNODE *codetree; /* Puntero al arbol de codigos prefijos */ + unsigned long int bytesleft; /* cuanto falta descomprimir en un bychunk */ } HUFF_STATE; -HUFF_STATE *shuff_init_static_byfile(char *inputfile, char *outputfile, long volsize); -HUFF_STATE *shuff_init_static_bychunk(char *outputfile, long volsize); -void shuff_deinit_static_byfile(HUFF_STATE *fshuff); -void shuff_deinit_static_bychunk(HUFF_STATE *cshuff); +HUFF_STATE *shuff_init_encoder_byfile(char *inputfile, char *outputfile, long volsize); +HUFF_STATE *shuff_init_encoder_bychunk(char *outputfile, long volsize); +HUFF_STATE *shuff_init_decoder(char *inputfile, char *outputfile); +void shuff_deinit_encoder(HUFF_STATE *shuff); int shuff_decode_file(HUFF_STATE *shuff); -int shuff_encode_file(HUFF_STATE *shuff); #endif /* _STATICHUFF_H_ */ -- 2.43.0