DRAFT: compress function added!

This commit is contained in:
Mylloon 2021-12-24 15:45:43 +01:00
parent 33e0e3fdb6
commit b745df67f4
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
2 changed files with 59 additions and 21 deletions

43
arbre.c
View file

@ -1,8 +1,10 @@
#include "arbre.h"
void listeVersArbre(Liste *liste) {
int listeVersArbre(Liste *liste) {
Cellule *curseur = *liste;
int nombreLettresDansFichier = 0;
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
Cellule *nouvelleCellule;
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->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
*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;
}
}
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
lettresListe[*i].lettre = arbre->lettre; // ajout de la lettre
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) {
if (arbre->lettre == '\0') { // free aussi les mini-racines
freeArbre(arbre->gauche);
@ -53,9 +60,9 @@ void freeArbre(Arbre arbre) {
free(arbre); // free du noeud courant
}
Lettre * arbreVersListe(Arbre arbre, int taille, int *tailleTotale) {
Lettre *lettres;
if ((lettres = (Lettre*)malloc(taille * sizeof(Lettre))) == NULL) { // on alloue la liste qui va contenir nos caractères
Entete *arbreVersListe(Arbre arbre, int taille, int *tailleTotale) {
Entete *lettres;
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
exit(1);
}
@ -66,10 +73,32 @@ Lettre * arbreVersListe(Arbre arbre, int taille, int *tailleTotale) {
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) {
/* fclose temporaire pour supprimer les warnings */
fclose(entree);
fclose(sortie);
int nombreLettresDansFichier; // initialisé par `listeVersArbre`
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) {

37
arbre.h
View file

@ -9,15 +9,15 @@
// Définition de l'Arbre.
typedef Cellule *Arbre;
// Définition d'une lettre/caractère au sens large
typedef struct lettre {
// Définition d'une lettre/caractère pour l'entete
typedef struct entete {
char lettre; // la lettre / caractère
int code; // code binaire
int longueur; // longueur du code
} Lettre;
} Entete;
// Convertis une liste (struct Liste) en arbre (struct Arbre).
void listeVersArbre(Liste *liste);
// Convertis une liste (struct Liste) en arbre (struct Arbre) et renvoie la taille des caractères valides de la liste.
int listeVersArbre(Liste *liste);
// Encode un fichier.
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.
-> `arbre` l'arbre binaire de huffman
-> `codeActuel` monte progresssivement quand on parcours l'arbre et c'est la valeur assigné aux noeuds
-> `longueur` la profondeur du noeud dans l'arbre
-> `lettresListe` notre liste de lettre
-> `i` nous permet de se balader dans la liste `lettresListe` (c'est l'on se trouve)
-> `longueurTotale` est la longueur totale du code en sortie en bits
- `arbre` l'arbre binaire de huffman
- `codeActuel` monte progresssivement quand on parcours l'arbre et c'est la valeur assigné aux noeuds
- `longueur` la profondeur du noeud dans l'arbre
- `lettresListe` notre liste de lettre
- `i` nous permet de se balader dans la liste `lettresListe` (c'est l'on se trouve)
- `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.
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).
Lettre * arbreVersListe(Arbre arbre, int taille, int *tailleTotale);
// Convertis un arbre (struct Arbre/Liste) en liste (struct Entete).
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