diff --git a/arbre.c b/arbre.c index 20863d1..5ea56ad 100644 --- a/arbre.c +++ b/arbre.c @@ -112,7 +112,7 @@ void enteteVersFichier(Entete *enteteListe, int nombreLettresDansFichier, int lo } void huffmanVersFichier(FILE *entree, FILE *sortie, Entete *enteteListe, int nombreLettresDansFichier) { - int buffer = 0, tailleBufferActuelle = 0, sizeOfInt = sizeof(int) * 8; // *8 car "long unsigned int" d'après GCC + int buffer = 0, tailleBufferActuelle = 0, sizeOfInt = sizeof(int) * 8; // *8 car quelque fois certains caractères sont mal encodés (en plus ça réduit la taille du fichier final) char lettre = 'a'; // initialisation pour éviter un warning while (lettre != EOF) { // on parcours le fichier lettre = fgetc(entree); @@ -157,8 +157,7 @@ Entete recuperationLettre(char lettre, Entete *enteteListe, int nombreLettresDan } Arbre lectureDonnees(FILE *fichier, int *tailleTotale) { - int nombreLettresDansFichier; - int lecture = 0; // bytes lues + int nombreLettresDansFichier, lecture = 0; // bytes lues lecture += fread(&nombreLettresDansFichier, sizeof(int), 1, fichier); lecture += fread(tailleTotale, sizeof(int), 1, fichier); @@ -177,18 +176,17 @@ Arbre lectureDonnees(FILE *fichier, int *tailleTotale) { // Ajout de la lettre à l'arbre Cellule *curseur = arbre; - int gaucheOuDroite, mask = 1; // mask est le masque de bit appliqué pour savoir si on doit aller a la gauche ou a la droite de l'arbre + int mask = 1; // mask est le masque de bit appliqué pour savoir si on doit aller a la gauche ou a la droite de l'arbre mask <<= entete[i].longueur - 1; // décalage vers la gauche de la longueur de la lettre - 1 for (int j = 0; j < entete[i].longueur; j++) { - gaucheOuDroite = entete[i].code & mask; entete[i].code <<= 1; // décalage de 1 vers la gauche pour éviter la segfault - if (!gaucheOuDroite) { // gauche - if (curseur->gauche == NULL) curseur->gauche = allouerCellule('\0'); // on remplace NULL par le caractère correspondant - curseur = curseur->gauche; - } else { // droite + if (entete[i].code & mask) { // droite if (curseur->droite == NULL) curseur->droite = allouerCellule('\0'); // on remplace NULL par le caractère correspondant curseur = curseur->droite; + } else { // gauche + if (curseur->gauche == NULL) curseur->gauche = allouerCellule('\0'); // on remplace NULL par le caractère correspondant + curseur = curseur->gauche; } } curseur->lettre = entete->lettre; // on assigne la bonne lettre correspondante @@ -196,12 +194,36 @@ Arbre lectureDonnees(FILE *fichier, int *tailleTotale) { free(entete); // on libère l'entête car on en a plus besoin - printf("%d bytes lus.\n", lecture); + printf("%d bytes lus pour reconstruire l'arbre.\n", lecture); return arbre; } void huffmanDepuisFichier(FILE *entree, FILE *sortie, Arbre arbre, int tailleTotale) { - // TODO + int mask = 1, buffer, bitsLus = 0, lecture = 0, sizeOfInt = sizeof(int) * 8; + int bitsMax = tailleTotale / sizeOfInt; + + if(tailleTotale % sizeOfInt != 0) bitsMax++; // parce que c'est un arbre binaire + + mask <<= sizeOfInt - 1; // on récupère le bon bit + + Cellule * curseur = arbre; + for (int i = 0; i < bitsMax; i++) { // on parcours le fichier + lecture += fread(&buffer, sizeof(int), 1, entree); + + for (int j = 0; bitsLus < tailleTotale && j < sizeOfInt; j++) { + if (curseur->lettre != '\0') { // update de l'arbre si on est sur une 'mini-racine' + fprintf(sortie, "%c", curseur->lettre); // on ajoute le caractères dans le fichier de sortie + curseur = arbre; + } + + if(mask & buffer) curseur = curseur->droite; // droite + else curseur = curseur->gauche; // gauche + bitsLus++; // on incrémente bitsLus de 1 + buffer <<= 1; // update du buffer + } + } + + printf("%d bytes lus pour reconstruire le fichier.\n", lecture); } void decompression(FILE *entree, FILE *sortie) {