62 lines
1.9 KiB
C
62 lines
1.9 KiB
C
#include "huftree.h"
|
|
#include "buffer.h"
|
|
#include "display.h"
|
|
#include "decompress.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
void decompress(FILE* source, FILE* dest) {
|
|
// ÉTAPE 1 : lecture du nombre de caractères originel. Cela permet
|
|
// d'ignorer les bits d'alignement en fin de fichier
|
|
uint64_t original_count = 0;
|
|
fread(&original_count, sizeof(original_count), 1, source);
|
|
printVerbose("Lecture du nombre de caractères : %d.\n", original_count);
|
|
|
|
if (original_count == 0) {
|
|
// Cas particulier : fichier vide, rien à restituer
|
|
return;
|
|
}
|
|
|
|
// ÉTAPE 2 : reconstruction de l'arbre à partir des données linéarisées
|
|
printVerbose("Reconstruction de l'arbre de Huffman.\n");
|
|
ReadBuffer input = createReadBuffer(source);
|
|
HufTree tree = readTree(&input);
|
|
|
|
if (isVerbose()) {
|
|
printTree(tree);
|
|
}
|
|
|
|
// ÉTAPE 3 : lecture des données compressées et interprétation grâce
|
|
// à l'arbre de Huffman reconstitué
|
|
printVerbose("\nLecture et interprétation des données compressées.\n");
|
|
char next_bit = getBuffer(&input);
|
|
uint64_t wrote_count = 0;
|
|
|
|
while (next_bit != -1 && wrote_count < original_count) {
|
|
HufTree current = tree;
|
|
|
|
// Descente dans l'arbre, allant à gauche si un '0' est rencontré
|
|
// ou à droite si un '1' est rencontré. Arrêt dès l'arrivée sur
|
|
// une feuille
|
|
while (
|
|
next_bit != -1 &&
|
|
current->child_l != NULL && current->child_r != NULL
|
|
) {
|
|
if (next_bit == 0) {
|
|
current = current->child_l;
|
|
} else {
|
|
current = current->child_r;
|
|
}
|
|
|
|
next_bit = getBuffer(&input);
|
|
}
|
|
|
|
// La valeur de la feuille trouvée est le caractère compressé :
|
|
// on l'écrit dans le fichier
|
|
fputc(current->value, dest);
|
|
wrote_count++;
|
|
}
|
|
|
|
freeTree(tree);
|
|
}
|