diff --git a/tp-huffman/hufftree.c b/tp-huffman/hufftree.c index affed94..fc3a71f 100644 --- a/tp-huffman/hufftree.c +++ b/tp-huffman/hufftree.c @@ -1,4 +1,5 @@ #include "hufftree.h" +#include "binheap.h" #include "error.h" #include @@ -9,8 +10,8 @@ /* Création d'une feuille */ huffnode *create_huffleaf(int byte, int freq) { huffnode *h = malloc(sizeof(huffnode)); - h -> freq = 0; - h -> byte = 0; + h -> freq = freq; + h -> byte = byte; h -> leftchild = NULL; h -> rightchild = NULL; return h; @@ -83,27 +84,68 @@ bool compare_hufftree(void *p1, void *p2) { huffnode *datafile_to_hufftree(FILE *input) { /* Phase 1: création du tableau de fréquences */ - int *tab = malloc(256 * sizeof(int)); + int *tab = malloc(256 * sizeof(int)); + for (int i = 0; i < 256; i++) { + tab[i] = 0; + } + int c; + while ((c = fgetc(input)) != EOF) { + tab[c]++; + } - /* Phase 2: intialisation de la file de priorité à partir du tableau de - * fréquences */ + /* Phase 2: intialisation de la file de priorité à partir du tableau de + * fréquences */ - // À écrire + binheap *heap = create_binheap(compare_hufftree); + for (int i = 0; i < 256; i++) { + if (tab[i] > 0) { + huffnode *h = create_huffleaf(i, tab[i]); + push_binheap(heap, h); + } + } + free(tab); - /* Phase 3: création de l'arbre de Huffman à partir de la file de priorités */ + /* Phase 3: création de l'arbre de Huffman à partir de la file de priorités */ - // À écrire - - return NULL; + while (getsize_binheap(heap) > 1) { + huffnode *pl = popmin_binheap(heap); + huffnode *pr = popmin_binheap(heap); + huffnode *h = merge_hufftree(pl, pr); + push_binheap(heap, h); + } + huffnode *root = popmin_binheap(heap); + free(heap); + return root; } /* Écriture de l'arbre de Huffman dans le futur fichier compressé */ void save_hufftree(huffnode *p, FILE *f) { - // À écrire + if (isleaf_huffnode(p)) { + fputc('L', f); + fputc(p->byte, f); + } else { + fputc('N', f); + save_hufftree(p->leftchild, f); + save_hufftree(p->rightchild, f); + } } /* Lecture de l'arbre de Huffman dans le fichier compressé */ huffnode *read_hufftree(FILE *f) { - // À écrire - return NULL; + int c = fgetc(f); + if (c == EOF) { + ERROR("read_hufftree: fin de fichier inattendue\n"); + exit(1); + } + if (c == 'L') { + int byte = fgetc(f); + return create_huffleaf(byte, 0); + } else if (c == 'N') { + huffnode *pl = read_hufftree(f); + huffnode *pr = read_hufftree(f); + return merge_hufftree(pl, pr); + } else { + ERROR("read_hufftree: caractère inattendu\n"); + exit(1); + } } diff --git a/tp-huffman/hufftree.o b/tp-huffman/hufftree.o index 3dda154..fa9e825 100644 Binary files a/tp-huffman/hufftree.o and b/tp-huffman/hufftree.o differ diff --git a/tp-huffman/main.o b/tp-huffman/main.o index c1f81d2..880baaa 100644 Binary files a/tp-huffman/main.o and b/tp-huffman/main.o differ diff --git a/tp-huffman/test.txt b/tp-huffman/test.txt new file mode 100644 index 0000000..3c59a58 --- /dev/null +++ b/tp-huffman/test.txt @@ -0,0 +1 @@ +Hello world ! diff --git a/tp-huffman/test.txt.huff b/tp-huffman/test.txt.huff new file mode 100644 index 0000000..e69de29 diff --git a/tp-huffman/tp b/tp-huffman/tp index 3f68ef2..3187c0e 100755 Binary files a/tp-huffman/tp and b/tp-huffman/tp differ