From 71980e4541d53f82a210297ad30d621b525dfcc1 Mon Sep 17 00:00:00 2001 From: name Date: Sat, 14 Dec 2019 11:10:02 +0100 Subject: [PATCH] Guillaume - Update Gestion Fichiers --- arbre_de_codage/liste.c | 126 ------------ arbre_de_codage/liste.h | 23 --- gestion_des_fichiers/gestion_fichiers.c | 151 +++++++------- gestion_des_fichiers/gestion_fichiers.h | 25 ++- gestion_des_fichiers/test.txt | 2 +- gestion_des_fichiers/text.txt | 3 - main_compress.c | 254 ++++++++++-------------- 7 files changed, 191 insertions(+), 393 deletions(-) delete mode 100644 arbre_de_codage/liste.c delete mode 100644 arbre_de_codage/liste.h delete mode 100644 gestion_des_fichiers/text.txt diff --git a/arbre_de_codage/liste.c b/arbre_de_codage/liste.c deleted file mode 100644 index bcbd663..0000000 --- a/arbre_de_codage/liste.c +++ /dev/null @@ -1,126 +0,0 @@ -#include -#include -#include "liste.h" - -Freq creer_liste_vide(){ - return NULL; -} - -int est_liste_vide(Freq l){ - return(l==NULL); -} - -Freq ajouter(int nb, int lettre, Freq l){ - Occ * tmp; - tmp=malloc(sizeof(Occ)); - tmp->nb=nb; - tmp->lettre=lettre; - tmp->suiv=l; - return tmp; -} - -Freq inserer(Occ *place, Freq l){ - printf(" Inserer :\n"); - if(est_liste_vide(l)){ - printf(" Liste vide :\n"); - return ajouter(place->nb,place->lettre,creer_liste_vide()); - } - else{ - printf(" Liste non vide :\n"); - Occ * tmp; - tmp = l; - if(tmp->suiv == NULL){ - if(tmp->nb < place->nb){ - tmp->suiv=place; - place->suiv=NULL; - }else{ - place->suiv=tmp; - l=place; - } - return l; - } - while(tmp->suiv != NULL){ - if(tmp->suiv->nb >= place->nb){ - place->suiv=tmp->suiv; - tmp->suiv=place; - return l; - } - else{ - tmp=tmp->suiv; - } - } - // Ajoute à la fin - while(l->suiv != NULL){ - l = l->suiv; - } - l->suiv=place; - return l; - } -} - -int tete_lettre(Freq l){ - assert(!est_liste_vide(l)); - return(l->lettre); -} - -int tete_freq(Freq l){ - assert(!est_liste_vide(l)); - return(l->nb); -} - -Freq queue(Freq l){ - assert(!est_liste_vide(l)); - return(l->suiv); -} - -void liberer_liste(Freq l){ - if(!est_liste_vide(l)){ - liberer_liste(queue(l)); - free(l); - } -} - -Freq liberer_maillon(Freq l){ - assert(!est_liste_vide(l)); - Occ * tmp = l->suiv; - free(l); - return tmp; -} - -int liste_rechercher(int lettre,Freq l){ - if(est_liste_vide(l)){ - return 0; - } - else if(lettre==tete_lettre(l)){ - return 1; - } - else{ - return liste_rechercher(lettre,queue(l)); - } -} - -Freq incrementer(int lettre, Freq l){ - /* - Incrémente de 1, l'occurence de la lettre associée - (Attention ! Ici, la liste est parcourue complétement même si on a déjà incrémenté ... Autres solutions ?) - */ - if(est_liste_vide(l)){ - return l; - } - else{ - while(lettre != tete_lettre(l)){ - l=queue(l); - } - l->nb++; - return l; - } -} - -void afficher(Freq L){ - printf("Affichage ...\n"); - while(queue(L) != NULL){ - printf(" P : %d | Char : %d\n",tete_freq(L),tete_lettre(L)); - L=queue(L); - } - printf("Fin Affichage.\n"); -} \ No newline at end of file diff --git a/arbre_de_codage/liste.h b/arbre_de_codage/liste.h deleted file mode 100644 index 343986d..0000000 --- a/arbre_de_codage/liste.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __LISTE_OCCURENCE__ -#define __LISTE_OCCURENCE__ -struct zoccurence{ - int nb; - int lettre; - struct zoccurence *suiv; -}; -typedef struct zoccurence Occ; -typedef struct zoccurence * Freq; - -Freq creer_liste_vide(); -int est_liste_vide(Freq l); -Freq ajouter(int nb, int lettre, Freq l); -Freq inserer(Occ *place, Freq l); -int tete_lettre(Freq l); -int tete_freq(Freq l); -Freq queue(Freq l); -void liberer_liste(Freq l); -Freq liberer_maillon(Freq l); -int liste_rechercher(int lettre, Freq l); -Freq incrementer(int lettre, Freq l); -void afficher(Freq L); -#endif \ No newline at end of file diff --git a/gestion_des_fichiers/gestion_fichiers.c b/gestion_des_fichiers/gestion_fichiers.c index a7f2adf..84b2571 100644 --- a/gestion_des_fichiers/gestion_fichiers.c +++ b/gestion_des_fichiers/gestion_fichiers.c @@ -17,11 +17,11 @@ Bin_file *Ouv_Bit(char *p,char mode) A->mode=mode; //On récupére le mode d'ouverture du fichier et on le rentre dansle struct if(mode=='r') //suivant le mode (écriturer w ou lecture r) on va ouvrir le fichier a l'aide de fopen et on { //enregistre cela dans lestruct Bin_files - A->file=fopen(p,"r"); + A->file=fopen(p,"rb"); } else { - A->file=fopen(p,"w"); + A->file=fopen(p,"wb"); } A->record_length=0; //On va ensuite initialiser tous les élèments du struct. A->i_record=0; @@ -30,33 +30,33 @@ Bin_file *Ouv_Bit(char *p,char mode) return A; } -void Ec_Bit(Bin_file *output,char bit) // On veux une fonction capable d'écrire un bit dans un fichier +void Ec_Bit(Bin_file *output,char bit) // On veux une fonction capable d'écrire un bit dans un fichier { - unsigned char octet,b; // On utilise deux variables octet et b qui vont permettre de récupérer les élèmets a écrire. + unsigned char octet,b; // On utilise deux variables octet et b qui vont permettre de récupérer les élèmets a écrire. int i; - output->octet[output->i_octet]=bit; // On va mettre le premier élèment du tableau octet de la struct Bin_file a la valeur de bit - output->i_octet++; //On incremente aussi i_octet pour ne pas réecrire surcette valeur - if (output->i_octet==8) //Si le tableau octet est plein on va aller écire dans le tableau record - { - octet=0; //on passe octet a 0 et b a 0x80 soit 1000 0000 - b=0x80; // cela permet de toujoursgarder 1 en bit de poids fort dans b apre les décalages a droite - for(i=0;i<8;i++) + output->octet[output->i_octet]=bit; // On va mettre le premier élèment du tableau octet de la struct Bin_file a la valeur de bit + output->i_octet++; //On incremente aussi i_octet pour ne pas réecrire surcette valeur + if (output->i_octet==8) //Si le tableau octet est plein on va aller écire dans le tableau record + { + octet=0; //on passe octet a 0 et b a 0x80 soit 1000 0000 + b=0x80; // cela permet de toujoursgarder 1 en bit de poids fort dans b apre les décalages a droite + for(i=0;i<8;i++) { - if(output->octet[i]=='1') //si on a un '1' dans le tableau octet on va mettre dans octet le résultats de octet ou b + if(output->octet[i]=='1') //si on a un '1' dans le tableau octet on va mettre dans octet le résultats de octet ou b { - octet=octet|b; + octet=octet|b; // On va alors creer une "copie" du tableau octet dans octet } b=b>>1; } output->i_octet=0; - output->record[output->i_record]=octet; // On va apres le for remmtre i_octet a 0 puis on passe dans record la valeur du char octet pour conserver - output->i_record++; //ce que l'on veut écrire - output->nb_octets++; //On incrémente aussi i record pour passer a l'élèment suivant et nb_octets car on en a traiter un autre - if(output->i_record==BLOCK_SIZE) //On vérifie ensuite que record qui sert de buffer soit plein avant d'écrire sont contenue. + output->record[output->i_record]=octet; // On va apres le for remetre i_octet a 0 puis on passe dans record la valeur du char octet pour conserver + output->i_record++; //ce que l'on veut écrire + output->nb_octets++; //On incrémente aussi i record pour passer a l'élèment suivant et nb_octets car on en a traiter un autre + if(output->i_record==BLOCK_SIZE) //On vérifie ensuite que record qui sert de buffer soit plein avant d'écrire sont contenue. { fwrite(output->record,1,BLOCK_SIZE,output->file); - output->i_record=0; //si on éceit on reinitialise i record pour passer auxélèments suivant + output->i_record=0; //si on éceit on reinitialise i record pour passer auxélèments suivant } } @@ -65,67 +65,57 @@ void Ec_Bit(Bin_file *output,char bit) // On veux une f char Lec_Bit(Bin_file*input) { - char bit; //On veut lire un fichier bit a bit. Pourcela on va vérifier si la record length est nul ou non + char bit; //On veut lire un fichier bit a bit. Pourcela on va vérifier si la record length est nul ou non + unsigned char x, b=0x80; // Ici on déclare de char, x va permettre de récupérer un octet de record + // b vas servir de masque. Il nous permettra de savoir quelle valeur possède les bits des élèment de record + int i; //i est un compteur utiliser pour les boucles for - if (input->record_length==0) - { - fread(input->record,BLOCK_SIZE,1,input->file); // si il est nul on va aller le fichier - input->record_length=(BLOCK_SIZE/8); //on va rentré la longueur lue (4096 bit) en octet - input->i_record=0; //on reinitialise i_record pour etre sur de reprendre le record du début + if (input->record_length==0){ // Si le buffer (record),est videon va aller chercher lesélèments du fichier - for (input->i_octet=0;input->i_octet<8;input->i_octet++) //On va ensuite aller écrire dans le tableau octet. - { - if((input->record[input->i_record]>>1)&1) //pour cela on predre le premier élèment de record le décallé de 1 bit a droite et a chaque décallage on va comparer avec 1 - { - input->octet[7-input->i_octet]='1'; //Si le bit vaut 1 on ajoute '1' a octet, 0 sinon - } // cette méthode lisant en premeir les bits de poids faible, on les ajoutes en partant de la fin du tableau. - else - { - input->octet[7-input->i_octet]='0'; - } + input->record_length = fread(input->record,1,BLOCK_SIZE,input->file); //Pour cela on récupère dans record_length le nombre d'élèment de input-file et on les écrit dans record + input->i_record=0; //On réinitialise l'indice de record pour recommencerdepuis le début. + + x = input->record[input->i_record] ; //On réupère la valeurde record[i_record] dans x + for(i=0;i<8;i++) { + if(x&b) input->octet[i]='1'; //On va alors tester les bits de x grace a x&b. Cela permet de renvoyer 1 si lesdeux bits sont a 1 + else input->octet[i]='0'; // si le test est vrai on ajoute le char 1 dans octet sinon 0 + b=b>>1; //On décale ensuite b de 1 bit a droite pourconserver le 1 a l'endroit que l'on veut tester } - - input->i_record++; //on incrémente i record pour aller a l'élèment suivant on réinitialise i_octet et + input->octet[8]=0; //On passe le derneir élèment de octet a 0 pour marquer la fin de chaine de caractère + input->i_record++; //on incrémente i record pour aller a l'élèment suivant on réinitialise i_octet et input->i_octet=0; - input->nb_octets=input->nb_octets+input->record_length; + input->nb_octets=input->nb_octets+input->record_length; //On ajoute la taille du record dans nb_octets pour conserver le bon nombred'élèment traité } - - bit=input->octet[input->i_octet]; //On passe alors bit a la valeur de octet[0] - input->i_octet++; //on incrémente ensuite le compteur - if(input->i_octet=8) - { - for (input->i_octet=0;input->i_octet<8;input->i_octet++) //Comme précédemment on récupère les 1 et les 0 de record pour les passé dans octet - { - if((input->record[input->i_record]>>1)&1) - { - input->octet[7-input->i_octet]='1'; - } - else - { - input->octet[7-input->i_octet]='0'; - } + bit=input->octet[input->i_octet]; //On passe alors bit a la valeur de octet[0] + input->i_octet++; //on incrémente ensuite le compteur + if(input->i_octet==8){ // Si on a écrit huit bit dans octet on va aller tester l'élèment suivant de record + x = input->record[input->i_record] ; + for(i=0;i<8;i++) { + if(x&b) input->octet[i]='1'; + else input->octet[i]='0'; + b=b>>1; } + input->octet[8]=0; input->i_record++; - input->i_octet=0; - if(input->i_record=BLOCK_SIZE) //si on a parcouru tous le buffer on repasse a 0 la longueur - { + input->i_octet=0;; + if(input->i_record==BLOCK_SIZE){ //si on a parcouru tous le buffer on repasse a 0 la longueur input->record_length=0; } } - return bit; // on renvoie le bit + return bit; // on renvoie le bit } int Ferm_Bit(Bin_file *fichier) { - unsigned char octet,b; + unsigned char octet,b; // On déclare deux unsigned char octet et b qui auront la même utilité que dans Ec_Bit int nb_octets=fichier->nb_octets; - - if(fichier->mode="w") - { - if(fichier->i_octet!=0) + + if(fichier->mode="w") // Si le fichier a été ouvert en mode écriture on va aller écrire la fin du buffer + { // dans le fichier. + if(fichier->i_octet!=0) //Pour cela on répète le même principe que dans Ec_Bit { octet=0; b=0x80; @@ -147,30 +137,35 @@ int Ferm_Bit(Bin_file *fichier) fwrite(fichier->record,1,BLOCK_SIZE,fichier->file); } } - fclose(fichier->file); + fclose(fichier->file); //On ferme ensuite le fichier et on libère l'espace occupé par le srtuct Bin_File. free(fichier); return nb_octets; } - -int main() -{ +/* +void main() +{ Bin_file *p; + char s[16]; int i; p=Ouv_Bit("test.txt",'r'); - printf("%d",p->record_length); - /* - for(i=0;i<32762;i++) - { - Ec_Bit(p,'1'); + printf("%i\n",p->record_length); + for (i=0;i<16;i++){ + s[i]=Lec_Bit(p); } - */ - for(i=0;i<32762;i++) - { - printf("%c",Lec_Bit(p)); + for(i=0;i<16;i++){ + printf("%c",s[i]); } - int n=Ferm_Bit(p); - printf("\n"); - printf("%i\n",n); - return 0; + Ferm_Bit(p); + p=Ouv_Bit("test.txt","w"); + Ec_Bit(p,'0'); + Ec_Bit(p,'1'); + Ec_Bit(p,'1'); + Ec_Bit(p,'0'); + Ec_Bit(p,'0'); + Ec_Bit(p,'1'); + Ec_Bit(p,'1'); + Ec_Bit(p,'0'); + Ferm_Bit(p); } +*/ \ No newline at end of file diff --git a/gestion_des_fichiers/gestion_fichiers.h b/gestion_des_fichiers/gestion_fichiers.h index 51f04f0..9ef940d 100644 --- a/gestion_des_fichiers/gestion_fichiers.h +++ b/gestion_des_fichiers/gestion_fichiers.h @@ -4,18 +4,27 @@ #ifndef __GESTION_FICHIERS__ #define __GESTION_FICHIERS__ #include -#define BLOCK_SIZE 4096 +#define BLOCK_SIZE 128 //il faut changer sa valeur pour les tests avec blocsize = nb d'octet qu'on veut écrire typedef struct { FILE*file; // Identificateur fichier - char mode; // Mode de lecture r ou w - unsigned char record[BLOCK_SIZE]; // Tampon pour lire ou écrire - int record_length; // nombre d'élèments du tampon - int i_record; // indice dans le tampon - char octet[8]; // On découpe l'octet en 8 caractère - int i_octet; // indice dansl'octet - int nb_octets; // Nb octet lis/écrit + char mode; //Mode de lecture r ou w + unsigned char record[BLOCK_SIZE]; //Tampon pour lire ou écrire + int record_length; //nombre d'élèments du tampon + int i_record; //indice dans le tampon + char octet[9]; //On découpe l'octet en 8 caractère + int i_octet; //indice dansl'octet + int nb_octets; //Nb octet lis/écrit }Bin_file; + +Bin_file *Ouv_bit(char *p,char mode); + +void Ec_Bit(Bin_file *output,char bit); + +char Lec_Bit(Bin_file*input); + +int Ferm_Bit(Bin_file *fichier); + #endif \ No newline at end of file diff --git a/gestion_des_fichiers/test.txt b/gestion_des_fichiers/test.txt index 03b7f0a..ac0307c 100644 --- a/gestion_des_fichiers/test.txt +++ b/gestion_des_fichiers/test.txt @@ -1 +1 @@ -AAABBBCCCCCDDDDDD \ No newline at end of file +DDDCCCBBBBBAAAAAA \ No newline at end of file diff --git a/gestion_des_fichiers/text.txt b/gestion_des_fichiers/text.txt deleted file mode 100644 index 728a638..0000000 --- a/gestion_des_fichiers/text.txt +++ /dev/null @@ -1,3 +0,0 @@ -NNN -dede -salut \ No newline at end of file diff --git a/main_compress.c b/main_compress.c index 7a800eb..988cee2 100644 --- a/main_compress.c +++ b/main_compress.c @@ -1,12 +1,12 @@ #include #include "arbre_de_codage/arbre_binaire.c" -#include "arbre_de_codage/liste.c" - -Freq freq_apparition(FILE *file); -arbre huffman(arbre H, Freq L); -void quicksort(Freq L, Freq deb, Freq fin); -Freq partition (Freq L, Freq deb, Freq fin); +#define ASCII_EXT 256 +arbre huffman(arbre H, int Tp[], int Tl[]); +void frequence(int Tp[], int Tl[], FILE *file); +void tri_tab(int T[],int T2[],int n); +void afficher_tab(int Tp[], int Tl[], int n); +void init_tab(int T[], int Elt, int n); // main_compress.c [nom_du_fichier_a_compresser] int main(int argc, char **argv){ @@ -24,167 +24,113 @@ int main(int argc, char **argv){ printf("\nErreur : Fichier %s inexistant\n",filename); return -2; } - - // Récupération des fréquences d'apparition des caractères dans le fichier - Freq tmp,freq; - freq = freq_apparition(file); - tmp=freq; - // Affichage pour vérification - while(!est_liste_vide(tmp)){ - printf("%d (%d)\n",tete_lettre(tmp),tete_freq(tmp)); - tmp=queue(tmp); - } - - // freq à ordonner dans l'ordre croissant - printf("Test Huffman\n"); + // Récupérer fréquence + int Tp[ASCII_EXT],Tl[ASCII_EXT]; + init_tab(Tp,-1,ASCII_EXT); + init_tab(Tl,-1,ASCII_EXT); + int compteur; + compteur=0; + frequence(Tp,Tl,file); + // Tri + tri_tab(Tp,Tl,ASCII_EXT); + afficher_tab(Tp,Tl,ASCII_EXT); arbre huff; - huff = huffman(creer_arbre_vide(),freq); - printf("FIN Test Huffman\n"); - + huff = huffman(creer_arbre_vide(),Tp,Tl); return 0; } -Freq freq_apparition(FILE *file){ - Freq text; - text = creer_liste_vide(); - int c; - while((c=fgetc(file))!=EOF){ - if(liste_rechercher(c,text)==1){ - text=incrementer(c,text); - } - else{ - text=ajouter(1,c,text); - } +void init_tab(int T[], int Elt, int n){ + int i; + for(i=0;iT[j]){ + tmp=T[i]; + tmp2=T2[i]; + T[i]=T[j]; + T2[i]=T2[j]; + T[j]=tmp; + T2[j]=tmp2; + } + } + } +} + +void afficher_tab(int Tp[], int Tl[], int n){ + printf("\n"); + int i; + for (i=0;isuiv->suiv != NULL)||i<50){ - printf("Test n°%d \n",i++); - l=L; - afficher(l); - int al,bl,ap,bp; - al = tete_lettre(L); - ap = tete_freq(L); - L = queue(L); - bl = tete_lettre(L); - bp = tete_freq(L); - L = queue(L); + compteur=compteur_tab(Tl,ASCII_EXT); + while(compteur != 1){ + printf("\n Test n°%d \n",i++); + int l1,l2,p1,p2; + l1=Tl[i_index_min_tab(Tl,1,ASCII_EXT)]; + p1=Tp[i_index_min_tab(Tl,1,ASCII_EXT)]; + l2=Tl[i_index_min_tab(Tl,2,ASCII_EXT)]; + p2=Tp[i_index_min_tab(Tl,2,ASCII_EXT)]; arbre fg,fd; - fg=creer_feuille(al,ap); - fd=creer_feuille(bl,bp); - H=creer_arbre_huffman(0,ap+bp,fg,fd); - printf("Test insérer\n"); - l=L; - afficher(l); - L=inserer(ajouter(0,ap+bp,creer_liste_vide()),L); - l=L; - afficher(l); - printf("Affichage vérification\n"); + fg=creer_feuille(l1,p1); + fd=creer_feuille(l2,p2); + H=creer_arbre_huffman(0,p1+p2,fg,fd); + // ajouter le nouveau poid + compteur--; } return H; } - -Freq partition (Freq L, Freq deb, Freq fin) -{ - int permu; - int pivot; - Freq compt = deb; - Freq tmp; - if (!est_liste_vide(deb)) - { - pivot = deb -> nb; - compt = deb; - tmp = deb -> suiv; - while(tmp != (fin -> suiv)) - { - if(tmp -> nb) - { - permu = tmp->nb; - tmp = tmp -> suiv; - compt -> nb = permu; - } - tmp = tmp -> suiv; - } - permu = deb -> nb; - deb -> nb = compt -> nb; - compt -> nb=permu; - } - return compt; -} - -void quicksort(Freq L, Freq deb, Freq fin) -{ - if ((deb -> nb) < (fin -> nb)) - { - Freq pivot = partition(L,deb,fin); - if(!est_liste_vide(pivot)) - { - //quicksort(L,deb,precedent(L,pivot->nb)); - } - } -} - -/* -Freq fusion(Freq L, int i, int m, int j) -{ - int tmp,u,k,v; - tmp=j-i+1; - k=0; - u=-i; - v=m; - while ((u