diff options
Diffstat (limited to 'sem_3/SYSTEME/TP3')
| -rw-r--r-- | sem_3/SYSTEME/TP3/HUFFMAN/Makefile | 9 | ||||
| -rw-r--r-- | sem_3/SYSTEME/TP3/HUFFMAN/compact.py | 32 | ||||
| -rw-r--r-- | sem_3/SYSTEME/TP3/HUFFMAN/decompact.py | 55 | ||||
| -rw-r--r-- | sem_3/SYSTEME/TP3/HUFFMAN/dehuf.c | 150 | ||||
| -rw-r--r-- | sem_3/SYSTEME/TP3/HUFFMAN/distrib.c | 357 | ||||
| -rw-r--r-- | sem_3/SYSTEME/TP3/HUFFMAN/minirapport.odt | bin | 0 -> 24351 bytes | |||
| -rw-r--r-- | sem_3/SYSTEME/TP3/HUFFMAN/readme.txt | 16 |
7 files changed, 619 insertions, 0 deletions
diff --git a/sem_3/SYSTEME/TP3/HUFFMAN/Makefile b/sem_3/SYSTEME/TP3/HUFFMAN/Makefile new file mode 100644 index 0000000..63886ef --- /dev/null +++ b/sem_3/SYSTEME/TP3/HUFFMAN/Makefile @@ -0,0 +1,9 @@ +all : dehuf.o huf.o + gcc -Wall -ansi -pedantic -std=c99 dehuf.o -o dehuf -lm + gcc -Wall -ansi -pedantic -std=c99 distrib.o -o huf -lm +dehuf.o : dehuf.c + gcc -Wall -ansi -pedantic -std=c99 -c dehuf.c +huf.o : distrib.c + gcc -Wall -ansi -pedantic -std=c99 -c distrib.c +clean : + rm *.o diff --git a/sem_3/SYSTEME/TP3/HUFFMAN/compact.py b/sem_3/SYSTEME/TP3/HUFFMAN/compact.py new file mode 100644 index 0000000..0d57b91 --- /dev/null +++ b/sem_3/SYSTEME/TP3/HUFFMAN/compact.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3
+
+import os,sys,re
+from subprocess import call
+
+def parcours (cible,fichierdir,init):
+ if os.path.isdir(cible):
+ liste=os.listdir(cible)
+ for fichier in liste :
+ fichier = cible+"/"+fichier
+ parcours(fichier,fichierdir,init)
+ else :
+ tmp = open(cible,'rb')
+ if init[0]=="/" :
+ fichierdir.write(b"\n--"+bytes(cible[len(re.search("(^\/.*\/).+",init).group(0))+1:],'UTF-8')+b"--\n")
+ else :
+ fichierdir.write(b"\n--"+bytes(cible,"UTF-8")+b"--\n")
+ print(cible)
+ byte=tmp.read()
+ fichierdir.write(byte)
+ tmp.close()
+
+if len(sys.argv)!= 2 :
+ print("Parametres incorrects, syntaxe : ./compact.py fichier\n")
+ exit()
+cible = sys.argv[1]
+fichier = open(".compactageencours",'ab')
+parcours(cible,fichier,cible)
+destination = re.search("(\w+\.?\w+)$",sys.argv[1]).group(1)+".comp"
+call(["./huf", ".compactageencours", destination])
+call(["rm",".compactageencours"])
+fichier.close()
diff --git a/sem_3/SYSTEME/TP3/HUFFMAN/decompact.py b/sem_3/SYSTEME/TP3/HUFFMAN/decompact.py new file mode 100644 index 0000000..1cc3bc3 --- /dev/null +++ b/sem_3/SYSTEME/TP3/HUFFMAN/decompact.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3
+
+import os, sys,re
+from subprocess import call
+
+def creerdossier(path):
+ result =re.split("/",path)
+ for i in range(len(result)-1):
+ if i >= 1 :
+ result[i]= result[i-1]+"/"+result[i]
+ if not (os.path.exists(result[i])):
+ call(["mkdir",result[i]])
+
+def decompactdistant(fichier, fichierdest):
+ os.system("./dehuf "+fichier+" > .decompactencours")
+ premierdos = fichierdest
+ call(["mkdir",premierdos])
+ decompact = open(".decompactencours","r")
+ destfile=decompact
+ for line in decompact.readlines()[1:]:
+ tmp = line.encode()
+ if line[0]=="-" and line[1]=="-":
+ estuneentete=re.search("^--(.*)--$",line)
+ if estuneentete:
+ destfile.close()
+ creerdossier(premierdos+"/"+estuneentete.group(1))
+ destfile=open(premierdos+"/"+estuneentete.group(1),"w")
+ else :
+ destfile.write(line)
+
+def decompacthere(fichier):
+ os.system("./dehuf "+fichier+" > .decompactencours")
+ premierdos = re.search("(\w+)\.?\w*.comp$",fichier).group(1)
+ call(["mkdir",premierdos])
+ decompact = open(".decompactencours","r")
+ destfile=decompact
+ for line in decompact.readlines()[1:]:
+ tmp = line.encode()
+ if line[0]=="-" and line[1]=="-":
+ estuneentete=re.search("^--(.*)--$",tmp)
+ if estuneentete:
+ destfile.close()
+ creerdossier(premierdos+"/"+estuneentete.group(1))
+ destfile=open(premierdos+"/"+estuneentete.group(1),"w")
+ else :
+ destfile.write(line)
+
+if len(sys.argv)==2:
+ decompacthere(sys.argv[1])
+elif len(sys.argv)==3:
+ decompactdistant(sys.argv[1],sys.argv[2])
+else:
+ print("Parametres incorrects, syntaxe : ./decompact.py fichiercomp [destination] \n (Destination est optionnel)")
+ exit()
+call(["rm",".decompactencours"])
diff --git a/sem_3/SYSTEME/TP3/HUFFMAN/dehuf.c b/sem_3/SYSTEME/TP3/HUFFMAN/dehuf.c new file mode 100644 index 0000000..7b264e1 --- /dev/null +++ b/sem_3/SYSTEME/TP3/HUFFMAN/dehuf.c @@ -0,0 +1,150 @@ +#include<stdio.h> +#include<stdlib.h> +#include<math.h> + +typedef struct table table; +struct table { + unsigned int taille; + unsigned int * taillecode; + char * carac; + char ** code; +}; + +table * gettable(FILE*); +int getcarac(char *,int, table *,char *); +void getdata(FILE *, table *); +void printtabcomp ( table * ); +void supprimerTable(table * ); + + +int main ( int argc, char ** argv){ + if (argc!=2) { + printf("Nombre d'arguments incorrects, syntaxe : \"./dehuf \"fichiercomp\"\"\n"); + return 1; + } + FILE * fichier = fopen(argv[1], "rb"); + if (fichier == NULL) { + printf("Erreur, l'ouverture du fichier source à rencontré une erreur, verifiez que vous avez les droits en lecture sur le fichier.\n"); + } + table * donneecompression = gettable(fichier); + //printtabcomp(donneecompression); + getdata(fichier, donneecompression); + supprimerTable(donneecompression); + return 0; +} + + +void supprimerTable(table * tablecod){ + for (unsigned int i = 0; i < tablecod->taille; i ++){ + free(tablecod->code[i]); + } + free(tablecod->taillecode); + free(tablecod->carac); + free(tablecod); +} +table * gettable(FILE* fichier){ + int temp=0; + table * tablecodage = malloc(sizeof(table)); + tablecodage->taille = fgetc(fichier); + if (tablecodage->taille == 0) tablecodage->taille=256; + tablecodage->taillecode=malloc(sizeof(int)*tablecodage->taille); + tablecodage->carac=malloc(sizeof(char)*tablecodage->taille); + tablecodage->code=malloc(sizeof(char*)*tablecodage->taille); + int caracrestant = tablecodage->taille; + int caracint =0; + while (caracrestant>0){ + tablecodage->taillecode[tablecodage->taille-caracrestant]=fgetc(fichier); + tablecodage->code[tablecodage->taille-caracrestant]=malloc(sizeof(char)*tablecodage->taillecode[tablecodage->taille-caracrestant]); + for (int i =0; i < tablecodage->taillecode[tablecodage->taille-caracrestant] ; i ++){ + + if ( i%8 == 0){ + caracint =fgetc(fichier); + } + if (caracint >= (float)pow(2,7-(i%8))){ + tablecodage->code[tablecodage->taille-caracrestant][i]='1'; + caracint -= pow(2,7-(i%8)); + } + else { + tablecodage->code[tablecodage->taille-caracrestant][i]='0'; + } + } + temp=fgetc(fichier); + tablecodage->carac[tablecodage->taille-caracrestant]=(char)temp; + caracrestant --; + } + return tablecodage; +} +int getcarac(char * code,int taille, table * tablecodage,char * carac){ + if (taille == 0){ + return 0; + } + int i =0; + int trouve = 0; + while ( i < tablecodage->taille && !trouve){ + if (tablecodage->taillecode[i]==taille){ + int j =0; + int cestpaslui = 0; + while ( j < taille && !cestpaslui){ + if ( code[j] != tablecodage->code[i][j]){ + cestpaslui=1; + } + else j ++; + } + trouve= !cestpaslui ? 1 : 0; + } + if (!trouve) i ++; + } + if (trouve){ + *carac=tablecodage->carac[i]; + return 1; + } + else return 0; +} +void printtabcomp ( table * tabcomp){ + for (int i =0; i < tabcomp->taille; i ++){ + if (tabcomp->carac[i]==(char)10) { + printf("Carac = LF"); + } + else if (tabcomp->carac[i]==(char)13) { + printf("Carac = CR"); + } + else printf("Carac = %c", tabcomp->carac[i]); + printf(", taille chemin = %d, chemin = ", tabcomp->taillecode[i]); + for (int j =0; j < tabcomp->taillecode[i]; j ++){ + printf("%c",tabcomp->code[i][j]); + } + printf("\n"); + } +} +void getdata(FILE * fichier, table * donneecompression){ + int currentcarac=fgetc(fichier); + int nextcarac=fgetc(fichier); + int lastcarac=fgetc(fichier); + int cpt=0; + int taille=0; + char * code = malloc(0); + char carac; + int trouve=0; + while (lastcarac!=EOF){ + while ( !(trouve=getcarac(code,taille,donneecompression,&carac))/*&&lastcarac!=EOF*/){ + if ( cpt == 8){ + currentcarac=nextcarac; + nextcarac=lastcarac; + lastcarac=fgetc(fichier); + cpt =0; + } + taille ++; + code=realloc(code,sizeof(char)*taille); + if (currentcarac>=pow(2,7-cpt)){ + code[taille-1]='1'; + currentcarac-=pow(2,7-cpt); + } + else code[taille-1]='0'; + cpt ++; + } + printf("%c", carac); + taille = 0; + code=realloc(code,0); + } + printf("\n"); +} diff --git a/sem_3/SYSTEME/TP3/HUFFMAN/distrib.c b/sem_3/SYSTEME/TP3/HUFFMAN/distrib.c new file mode 100644 index 0000000..3ae45b1 --- /dev/null +++ b/sem_3/SYSTEME/TP3/HUFFMAN/distrib.c @@ -0,0 +1,357 @@ +#include<stdio.h> +#include<stdlib.h> +#include<math.h> + +typedef struct proba proba; +struct proba { + char * carac; + int * nb_carac; + float * proba; + int taille; + int somme; +}; +typedef struct branche branche; +struct branche { + char noeud; + branche * filsg; + branche * filsd; +}; +typedef struct doublet doublet; +struct doublet{ + int a; + int b; +}; +typedef struct table table; +struct table { + unsigned int taille; + unsigned int * taillecode; + char * carac; + char ** code; + unsigned int indice[256]; +}; +typedef struct buffer buffer; +struct buffer { + unsigned int taille; + char contenu; +}; + +void loading(int, FILE *,float *); +void forceprintbuffer(buffer *,FILE *); +void supprimerTable(table *); +void ecrirecomp(FILE *,FILE *,table *,buffer *,int ); +void videbuffer(buffer *); +void ajouterbuffer(buffer*, char,FILE *); +void printcaraccode(table *,char,FILE *, buffer*); +void printchemin (char *, int, FILE *, buffer *); +void parcoursarbre ( branche *, char *, int, FILE *, table *, buffer *); +table * ecrireArbre(FILE *, branche*, int,buffer *); +void afficheTab(proba *); +void supprimerArbre(branche *); +branche* creerArbre(char , branche * , branche * ); +int estdanstab (char *,int,char); +void creertab (proba *, FILE *); +branche* creerHuff(proba*); +doublet deuxpluspetits(proba *); +void aff(branche *, int ); +void printinfofinales(table *, FILE *, FILE *); + + +int main (int argc, char ** argv) { + if (argc != 3) { + printf("Erreur, la syntaxe est la suivante : ./huffhuff [source] [destination]"); + return -1; + } + FILE * fichier = fopen(argv[1], "r"); + if (fichier == NULL) { + printf("Erreur, l'ouverture du fichier source à rencontré une erreur, verifiez que vous avez les droits en lecture sur le fichier."); + } + FILE * fichierdest = fopen(argv[2],"wb"); + if (fichierdest == NULL) { + printf("Erreur, l'ouverture du fichier de destination à rencontré une erreur."); + return -2; + } + fseek(fichier,0,SEEK_END); + int size = ftell(fichier); + rewind(fichier); + proba tab; + printf("Le fichier %s fait %d octets.\n",argv[1],size); + creertab (&tab, fichier); + afficheTab(&tab); + branche * Arbre = creerHuff(&tab); + free(tab.carac); + free(tab.nb_carac); + free(tab.proba); + buffer * buf = malloc(sizeof(buffer)); + videbuffer(buf); + table * tablecodage = ecrireArbre(fichierdest, Arbre, tab.taille,buf); + ecrirecomp(fichier,fichierdest,tablecodage,buf,size); + printinfofinales(tablecodage,fichier,fichierdest); + supprimerArbre(Arbre); + supprimerTable(tablecodage); + free(buf); + fclose(fichierdest); + fclose( fichier); + return 0; +} + + +void printinfofinales(table * tablecode, FILE * source, FILE * destination){ + int somme=0; + for (int i = 0; i < tablecode->taille;i++){ + somme+=tablecode->taillecode[i]; + } + float moy = (float)somme/(float)tablecode->taille; + printf("Fini ! \n"); + printf("Longueur moyenne du codage : %2.2f bits;", moy); + fseek(source,0,SEEK_END); + fseek(destination,0,SEEK_END); + int taillesource = ftell(source); + int taillecible = ftell(destination); + printf (" Taille d'origine : %d; Taille compressée : %d; Soit un gain de %3.2f %%\n", taillesource,taillecible,100-(float)taillecible*100/(float)taillesource); +} +void supprimerTable(table * tablecod){ + for (unsigned int i = 0; i < tablecod->taille; i ++){ + free(tablecod->code[i]); + } + free(tablecod->taillecode); + free(tablecod->carac); + free(tablecod); +} +void loading(int taille, FILE * fichier, float * anciennevaleur){ + int current = ftell(fichier)-1; + float avancement = current*100/taille; + if (current == 0){ + *anciennevaleur=0; + printf("["); + fflush(stdout); + } + if (*anciennevaleur+10 <= avancement){ + printf("##"); + fflush(stdout); + *anciennevaleur=avancement; + } + if (current == taille-2){ + printf("##]"); + fflush(stdout); + } + +} +void ecrirecomp(FILE * fichier,FILE * fichierdest,table * tablecodage, buffer * buf, int size){ + fseek(fichier,0,SEEK_SET); + int current=fgetc(fichier); + float * anciennevaleur=malloc(sizeof(float)); + *anciennevaleur=0; + while(current!=EOF){ + printcaraccode(tablecodage,(char)current,fichierdest,buf); + loading(size,fichier,anciennevaleur); + current =fgetc(fichier); + } + char remplissage = (char) 8-buf->taille; + forceprintbuffer(buf,fichierdest); + fwrite(&remplissage,sizeof(char),1,fichierdest); + free(buf); +} +void videbuffer(buffer * buf){ + buf->taille=0; + buf->contenu = 0; +} +void ajouterbuffer(buffer* buf, char carac,FILE * destination){ + char tmp='1'; + if ( buf->taille < 8){ + if ( carac == tmp)buf->contenu+=pow(2,7-buf->taille); + buf->taille++; + } + if (buf->taille == 8) { + fwrite(&buf->contenu,sizeof(char),1,destination); + videbuffer(buf); + fflush(destination); + } +} +void forceprintbuffer(buffer * buf,FILE * destination){ + if ( buf->taille>0){ + fwrite(&buf->contenu,sizeof(char),1,destination); + videbuffer(buf); + } +} +void printcaraccode(table* tablecodage,char carac,FILE * fichierdest, buffer * buf){ + unsigned int i =0; + i=tablecodage->indice[(unsigned char)carac]; + for (unsigned int j=0; j < tablecodage->taillecode[i];j++){ + ajouterbuffer(buf,tablecodage->code[i][j],fichierdest); + } +} +void printchemin (char * chemin, int taille, FILE *destination,buffer * buf){ + char taillechar = (char)taille; + fwrite(&taillechar, sizeof(char),1,destination); + for (int i =0; i < taille; i ++){ + ajouterbuffer(buf,chemin[i],destination); + }; + forceprintbuffer(buf, destination); +} +branche* creerHuff(proba*prob){ + branche * arbrehuf[prob->taille]; + for ( int i =0; i <= prob->taille; i ++){ + arbrehuf[i]= creerArbre(prob->carac[i], NULL, NULL); + } + doublet indices = deuxpluspetits(prob); + while (indices.b!=-1) { + arbrehuf[indices.a] = creerArbre (0, arbrehuf[indices.a],arbrehuf[indices.b]); + prob->proba[indices.a]+=prob->proba[indices.b]; + prob->proba[indices.b]=0; + indices = deuxpluspetits(prob); + } + return arbrehuf[indices.a]; +} +void parcoursarbre ( branche * Arbre, char * chemin, int taille, FILE * destination, table * tabcode, buffer * buf){ + if ( Arbre->filsd == NULL && Arbre->filsg==NULL ){ + printchemin(chemin, taille, destination, buf); + fwrite(&Arbre->noeud,sizeof(char),1,destination); + char * code = malloc(taille*sizeof(char)); + tabcode->taille+=1; + tabcode->code= realloc(tabcode->code,tabcode->taille*sizeof(char*)); + tabcode->carac=realloc(tabcode->carac,tabcode->taille*sizeof(char)); + tabcode->taillecode=realloc(tabcode->taillecode,tabcode->taille*sizeof(unsigned int)); + tabcode->carac[tabcode->taille-1]=Arbre->noeud; + tabcode->taillecode[tabcode->taille-1]=taille; + tabcode->indice[(unsigned char)Arbre->noeud]=tabcode->taille-1; + for (int i =0; i < taille; i ++){ + code[i]=chemin[i]; + } + tabcode->code[tabcode->taille-1]=code; + if (Arbre->noeud==(char)10) { + printf("Carac = LF"); + } + else if (Arbre->noeud==(char)13) { + printf("Carac = CR"); + } + else printf("Carac = %c", Arbre->noeud); + printf(", taille chemin = %d, chemin = ", taille); + for (int i =0; i < taille; i ++){ + printf("%c",chemin[i]); + } + printf("\n"); + } + else{ + int newtaille= taille + 1; + chemin = realloc(chemin, newtaille*sizeof(char)); + if (Arbre->filsg!=NULL){ + chemin[newtaille-1]='0'; + parcoursarbre ( Arbre->filsg, chemin, newtaille, destination, tabcode,buf ); + } + if (Arbre->filsd!=NULL){ + chemin[newtaille-1]='1'; + parcoursarbre ( Arbre->filsd, chemin, newtaille, destination, tabcode,buf); + } + } +} +table * ecrireArbre(FILE * destination, branche* arbre, int taille,buffer * buf){ + char taille2 = (char)taille; + table * tabcode = malloc(sizeof(table)); + tabcode->taille = 0; + tabcode->taillecode= malloc(0); + tabcode->code=malloc(0); + tabcode->carac=malloc(0); + fwrite(&taille2,sizeof(char),1,destination); + char * chemin = malloc(0); + parcoursarbre(arbre, chemin, 0, destination, tabcode,buf); + free(chemin); + fflush(destination); + return tabcode; +} +branche* creerArbre(char carac, branche * ssag, branche * ssad){ + branche * tmp = malloc(sizeof(branche)); + tmp->noeud= carac; + tmp->filsd= ssad; + tmp->filsg=ssag; + return tmp; +} +void supprimerArbre(branche * arbre){ + branche * gauche = arbre->filsg; + branche * droite = arbre->filsd; + if ( gauche != NULL){ + supprimerArbre(gauche); + } + if (droite!=NULL){ + supprimerArbre(droite); + } + if (droite==NULL && gauche == NULL) { + free(arbre); + } +} +void creertab (proba * tab, FILE * fichier){ + tab->carac = malloc(0); + tab->nb_carac = malloc (0); + tab->taille = 0; + tab->somme=0; + int caracint = 0; + char caracchar = 0; + int indice = -1; + caracint= fgetc(fichier); + while (caracint != EOF ) { + caracchar = (char)caracint; + tab->somme ++; + indice = estdanstab(tab->carac, tab->taille, caracchar); + if ( indice != -1) { + tab->nb_carac[indice]++; + } + else { + tab->taille ++; + tab->carac=realloc(tab->carac,tab->taille*(sizeof(char))); + tab->nb_carac=realloc(tab->nb_carac,tab->taille*(sizeof(int))); + tab->carac[tab->taille-1]= caracchar; + tab->nb_carac[tab->taille-1]= 1; + } + caracint = fgetc(fichier); + } + tab->proba=malloc(tab->taille*(sizeof(float))); + for (int i =0; i<tab->taille;i++){ + tab->proba[i]= (float)tab->nb_carac[i]/(float)tab->somme; + } +} +int estdanstab(char * tab, int n, char x) { + int i=0; + int ret=0; + while (i<n && !ret) { + if (tab[i]==x) ret = 1; + i ++; + } + return ret ? i-1 : -1; +} +void afficheTab(proba * prob){ + for (int i =0; i < prob->taille; i ++) { + if (prob->carac[i]==(char)10) { + printf("LF | %1.3f \n", prob->proba[i]); + } + if (prob->carac[i]==(char)13) { + printf("CR | %1.3f \n", prob->proba[i]); + } + else { + printf("%c | %1.3f \n", prob->carac[i], prob->proba[i]); + } + + } + printf("Le fichier comporte %d caracteres differents\n", prob->taille); +} +doublet deuxpluspetits(proba * prob) { //renvoie les indices des deux plus petits float du tableau + doublet ret; + ret.a= -1; + ret.b=-1; + float aval,bval; + aval = 2; + bval = 2; + for (int i =0; i< prob->taille; i ++){ + if ( prob->proba[i]!=0){ + if ( prob->proba[i]< aval){ + ret.b= ret.a; + bval=aval; + ret.a=i; + aval=prob->proba[i]; + } + else if (prob->proba[i]<bval){ + ret.b=i; + bval=prob->proba[i]; + } + } + } + return ret; +} diff --git a/sem_3/SYSTEME/TP3/HUFFMAN/minirapport.odt b/sem_3/SYSTEME/TP3/HUFFMAN/minirapport.odt Binary files differnew file mode 100644 index 0000000..f03ca37 --- /dev/null +++ b/sem_3/SYSTEME/TP3/HUFFMAN/minirapport.odt diff --git a/sem_3/SYSTEME/TP3/HUFFMAN/readme.txt b/sem_3/SYSTEME/TP3/HUFFMAN/readme.txt new file mode 100644 index 0000000..f6fd3d3 --- /dev/null +++ b/sem_3/SYSTEME/TP3/HUFFMAN/readme.txt @@ -0,0 +1,16 @@ +Compresseur Huffman de Gaspard Coulet,
+"make all" pour compiler huf et dehuf,
+./huf source destination
+./dehuf fichiercompressé
+
+Pas de bug ou de soucis connu jusque là, le traitement prend apparemment un peu de temps, la faute à une optimisation peut être pas assez poussée. Le programme n'affiche pas l'arbre de huffman, car je n'ai pas eu le temps de me pencher sur la représentation
+de l'arbre, en revanche, il affiche les chemin de chacun des caractères, ce qui est, en soit, une représentation de l'arbre.
+
+Compacteur :
+
+aide :
+
+"./compact.py source"
+Compacte source dans source.comp à l'endroit ou le script est exécuté.
+"./decompact.py source [destination]"
+Décompacte le dossier compressé source, si destination est précisé, décompresse dedans.
|
