From: Alan Kennedy Date: Sun, 20 Jun 2004 05:32:28 +0000 (+0000) Subject: Listo Huffman, Encoding y Decoding con Codigos de 32 bits maximo. Tambien arme el... X-Git-Tag: svn_import~140 X-Git-Url: https://git.llucax.com/z.facultad/75.06/jacu.git/commitdiff_plain/69bddb46f46871d27bcf797cd6fae14430802380?hp=efbfacc87590729a6790eecee98b91d55615f881 Listo Huffman, Encoding y Decoding con Codigos de 32 bits maximo. Tambien arme el ejecutable para que tome los parametros como los pide el TP, no es que vaya a usarse mi ejecutable, pero para que lo puedan probar tranquilo. Aun NO SOPORTA multivolumen, ahora me pongo a ver los 40 mails sobre el VFILE que no logre ver en la semana para ver como acoplo lo que tengo. Ademas hay que ver como acopla el Huffman con la salida el MTF, porque por el momento lo arme para que reciba archivos, no chunks, o cosas por el estilo, lo charlamos luego, me parece mejor ver el tema VFILE first pero avisen --- diff --git a/src/statichuff/statichuff.c b/src/statichuff/statichuff.c index e1dfe35..e608bb2 100644 --- a/src/statichuff/statichuff.c +++ b/src/statichuff/statichuff.c @@ -5,8 +5,7 @@ void putbit(char bit, char restart, char flush, FILE *fp) { static unsigned long int bits_buffer = 0; - static unsigned char bits_used = 0; - int i; + static unsigned char bits_used = 0; /* me obligan a emitir el output */ if ((flush == 1) && (bits_used > 0)) { @@ -120,7 +119,7 @@ SHUFFNODE *shuff_buildlist(t_freq *freqtable, int *nonzerofreqs) SHUFFNODE *shuff_buildtree(SHUFFNODE *list, int listcount) { SHUFFNODE *lastsymbol = list+(listcount-1); - SHUFFNODE *node1,*node2,*fictnode; + SHUFFNODE *node1,*node2; /* Ordenamos inicialmente la inputlist para tomar las dos freqs min */ while (lastsymbol > list) { @@ -240,10 +239,10 @@ int shuff_encode_file(char *inputfile, char *outputfile) SHUFFNODE *inputlist; SHUFFNODE *codetree; SHUFFCODE *codetable = (SHUFFCODE*)malloc(sizeof(SHUFFCODE)*256); - int freqcount = 0,i; + int freqcount = 0; /* Armamos la tabla de frecuencias */ - if (!shuff_scanfreq(inputfile,freqtable)) return -1; + if (!shuff_scanfreq(inputfile,freqtable)) return 0; /* Armo el input list y genero el arbol de huffman */ inputlist = shuff_buildlist(freqtable, &freqcount); @@ -252,45 +251,116 @@ int shuff_encode_file(char *inputfile, char *outputfile) /* Armo la tabla de codigos prefijos para el encoder */ shuff_zerocodes(codetable); shuff_buildcodes(codetable,codetree,0,0); - shuff_printcodes(codetable,freqtable); + /*shuff_printcodes(codetable,freqtable);*/ /* Encodeo byte per byte */ shuff_encode_symbols(freqtable,codetable,inputfile,outputfile); + + return 1; } -int shuff_decode(char *inputfile, char *outputfile) +SHUFFNODE *shuff_decode_symbols(SHUFFNODE *entrynode, unsigned long int buffer, + int *bitsleft, unsigned short int *symbol) +{ + char bit = 0; + + /* Levanto el symbolo y si es uno valido, devuelvo */ + *symbol = entrynode->symbol; + if (*symbol != 256) return entrynode; + if (*bitsleft == 0) return entrynode; + + /* Obtengo otro bit a procesar y me muevo en el arbol */ + bit = (buffer >> ((*bitsleft)-1)) & 1; + --(*bitsleft); + if (bit == 0) return shuff_decode_symbols(entrynode->lchild,buffer,bitsleft,symbol); + else return shuff_decode_symbols(entrynode->rchild,buffer,bitsleft,symbol); +} + +int shuff_decode_file(char *inputfile, char *outputfile) { SHUFFNODE *inputlist; - SHUFFNODE *codetree; + SHUFFNODE *codetree,*currnode; t_freq *ftable = (t_freq*)malloc(sizeof(t_freq)*256); - unsigned long int bytesleft; + unsigned long int bytesleft,codebuffer; FILE *fpsource; FILE *fpdest; - int i,freqcount = 0; + unsigned short int decoded_symbol; + int bitsleft,freqcount = 0; /* Levanto cuantos bytes decodeo y la freq table */ if ((fpsource = fopen(inputfile,"rb")) == NULL) return 0; if ((fpdest = fopen(outputfile,"wb")) == NULL) return 0; fread(&bytesleft,sizeof(unsigned long int),1,fpsource); - fread(ftable,sizeof(unsigned long int),256,fpsource); + fread(ftable,sizeof(unsigned long int),256,fpsource); inputlist = shuff_buildlist(ftable, &freqcount); codetree = shuff_buildtree(inputlist,freqcount); + currnode = codetree; + + while (!feof(fpsource) && (bytesleft > 0)) { + + /* Leo un buffer de 32 bits */ + if (fread(&codebuffer,sizeof(unsigned long int),1,fpsource) != 1) continue; + bitsleft = sizeof(unsigned long int) * 8; + + /* Proceso el buffer sacando simbolos hasta que se me agote */ + while ((bitsleft > 0) && (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; + } + } + } fclose(fpsource); fclose(fpdest); - + return 1; } int main(int argc, char* argv[]) { - if (argc == 1) return -1; + int cflag = 0; + int dflag = 0; + int tflag = 0; + long int volumesize = 0; + int ch; + + while ((ch = getopt(argc, argv, "cdt:")) != -1) { + + switch (ch) { + case 'c': cflag = 1; + break; + + case 'd': dflag = 1; + break; + + case 't': tflag = 1; + volumesize = atoi(optarg); + break; + + default: fprintf(stderr, "Usage: %s [-cdt] sourcefile targetfile\n", argv[0]); + return(2); + } + } - /* Comprimo */ - shuff_encode_file(argv[1],"output.shf"); - - /* Decodeo */ - shuff_decode("output.shf","decoded.dat"); + if ( (argc == 1) || (cflag & dflag) || !(cflag | dflag) || ((argc - optind) < 2) ) { + fprintf(stderr, "Usage: %s [-cdt] sourcefile targetfile\n", argv[0]); + if ((tflag == 1) && (volumesize <= 0)) fprintf(stderr,"Error: The volume size must be a non-zero value\n"); + return (2); + } + + if (cflag == 1) { + /* Comprimo */ + return shuff_encode_file(argv[optind],argv[optind+1]); + } + if (dflag == 1) { + /* Descomprimo */ + return shuff_decode_file(argv[optind],argv[optind+1]); + } + return 0; } diff --git a/src/statichuff/statichuff.h b/src/statichuff/statichuff.h index eac6505..8c3502d 100644 --- a/src/statichuff/statichuff.h +++ b/src/statichuff/statichuff.h @@ -1,5 +1,9 @@ +#ifndef _STATICHUFF_H_ +#define _STATICHUFF_H_ + #include +#include typedef unsigned long int t_freq; @@ -14,3 +18,8 @@ typedef struct t_code { unsigned long int code; unsigned char codelength; } SHUFFCODE; + +int shuff_decode_file(char *inputfile, char *outputfile); +int shuff_encode_file(char *inputfile, char *outputfile); + +#endif /* _STATICHUFF_H_ */