DRAFT: compress function added!
This commit is contained in:
parent
33e0e3fdb6
commit
b745df67f4
2 changed files with 59 additions and 21 deletions
43
arbre.c
43
arbre.c
|
@ -1,8 +1,10 @@
|
||||||
#include "arbre.h"
|
#include "arbre.h"
|
||||||
|
|
||||||
void listeVersArbre(Liste *liste) {
|
int listeVersArbre(Liste *liste) {
|
||||||
Cellule *curseur = *liste;
|
Cellule *curseur = *liste;
|
||||||
|
int nombreLettresDansFichier = 0;
|
||||||
while (curseur != NULL) { // parcours de la liste
|
while (curseur != NULL) { // parcours de la liste
|
||||||
|
if (curseur->lettre != '\0') nombreLettresDansFichier++; // +1 au compteur si c'est bien une lettre
|
||||||
if (curseur->suivant != NULL) { // on créer un mini-arbre qu'on colle au reste de l'arbre seulement si le suivant existe
|
if (curseur->suivant != NULL) { // on créer un mini-arbre qu'on colle au reste de l'arbre seulement si le suivant existe
|
||||||
Cellule *nouvelleCellule;
|
Cellule *nouvelleCellule;
|
||||||
if ((nouvelleCellule = (Cellule*)malloc(sizeof(Cellule))) == NULL) { // on alloue de la mémoire pour notre nouvelle cellule (mini-racine)
|
if ((nouvelleCellule = (Cellule*)malloc(sizeof(Cellule))) == NULL) { // on alloue de la mémoire pour notre nouvelle cellule (mini-racine)
|
||||||
|
@ -15,6 +17,8 @@ void listeVersArbre(Liste *liste) {
|
||||||
nouvelleCellule->lettre = '\0';
|
nouvelleCellule->lettre = '\0';
|
||||||
nouvelleCellule->frequence = nouvelleCellule->gauche->frequence + nouvelleCellule->droite->frequence;
|
nouvelleCellule->frequence = nouvelleCellule->gauche->frequence + nouvelleCellule->droite->frequence;
|
||||||
|
|
||||||
|
if (curseur->suivant->lettre != '\0') nombreLettresDansFichier++; // +1 si le suivant est aussi une lettre (membre droit)
|
||||||
|
|
||||||
curseur = curseur->suivant->suivant; // on va au suivant 2x car on a déjà ajouté le suivant en tant que membre droit
|
curseur = curseur->suivant->suivant; // on va au suivant 2x car on a déjà ajouté le suivant en tant que membre droit
|
||||||
|
|
||||||
*liste = curseur; // on change le point de départ de notre liste pour ne pas traiter en boucle les anciennes cellules
|
*liste = curseur; // on change le point de départ de notre liste pour ne pas traiter en boucle les anciennes cellules
|
||||||
|
@ -25,9 +29,11 @@ void listeVersArbre(Liste *liste) {
|
||||||
curseur = curseur->suivant;
|
curseur = curseur->suivant;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nombreLettresDansFichier;
|
||||||
}
|
}
|
||||||
|
|
||||||
void assignationCode(Arbre arbre, int codeActuel, int longueur, Lettre *lettresListe, int *i, int *longueurTotale) {
|
void assignationCode(Arbre arbre, int codeActuel, int longueur, Entete *lettresListe, int *i, int *longueurTotale) {
|
||||||
if (arbre->lettre != '\0') { // si c'est une lettre qu'on regarde
|
if (arbre->lettre != '\0') { // si c'est une lettre qu'on regarde
|
||||||
lettresListe[*i].lettre = arbre->lettre; // ajout de la lettre
|
lettresListe[*i].lettre = arbre->lettre; // ajout de la lettre
|
||||||
lettresListe[*i].code = codeActuel; // assignation de son code
|
lettresListe[*i].code = codeActuel; // assignation de son code
|
||||||
|
@ -44,6 +50,7 @@ void assignationCode(Arbre arbre, int codeActuel, int longueur, Lettre *lettresL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Libère en mémoire un Arbre
|
||||||
void freeArbre(Arbre arbre) {
|
void freeArbre(Arbre arbre) {
|
||||||
if (arbre->lettre == '\0') { // free aussi les mini-racines
|
if (arbre->lettre == '\0') { // free aussi les mini-racines
|
||||||
freeArbre(arbre->gauche);
|
freeArbre(arbre->gauche);
|
||||||
|
@ -53,9 +60,9 @@ void freeArbre(Arbre arbre) {
|
||||||
free(arbre); // free du noeud courant
|
free(arbre); // free du noeud courant
|
||||||
}
|
}
|
||||||
|
|
||||||
Lettre * arbreVersListe(Arbre arbre, int taille, int *tailleTotale) {
|
Entete *arbreVersListe(Arbre arbre, int taille, int *tailleTotale) {
|
||||||
Lettre *lettres;
|
Entete *lettres;
|
||||||
if ((lettres = (Lettre*)malloc(taille * sizeof(Lettre))) == NULL) { // on alloue la liste qui va contenir nos caractères
|
if ((lettres = (Entete*)malloc(taille * sizeof(Entete))) == NULL) { // on alloue la liste qui va contenir nos caractères
|
||||||
printf("Impossible d'allouer de la mémoire supplémentaire (arbreVersListe).\n"); // gestion de l'erreur
|
printf("Impossible d'allouer de la mémoire supplémentaire (arbreVersListe).\n"); // gestion de l'erreur
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -66,10 +73,32 @@ Lettre * arbreVersListe(Arbre arbre, int taille, int *tailleTotale) {
|
||||||
return lettres;
|
return lettres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Entete *fichierVersListe(FILE *fichier, int *nombreLettresDansFichier, int *tailleTotale) {
|
||||||
|
char lettre = 'a';
|
||||||
|
Liste liste = NULL;
|
||||||
|
while (lettre != EOF) {
|
||||||
|
lettre = fgetc(fichier);
|
||||||
|
ajouterLettre(&liste, lettre);
|
||||||
|
}
|
||||||
|
rewind(fichier);
|
||||||
|
|
||||||
|
trierListe(&liste);
|
||||||
|
*nombreLettresDansFichier = listeVersArbre(&liste);
|
||||||
|
|
||||||
|
return arbreVersListe(liste, *nombreLettresDansFichier, tailleTotale);
|
||||||
|
}
|
||||||
|
|
||||||
void compression(FILE *entree, FILE *sortie) {
|
void compression(FILE *entree, FILE *sortie) {
|
||||||
/* fclose temporaire pour supprimer les warnings */
|
/* fclose temporaire pour supprimer les warnings */
|
||||||
fclose(entree);
|
int nombreLettresDansFichier; // initialisé par `listeVersArbre`
|
||||||
fclose(sortie);
|
int tailleTotale = 0; // taille totale en en bit du fichier en sortie
|
||||||
|
Entete *entete = fichierVersListe(entree, &nombreLettresDansFichier, &tailleTotale);
|
||||||
|
|
||||||
|
// On écrit l'entête du fichier avec la table complète des correspondances
|
||||||
|
enteteVersFichier(entete, nombreLettresDansFichier, tailleTotale, sortie);
|
||||||
|
|
||||||
|
// On écrit les données huffman-isée dans le fichier
|
||||||
|
huffmanVersFichier(entree, sortie, entete, nombreLettresDansFichier);
|
||||||
}
|
}
|
||||||
|
|
||||||
void decompression(FILE *entree, FILE *sortie) {
|
void decompression(FILE *entree, FILE *sortie) {
|
||||||
|
|
37
arbre.h
37
arbre.h
|
@ -9,15 +9,15 @@
|
||||||
// Définition de l'Arbre.
|
// Définition de l'Arbre.
|
||||||
typedef Cellule *Arbre;
|
typedef Cellule *Arbre;
|
||||||
|
|
||||||
// Définition d'une lettre/caractère au sens large
|
// Définition d'une lettre/caractère pour l'entete
|
||||||
typedef struct lettre {
|
typedef struct entete {
|
||||||
char lettre; // la lettre / caractère
|
char lettre; // la lettre / caractère
|
||||||
int code; // code binaire
|
int code; // code binaire
|
||||||
int longueur; // longueur du code
|
int longueur; // longueur du code
|
||||||
} Lettre;
|
} Entete;
|
||||||
|
|
||||||
// Convertis une liste (struct Liste) en arbre (struct Arbre).
|
// Convertis une liste (struct Liste) en arbre (struct Arbre) et renvoie la taille des caractères valides de la liste.
|
||||||
void listeVersArbre(Liste *liste);
|
int listeVersArbre(Liste *liste);
|
||||||
|
|
||||||
// Encode un fichier.
|
// Encode un fichier.
|
||||||
void compression(FILE *entree, FILE *sortie);
|
void compression(FILE *entree, FILE *sortie);
|
||||||
|
@ -27,19 +27,28 @@ void decompression(FILE *entree, FILE *sortie);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Ajoute les valeurs des lettres dans l'arbre récursivement.
|
Ajoute les valeurs des lettres dans l'arbre récursivement.
|
||||||
-> `arbre` l'arbre binaire de huffman
|
- `arbre` l'arbre binaire de huffman
|
||||||
-> `codeActuel` monte progresssivement quand on parcours l'arbre et c'est la valeur assigné aux noeuds
|
- `codeActuel` monte progresssivement quand on parcours l'arbre et c'est la valeur assigné aux noeuds
|
||||||
-> `longueur` la profondeur du noeud dans l'arbre
|
- `longueur` la profondeur du noeud dans l'arbre
|
||||||
-> `lettresListe` notre liste de lettre
|
- `lettresListe` notre liste de lettre
|
||||||
-> `i` nous permet de se balader dans la liste `lettresListe` (c'est là où l'on se trouve)
|
- `i` nous permet de se balader dans la liste `lettresListe` (c'est là où l'on se trouve)
|
||||||
-> `longueurTotale` est la longueur totale du code en sortie en bits
|
- `longueurTotale` est la longueur totale du code en sortie en bits
|
||||||
|
|
||||||
J'essaie de favoriser l'utilisation de pointeur pour éviter de recopier plus fois la même chose en mémoire.
|
J'essaie de favoriser l'utilisation de pointeur pour éviter de recopier plus fois la même chose en mémoire.
|
||||||
Parcours prefixé de l'arbre.
|
Parcours prefixé de l'arbre.
|
||||||
*/
|
*/
|
||||||
void assignationCode(Arbre arbre, int codeActuel, int longueur, Lettre *lettresListe, int *i, int *longueurTotale);
|
void assignationCode(Arbre arbre, int codeActuel, int longueur, Entete *lettresListe, int *i, int *longueurTotale);
|
||||||
|
|
||||||
// Convertis un arbre (struct Arbre) en liste (struct Lettre).
|
// Convertis un arbre (struct Arbre/Liste) en liste (struct Entete).
|
||||||
Lettre * arbreVersListe(Arbre arbre, int taille, int *tailleTotale);
|
Entete *arbreVersListe(Arbre arbre, int taille, int *tailleTotale);
|
||||||
|
|
||||||
|
// Lie le fichier d'entrée pour le transformer en liste (struct Entete) de caractères.
|
||||||
|
Entete *fichierVersListe(FILE *fichier, int *nombreLettresDansFichier, int *tailleTotale);
|
||||||
|
|
||||||
|
// Écrit l'entête avec la table de Huffman dans le fichier.
|
||||||
|
void enteteVersFichier(Entete *lettres, int nombreLettresDansFichier, int longueurTotale, FILE *fichier);
|
||||||
|
|
||||||
|
// Écrit les données une fois traduite après l'algorithme de Huffman dans le fichier de sortie.
|
||||||
|
void huffmanVersFichier(FILE *entree, FILE *sortie, Entete *listeLettres, int nombreLettresDansFichier);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Reference in a new issue