From e915bd3080ac60fe82f54269a41236561c7b10d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre=20=E2=9C=8F?= Date: Sun, 20 Nov 2016 15:57:15 +0100 Subject: [PATCH] Renommage name -> value, frequency -> count dans HufTree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialisation de value à -1 lorsque aucune valeur --- inc/huftree.h | 14 ++++++-------- src/decompress.c | 7 ++++++- src/display.c | 2 +- src/huftree.c | 30 +++++++++++++++++------------- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/inc/huftree.h b/inc/huftree.h index f46dbfb..a7dd95a 100644 --- a/inc/huftree.h +++ b/inc/huftree.h @@ -16,15 +16,13 @@ typedef struct ReadBuffer ReadBuffer; typedef struct HufVertex HufVertex; typedef HufVertex* HufTree; struct HufVertex { - // Indique la fréquence d'apparition de la lettre du sommet - // dans le corpus original, ou bien la somme des fréquences - // de ses enfants (si ce n'est pas une feuille) - double frequency; + // Caractère associé à ce sommet ou -1 s'il n'y a aucun caractère + // associé (notamment s'il s'agit d'une branche) + unsigned int value; - // Caractère du corpus original associé à ce sommet. Uniquement - // valable pour les feuilles. Pour les autres sommets, la valeur - // de `name` n'est pas garantie - int name; + // Indique l'effectif du caractère associée à ce sommet + // dans le fichier source, ou -1 s'il n'y a aucun caractère associé + bytecount count; // Pointeurs vers les deux enfants de ce sommet. Ils valent tous // deux NULL si le sommet est une feuille. À noter qu'un sommet diff --git a/src/decompress.c b/src/decompress.c index 8b8464b..6dfc9c1 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -12,6 +12,11 @@ void decompress(FILE* source, FILE* dest) { 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); @@ -48,7 +53,7 @@ void decompress(FILE* source, FILE* dest) { // La valeur de la feuille trouvée est le caractère compressé : // on l'écrit dans le fichier - fputc(current->name, dest); + fputc(current->value, dest); wrote_count++; } diff --git a/src/display.c b/src/display.c index e4c067d..8b019bb 100644 --- a/src/display.c +++ b/src/display.c @@ -85,7 +85,7 @@ void _subPrintTree(HufTree tree, wchar_t* buffer, int length) { } else { // Affichage d'une feuille de l'arbre, correspondant // à un caractère du corpus - printVerbose("%c\n", _safeChar(tree->name)); + printVerbose("%c\n", _safeChar(tree->value)); } } diff --git a/src/huftree.c b/src/huftree.c index ce0d633..6bb05f9 100644 --- a/src/huftree.c +++ b/src/huftree.c @@ -48,8 +48,8 @@ HufTree createTree(bytecount* counts) { if (counts[i] > 0) { remaining[next_index] = malloc(sizeof(*remaining[next_index])); - remaining[next_index]->name = i; - remaining[next_index]->frequency = counts[i]; + remaining[next_index]->value = i; + remaining[next_index]->count = counts[i]; remaining[next_index]->child_l = NULL; remaining[next_index]->child_r = NULL; @@ -80,7 +80,8 @@ HufTree createTree(bytecount* counts) { // Création d'un sommet parent P pour A et B HufVertex* parent = malloc(sizeof(*parent)); - parent->frequency = min_vert->frequency + sec_min_vert->frequency; + parent->value = -1; + parent->count = min_vert->count + sec_min_vert->count; parent->child_l = min_vert; parent->child_r = sec_min_vert; @@ -118,8 +119,8 @@ void _findMinimalVertices( size_t* min_index, size_t* sec_min_index ) { // Initialisation de telle sorte qu'initialement - // on ait `freq(min_index) < freq(sec_min_index)` - if (vertices[0]->frequency < vertices[1]->frequency) { + // on ait `count(min_index) < count(sec_min_index)` + if (vertices[0]->count < vertices[1]->count) { *min_index = 0; *sec_min_index = 1; } else { @@ -128,14 +129,14 @@ void _findMinimalVertices( } for (size_t i = 2; i < size; i++) { - double freq = vertices[i]->frequency; + double freq = vertices[i]->count; - if (freq < vertices[*min_index]->frequency) { + if (freq < vertices[*min_index]->count) { // Sommet de valeur inférieure au minimum trouvé, la valeur // devient le nouveau minimum, le minimum devient second minimum *sec_min_index = *min_index; *min_index = i; - } else if (freq < vertices[*sec_min_index]->frequency) { + } else if (freq < vertices[*sec_min_index]->count) { // Sommet de valeur entre le minimum et le second minimum trouvé, // la valeur devient le nouveau second minimum *sec_min_index = i; @@ -163,7 +164,7 @@ void writeTree(HufTree tree, WriteBuffer* buffer) { // Écriture de la valeur du sommet for (int i = 7; i >= 0; i--) { - putBuffer((tree->name & (1 << i)) != 0, buffer); + putBuffer((tree->value & (1 << i)) != 0, buffer); } } } @@ -176,17 +177,20 @@ HufTree readTree(ReadBuffer* buffer) { if (bit == 1) { // Sommet avec enfants + tree->value = -1; + tree->count = -1; tree->child_l = readTree(buffer); tree->child_r = readTree(buffer); } else if (bit == 0) { // Feuille de l'arbre - int name = 0; + int value = 0; for (int i = 7; i >= 0; i--) { - name |= getBuffer(buffer) << i; + value |= getBuffer(buffer) << i; } - tree->name = name; + tree->value = value; + tree->count = 0; tree->child_l = NULL; tree->child_r = NULL; } @@ -241,7 +245,7 @@ void _labelVertex(HufVertex vertex, char** labels, char* label, size_t length) { } else { // Si le sommet est une feuille, étiquetage du caractère // associé avec l'étiquette passée en paramètre. Fin de la récursion - labels[vertex.name] = label; + labels[vertex.value] = label; } }