From af83ce011734983160a33dede1c05f04f8726fbf Mon Sep 17 00:00:00 2001 From: untypequicode Date: Thu, 24 Oct 2024 16:29:20 +0200 Subject: [PATCH] update tp-huffman --- tp-huffman/Makefile | 49 ++++++ tp-huffman/alloc.c | 19 ++ tp-huffman/alloc.d | 1 + tp-huffman/alloc.h | 182 +++++++++++++++++++ tp-huffman/alloc.o | Bin 0 -> 7368 bytes tp-huffman/binheap.c | 138 +++++++++++++++ tp-huffman/binheap.d | 1 + tp-huffman/binheap.h | 82 +++++++++ tp-huffman/binheap.o | Bin 0 -> 14528 bytes tp-huffman/dequeue.h | 92 ++++++++++ tp-huffman/dequeue.o | 1 + tp-huffman/dequeue_arm64.o | Bin 0 -> 12248 bytes tp-huffman/dequeue_x86-64.o | Bin 0 -> 16592 bytes tp-huffman/error.h | 58 ++++++ tp-huffman/huffcomp.c | 59 +++++++ tp-huffman/huffcomp.d | 2 + tp-huffman/huffcomp.h | 71 ++++++++ tp-huffman/huffcomp.o | Bin 0 -> 7832 bytes tp-huffman/huffdecomp.c | 34 ++++ tp-huffman/huffdecomp.d | 2 + tp-huffman/huffdecomp.h | 40 +++++ tp-huffman/huffdecomp.o | Bin 0 -> 6832 bytes tp-huffman/hufftree.c | 85 +++++++++ tp-huffman/hufftree.d | 1 + tp-huffman/hufftree.h | 98 +++++++++++ tp-huffman/hufftree.o | Bin 0 -> 8392 bytes tp-huffman/main.c | 312 +++++++++++++++++++++++++++++++++ tp-huffman/main.d | 2 + tp-huffman/main.o | Bin 0 -> 30040 bytes tp-huffman/testprint.c | 340 ++++++++++++++++++++++++++++++++++++ tp-huffman/testprint.d | 2 + tp-huffman/testprint.h | 74 ++++++++ tp-huffman/testprint.o | Bin 0 -> 24280 bytes tp-huffman/tp | Bin 0 -> 64856 bytes 34 files changed, 1745 insertions(+) create mode 100644 tp-huffman/Makefile create mode 100644 tp-huffman/alloc.c create mode 100644 tp-huffman/alloc.d create mode 100644 tp-huffman/alloc.h create mode 100644 tp-huffman/alloc.o create mode 100644 tp-huffman/binheap.c create mode 100644 tp-huffman/binheap.d create mode 100644 tp-huffman/binheap.h create mode 100644 tp-huffman/binheap.o create mode 100644 tp-huffman/dequeue.h create mode 120000 tp-huffman/dequeue.o create mode 100644 tp-huffman/dequeue_arm64.o create mode 100644 tp-huffman/dequeue_x86-64.o create mode 100644 tp-huffman/error.h create mode 100644 tp-huffman/huffcomp.c create mode 100644 tp-huffman/huffcomp.d create mode 100644 tp-huffman/huffcomp.h create mode 100644 tp-huffman/huffcomp.o create mode 100644 tp-huffman/huffdecomp.c create mode 100644 tp-huffman/huffdecomp.d create mode 100644 tp-huffman/huffdecomp.h create mode 100644 tp-huffman/huffdecomp.o create mode 100644 tp-huffman/hufftree.c create mode 100644 tp-huffman/hufftree.d create mode 100644 tp-huffman/hufftree.h create mode 100644 tp-huffman/hufftree.o create mode 100644 tp-huffman/main.c create mode 100644 tp-huffman/main.d create mode 100644 tp-huffman/main.o create mode 100644 tp-huffman/testprint.c create mode 100644 tp-huffman/testprint.d create mode 100644 tp-huffman/testprint.h create mode 100644 tp-huffman/testprint.o create mode 100755 tp-huffman/tp diff --git a/tp-huffman/Makefile b/tp-huffman/Makefile new file mode 100644 index 0000000..9d8204e --- /dev/null +++ b/tp-huffman/Makefile @@ -0,0 +1,49 @@ +# CC=gcc or clang or gcc-14 (on OSX) +CC=gcc + +# Math, big numbers and SDL2 fonts +LDLIBS=-lm + +# The DEBUG_LEVEL (OFF, CRITICAL, ERROR, WARNING, INFO, TRACE) +# is set by default to WARNING in error.h. +# To set it on the command line, force compilation and set it. +# Example: make -B CFLAGS="-DDEBUG_LEVEL=INFO" to see all debug messages +# above the 'INFO' level. + +# clang 14.0.3 does implement the C23 feature __VA_OPTS__ but issues a spurious +# warning. The -Wno-gnu-zero-variadic-macro-arguments disables this warning. +# This flag is ignored by gcc (which implements __VA_OPTS__ without any warning). +ifeq ($(shell uname -s), Darwin) +override CFLAGS += -std=gnu2x -MMD -Wall -pedantic -Wextra -Wshadow -Wpointer-arith \ +-Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wno-gnu-zero-variadic-macro-arguments +endif + +ifeq ($(shell uname -s), Linux) +override CFLAGS += -std=gnu2x -MMD -Wall -pedantic -Wextra -Wshadow -Wpointer-arith \ +-Wcast-qual -Wstrict-prototypes -Wmissing-prototypes +endif + +SOURCES := $(wildcard *.c) +OBJECTS := $(SOURCES:%.c=%.o) +DEPS := $(SOURCES:%.c=%.d) +OBJECTS_NO_SOURCE = dequeue.o + +# Compilation in debug mode by default, to use gdb and valgrind. Warnings produce an error. +all: CFLAGS += -g -O0 -Werror -Wno-unused-parameter -Wno-unused-function +all: tp + +# Once the program works, optimized mode (and no error in case of warning). +nowerror: CFLAGS += -O3 -Wunused-parameter +nowerror: tp + +# Add parser.o scan.o if bison/flex interface. +tp: $(OBJECTS) $(OBJECTS_NO_SOURCE) + $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ $(LDLIBS) + +# Include dependancies generated by gcc -MMD. +-include $(DEPS) + +# Clean all. +.PHONY: clean +clean: + rm -f $(OBJECTS) $(DEPS) tp TAGS core diff --git a/tp-huffman/alloc.c b/tp-huffman/alloc.c new file mode 100644 index 0000000..aa89e9c --- /dev/null +++ b/tp-huffman/alloc.c @@ -0,0 +1,19 @@ +/** + * @file alloc.c + * @brief Fonctions d'allocation mémoire. + */ + +#include "alloc.h" + +void check_null(const char *function, char *file, int line, int n, ...) { + va_list ap; + char *s; + + va_start(ap, n); + for (int i = 0; i < n; i++) { + void *p = va_arg(ap, void *); + s = va_arg(ap, char *); + if (p == NULL) + PRINT_ERROR(KO, "CRITICAL", function, file, line, "%s is NULL.", s); + } +} diff --git a/tp-huffman/alloc.d b/tp-huffman/alloc.d new file mode 100644 index 0000000..f1b5d34 --- /dev/null +++ b/tp-huffman/alloc.d @@ -0,0 +1 @@ +alloc.o: alloc.c alloc.h error.h diff --git a/tp-huffman/alloc.h b/tp-huffman/alloc.h new file mode 100644 index 0000000..8af0886 --- /dev/null +++ b/tp-huffman/alloc.h @@ -0,0 +1,182 @@ +/** + * @file alloc.h + * @brief Macros et fonctions d'allocation mémoire. + * + * @details Les macros MALLOC(), CALLOC() et REALLOC() définies dans ce fichier + * permettent d'allouer de la mémoire dynamiquement, en vérifiant que + * l'allocation a réussi. En cas d'échec, elles affichent un message d'erreur + * sur la sortie erreur, en indiquant la fonction, le fichier et la ligne où + * l'allocation a échoué, et quittent le programme. + * + * La fonction multiple_free() permet de libérer plusieurs pointeurs en + * un seul appel (mais attention, aucun de ces pointeurs ne doit être `NULL`, et + * tous doivent avoir été alloués dynamiquement avant cette libération). + * + * La macro CHECK_NULL() permet de vérifier qu'un ou plusieurs pointeurs ne sont + * pas `NULL`. + * + * La fonction check_null() n'est pas destinée à être utilisée directement, mais + * est utilisée par la macro CHECK_NULL(). + */ + +#ifndef ALLOC_H_ +#define ALLOC_H_ + +#include "error.h" +#include +#include +#include + +/** + * @brief Macro pour allouer de la mémoire en utilisant la fonction malloc(). + * @param p Pointeur à allouer. + * @param num_objects Nombre d'objets à allouer. + * + * @details + * Alloue de la mémoire permettant de stocker `num_objects`, chacun de type + * `*p`. + * + * **Exemple d'utilisation :** + * ``` + * backmove *p; + * MALLOC(p, 10); // Alloue un tableau de 10 backmove. + * ``` + * + * Si l'allocation échoue, affiche un message d'erreur et quitte le programme. + * + * @attention + * Le pointeur `p` doit avoir été déclaré, mais ne pas pointer vers une zone + * déjà allouée dynamiquement (sous peine de créer une fuite mémoire). + * Si `p` pointe déjà vers une zone allouée dynamiquement, il faut utiliser + * REALLOC. + * + * @see REALLOC() + */ + +#define MALLOC(p, num_objects) \ + do { \ + void *tmp = malloc(sizeof *(p) * (num_objects)); \ + if (!tmp) { \ + FATAL("Malloc error."); \ + } \ + (p) = tmp; \ + } while (0) + +/** + * @brief Macro pour allouer de la mémoire en utilisant la fonction calloc(). + * @param p Pointeur à allouer. + * @param num_objects Nombre d'objets à allouer. + * + * @details + * Alloue de la mémoire initialisée à 0, permettant de stocker `num_objects`, + * chacun de type `*p`. + * + * **Exemple d'utilisation :** + * ``` + * backmove *p; + * CALLOC(p, 10); // Alloue un tableau de 10 backmove, initialisé à 0. + * ``` + * + * Si l'allocation échoue, affiche un message d'erreur et quitte le programme. + * + * @attention + * Le pointeur `p` doit avoir été déclaré, mais ne pas pointer vers une zone + * déjà allouée dynamiquement (sous peine de créer une fuite mémoire). + * Si `p` pointe déjà vers une zone allouée dynamiquement, il faut utiliser + * REALLOC. + * + * @sa REALLOC() + */ + +#define CALLOC(p, num_objects) \ + do { \ + void *tmp = calloc((num_objects), sizeof *(p)); \ + if (!tmp) { \ + FATAL("Calloc error."); \ + } \ + (p) = tmp; \ + } \ + while (0) + +/** + * @brief Macro pour réallouer de la mémoire en utilisant la fonction realloc(). + * @param p Pointeur à allouer. + * @param num_objects Nouveau nombre d'objets à allouer. + * + * Ré-alloue la mémoire pointée par un pointeur p, dont la valeur doit avoir été + * retournée précédemment par une fonction d'allocation dynamique (malloc, + * calloc, realloc ou une des macros de ce fichier). + * + * Si l'allocation échoue, affiche un message d'erreur et quitte le programme. + * + * **Exemple d'utilisation :** + * ``` + * backmove *p; + * MALLOC(p, 10); // Alloue un tableau de 10 backmove. + * // ... + * REALLOC(p, 20); // Ré-alloue un tableau de 20 backmove en copiant le tableau + * // précédent en début ce nouveay tableau, et affecte à p + * // l'adresse de la première case de ce tableau. + * ``` + * + * Si l'allocation échoue, affiche un message d'erreur et quitte le programme. + * + * @attention + * Le pointeur `p` doit avoir été déclaré et pointer vers une zone + * déjà allouée dynamiquement. + * + * @sa MALLOC(), CALLOC() + */ + +#define REALLOC(p, num_objects) \ + do { \ + void *tmp = realloc((p), sizeof *(p) * (num_objects)); \ + if (!tmp) { \ + FATAL("Realloc error."); \ + } \ + (p) = tmp; \ + } while (0) + + +/** + * @brief Macro permettant de tester si un ou plusieurs pointeurs sont NULL. + * @param n Nombre de pointeurs à tester. + * @param ... Pointeurs à tester, en alternance avec des chaînes de caractères. + * + * Il doit y avoir un pointeur à tester pour chaque chaîne de caractères, et + * inversement. + * + * La chaîne de caractères qui suit chaque pointeur permet de personnaliser le + * message d'erreur. + * + * @details + * **Exemple d'utilisation :** + * ``` + * CHECK_NULL(3, p1, "Name1", p2, "Name2", p3, "Name3"); + * ``` + * Ici, 3 est le nombre de pointeurs à vérifier, et p1, p2, p3 sont les + * pointeurs. Si `p1` et `p3` sont NULL, la macro affichera un message d'erreur + * de la forme : + *** + [CRITICAL] Name1 is NULL!\n + [CRITICAL] Name3 is NULL! + *** + * @sa check_null() + */ + +#define CHECK_NULL(n, ...) \ + check_null \ + (__func__, __FILE__, __LINE__, \ + n __VA_OPT__( , ) __VA_ARGS__) + +/** + * @brief Ne pas utiliser cette fonction directement, mais à la place la macro + * ::CHECK_NULL(), qui indique dans le message la position de l'erreur dans le + * source. + * + * @sa CHECK_NULL() + */ + +void check_null(const char *function, char *file, int line, int n, ...); + +#endif // ALLOC_H_ diff --git a/tp-huffman/alloc.o b/tp-huffman/alloc.o new file mode 100644 index 0000000000000000000000000000000000000000..f8bd5c05bf4222b6e1823703a42dc9d19475f9f4 GIT binary patch literal 7368 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 YWhBj1>ijXL+3b&S{O4v&390t~0T`jt*#H0l literal 0 HcmV?d00001 diff --git a/tp-huffman/binheap.c b/tp-huffman/binheap.c new file mode 100644 index 0000000..5f8f7ad --- /dev/null +++ b/tp-huffman/binheap.c @@ -0,0 +1,138 @@ +#include "binheap.h" + +/*************************/ +/* Fonctions auxiliaires */ +/*************************/ + +/* La fonction de comparaison pour les tas d'entiers */ +bool fcmp_int(void *x, void *y) { + return *(int *)x < *(int *)y; +} + +/* Fonctions de navigation dans un arbre représenté par un tableau */ +int left_binheap(int i) { + return i*2+1; +} +int right_binheap(int i) { + return i*2+2; +} +int parent_binheap(int i) { + return (i-1)/2; +} +bool isvalid_binheap(binheap *p, int i) { + return i < p->size_heap; +} + +/* Modification de la taille du tableau */ +static void grow_binheap(binheap *p) { + p->size_array *= 2; + p->array = realloc(p->array, p->size_array * sizeof(void *)); + if (p->array == NULL) { + ERROR("Erreur d'allocation mémoire\n"); + exit(EXIT_FAILURE); + } +} + +static void shrink_binheap(binheap *p) { + p->size_array /= 2; + p->array = realloc(p->array, p->size_array * sizeof(void *)); + if (p->array == NULL) { + ERROR("Erreur d'allocation mémoire\n"); + exit(EXIT_FAILURE); + } +} + +/************************/ +/* Fonctions primitives */ +/************************/ + +/* Création d'un tas vide */ +binheap *create_binheap(bool (*fc)(void *, void *)) { + binheap *p = malloc(sizeof(binheap)); + if (p == NULL) { + ERROR("Erreur d'allocation mémoire\n"); + exit(EXIT_FAILURE); + } + p->array = malloc(1 * sizeof(void *)); + if (p->array == NULL) { + ERROR("Erreur d'allocation mémoire\n"); + exit(EXIT_FAILURE); + } + p->size_array = 1; + p->size_heap = 0; + p->fc = fc; + return p; +} + +/* Suppression */ +void delete_binheap(binheap *p) { + if (p != NULL) { + if (p->array != NULL) { + free(p->array); + } + free(p); + } +} + +/* Test du vide */ +bool isempty_binheap(binheap *p) { + return p == NULL || p->size_heap == 0; +} + +/* Récupération de la taille */ +int getsize_binheap(binheap *p) { + return p->size_heap; +} + +/* Insertion d'une valeur */ +void push_binheap(binheap *p, void *val) { + if (p->size_heap == p->size_array) { + grow_binheap(p); + } + p->array[p->size_heap] = val; + p->size_heap++; + int i = p->size_heap - 1; + while (i > 0 && p->fc(p->array[i], p->array[parent_binheap(i)])) { + void *temp = p->array[i]; + p->array[i] = p->array[parent_binheap(i)]; + p->array[parent_binheap(i)] = temp; + i = parent_binheap(i); + } +} + +/* Récupération du minimum sans le retirer */ +void *peekmin_binheap(binheap *p) { + if (isempty_binheap(p)) { + return NULL; + } + return p->array[0]; +} + +/* Récupération du minimum en le retirant */ +void *popmin_binheap(binheap *p) { + if (isempty_binheap(p)) { + return NULL; + } + void *min = p->array[0]; + p->size_heap--; + p->array[0] = p->array[p->size_heap]; + int i = 0; + while (isvalid_binheap(p, left_binheap(i))) { + int j = left_binheap(i); + if (isvalid_binheap(p, right_binheap(i)) && p->fc(p->array[right_binheap(i)], p->array[j])) { + j = right_binheap(i); + } + if (p->fc(p->array[j], p->array[i])) { + void *temp = p->array[i]; + p->array[i] = p->array[j]; + p->array[j] = temp; + i = j; + } else { + break; + } + } + if (p->size_heap < p->size_array / 4) { + shrink_binheap(p); + } + return min; +} diff --git a/tp-huffman/binheap.d b/tp-huffman/binheap.d new file mode 100644 index 0000000..9482ed5 --- /dev/null +++ b/tp-huffman/binheap.d @@ -0,0 +1 @@ +binheap.o: binheap.c binheap.h alloc.h error.h diff --git a/tp-huffman/binheap.h b/tp-huffman/binheap.h new file mode 100644 index 0000000..f01ab75 --- /dev/null +++ b/tp-huffman/binheap.h @@ -0,0 +1,82 @@ +/************************************************************************/ +/** Files de priorité: implémentation d'une tas binaire par un tableau **/ +/************************************************************************/ + +#ifndef BINHEAP_H_ +#define BINHEAP_H_ + +#include "alloc.h" +#include +#include + +// On travaille avec des tas génériques: le type des valeurs n'est pas fixé +// Pour ce faire, les éléments du tas seront des pointeurs génériques (void *). +// Le tas ne contiendra donc pas directement les valeurs mais des pointeurs +// sur celles-ci. +// +// Puisque le type des valeurs n'est pas fixé, la fonction de comparaison qui +// sert à ordonner les éléments du tas est un paramètre de ce tas. On utilise +// pour cela des pointeurs de fonctions: un des champs du type sera un pointeur +// sur une fonction qui associe un Booléen à deux éléments de type void * (qui +// indique si le premier est considéré comme "plus petit" que le deuxième). + +typedef struct { + // Tableau stockant des pointeurs vers chaque valeur du tas + void **array; + // Taille totale du tableau + int size_array; + // Taille du tas (nombres de case utilisées dans le tableau) + int size_heap; + // Pointeur sur la fonction de comparaison utilisée par le tas + bool (*fc)(void *, void *); +} binheap; + +/*************************/ +/* Fonctions auxiliaires */ +/*************************/ + +/* La fonction de comparaison pour les tas d'entiers */ +bool fcmp_int(void *x, void *y); +// Déjà écrite dans binheap.c + +/* Fonctions de navigation dans un arbre représenté par un tableau */ +int left_binheap(int i); +// Retourne l'indice du fils gauche du noeud à l'indice i +int right_binheap(int i); // Fils droit +// Retourne l'indice du fils droit du noeud à l'indice i +int parent_binheap(int i); // Parent +// Retourne l'indice du parent du noeud à l'indice i +bool isvalid_binheap(binheap *p, int i); +// Teste si l'indice i correspond à un noeud est valide dans le tas p + +/************************/ +/* Fonctions primitives */ +/************************/ + +/* Création d'un tas vide */ +binheap *create_binheap(bool (*)(void *, void *)); +// Le paramètre est un pointeur de fonction +// Il faut lui donner l'adresse de la fonction de comparaison à utiliser +// Par exemple, pour créer un tas d'entier on appellera la primitive avec +// l'adresse de la fonction fcmp_int ci-dessus: +// p = create_binheap(&fcmp_int); + +/* Suppression */ +void delete_binheap(binheap *); + +/* Test du vide */ +bool isempty_binheap(binheap *); + +/* Taille */ +int getsize_binheap(binheap *); + +/* Insertion d'une valeur */ +void push_binheap(binheap *, void *); + +/* Récupération du minimum sans le retirer */ +void *peekmin_binheap(binheap *); + +/* Récupération du minimum en le retirant */ +void *popmin_binheap(binheap *); + +#endif diff --git a/tp-huffman/binheap.o b/tp-huffman/binheap.o new file mode 100644 index 0000000000000000000000000000000000000000..3737bc5cbbed228341fd1a53cbf2bea42d1c6881 GIT binary patch literal 14528 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 + +/**********************/ +/* Définition du type */ +/**********************/ + +typedef struct { + int *array; // Tableau des valeurs + int size_array; // Taille du tableau des valeurs + int left; // Indice de la valeur à gauche du tuyau (si non-vide). + int right; // Indice qui suit celui de la valeur à droite du tuyau (si + // non-vide). + bool empty; // Booléen indiquant si le tuyau est vide. +} dequeue; + +/*************************/ +/* Fonctions auxiliaires */ +/*************************/ + +// Double la taille du tableau utilisé dans la représentation. +void grow_dequeue(dequeue *); + +// Divise par deux la taille du tableau utilisé dans la représentation +// (on supposera que seulement la moitié des cases sont utilisées dans +// la représentation). +void shrink_dequeue(dequeue *); + +/************************/ +/* Fonctions primitives */ +/************************/ + +// Création +dequeue *create_dequeue(void); + +// Suppression +void delete_dequeue(dequeue *); + +// Taille +int getsize_dequeue(dequeue *p); + +// Test du vide +bool isempty_dequeue(dequeue *); + +// Insertion +void leftinsert(int, dequeue *); +void rightinsert(int, dequeue *); + +// Lecture + +// Les deux fonctions suivantes étendent le type abstrait tuyau vu en TD. +// En effet, elles permettent de lire la i-ème valeur à partir de la gauche ou +// de la droite, ce qui n'était pas possible avec le type abstrait tuyau. + +// Lit la ième valeur en partant de la gauche (la première à gauche a pour +// indice 0). +int leftread(dequeue *, int i); + +// Lit la ième valeur en partant de la droite (la première à droite a pour +// indice 0). +int rightread(dequeue *, int i); + +// Suppression + +int leftpull(dequeue *); + +int rightpull(dequeue *); + +// Affichage d'un tuyau +// Cette primitive est déjà écrite. Utilisez-la pour vos tests. +void print_dequeue(dequeue *p); + +#endif // DEQUEUE_H_ diff --git a/tp-huffman/dequeue.o b/tp-huffman/dequeue.o new file mode 120000 index 0000000..4fea2bb --- /dev/null +++ b/tp-huffman/dequeue.o @@ -0,0 +1 @@ +dequeue_x86-64.o \ No newline at end of file diff --git a/tp-huffman/dequeue_arm64.o b/tp-huffman/dequeue_arm64.o new file mode 100644 index 0000000000000000000000000000000000000000..b362d2460791dada3c04b550b1f948daeda7a26b GIT binary patch literal 12248 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 F{tri>f6xE` literal 0 HcmV?d00001 diff --git a/tp-huffman/dequeue_x86-64.o b/tp-huffman/dequeue_x86-64.o new file mode 100644 index 0000000000000000000000000000000000000000..778a621af1c98b0aa84df92aed7634d282720cd9 GIT binary patch literal 16592 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 (int)level) \ + PRINT_ERROR(symbol, name, __func__, __FILE__, __LINE__, msg __VA_OPT__( , ) __VA_ARGS__); \ + } while (0) + +#define TRACE(msg, ...) PRINT_DEBUG(OK, "TRACE", TRACE_L, msg, __VA_ARGS__) + +#define DEBUG(msg, ...) PRINT_DEBUG(HINT, "DEBUG", DEBUG_L, msg, __VA_ARGS__) + +#define INFO(msg, ...) PRINT_DEBUG(HINT, "INFO", INFO_L, msg, __VA_ARGS__) + +#define WARNING(msg, ...) PRINT_DEBUG(ATTENTION, "WARNING", WARNING_L, msg, __VA_ARGS__) + +#define ERROR(msg, ...) PRINT_DEBUG(ATTENTION, "ERROR", ERROR_L, msg, __VA_ARGS__) + +#define CRITICAL(msg, ...) PRINT_DEBUG(KO, "CRITICAL", CRITICAL_L, msg, __VA_ARGS__) + +#endif // ERROR_H_ diff --git a/tp-huffman/huffcomp.c b/tp-huffman/huffcomp.c new file mode 100644 index 0000000..e6f905c --- /dev/null +++ b/tp-huffman/huffcomp.c @@ -0,0 +1,59 @@ +/************************************/ +/** Codage de Huffman: Compression **/ +/************************************/ + +#include "huffcomp.h" + +/**********************************/ +/* Fonctions manipulant les codes */ +/**********************************/ + +/* Construction du tableau des codes à partir de l'arbre de Huffman */ +huffcode **create_huffdict(huffnode *tree) { + // À écrire + return NULL; +} + +/* Suppression du tableau de code */ +void delete_huffdict(huffcode **dict) { + // À écrire +} + +/***********************************************/ +/** Fonction pour la compression d'un fichier **/ +/***********************************************/ + +/* Écriture d'un unsigned int sur 4 octets dans un fichier */ +void write_size(FILE *output, unsigned int size) { + // À écrire +} + +/* Insertion d'un code à droite d'un tuyau servant de tampon */ +void insert_code_in_buffer(dequeue *buffer, huffcode *code) { + // À écrire +} + +/* Calcule l'octet correspondant aux 8 derniers éléments d'un tuyau servant de + * tampon */ +int buffer_to_byte(dequeue *buffer) { + // À écrire + return 0; +} + +/* Procédure de compression */ +void compress_file(FILE *in, FILE *out) { + /* Phase 1: calcul de la taille de l'arbre et du dictionnaire à partir du + * fichier source */ + + // À écrire + + /* Phase 2: écriture de la taille du fichier original */ + + // À écrire + + /* Phase 3: écriture de l'arbre en représentation préfixe */ + + // À écrire + + /* Phase 4: écriture du codage */ +} diff --git a/tp-huffman/huffcomp.d b/tp-huffman/huffcomp.d new file mode 100644 index 0000000..e159f55 --- /dev/null +++ b/tp-huffman/huffcomp.d @@ -0,0 +1,2 @@ +huffcomp.o: huffcomp.c huffcomp.h alloc.h error.h dequeue.h hufftree.h \ + binheap.h diff --git a/tp-huffman/huffcomp.h b/tp-huffman/huffcomp.h new file mode 100644 index 0000000..7d47610 --- /dev/null +++ b/tp-huffman/huffcomp.h @@ -0,0 +1,71 @@ +/************************************/ +/** Codage de Huffman: Compression **/ +/************************************/ + +#ifndef HUFFCOMP_H_ +#define HUFFCOMP_H_ + +#include "alloc.h" +#include "dequeue.h" +#include "hufftree.h" +#include +#include + +/************************************************/ +/* Type utilisé pour stocker un code de Huffman */ +/************************************************/ + +// Type pour représenter un seul code +typedef struct { + // Le nombre de bits dans le code (un code n'aura jamais plus de 256 bits). + unsigned char size; + + // Le tableau qui stocke le code : les valeurs sont toutes 0 ou 1. + unsigned char *code; +} huffcode; + +// Le dictionnaire contiendra tous les codes. +// Il sera de type huffcode **, et pointera vers 256 cases. +// Chacun de ses éléments sera donc de type huffcode *. +// Pour les valeurs i ayant un code, la ième case contient ce code +// Pour les valeurs i n'ayant pas de code (de fréquence nulle), la ième case +// contient NULL. + +/********************************************/ +/* Fonction de construction du dictionnaire */ +/********************************************/ + +// Construction du dictionnaire à partir de l'arbre de Huffman. +huffcode **create_huffdict(huffnode *tree); + +// Suppression du dictionnaire +void delete_huffdict(huffcode **dict); + +/***********************************************/ +/** Fonction pour la compression d'un fichier **/ +/***********************************************/ + +// Écriture d'un unsigned int sur 4 octets dans un fichier. +// output doit être ouvert en écriture. +void write_size(FILE *output, unsigned int size); + +// Insertion de tous les bits d'un code à droite d'un tuyau tampon. +// Le tuyau est supposé contenir une séquence de 0 et de 1. +void insert_code_in_buffer(dequeue *buffer, huffcode *code); + +// Calcule l'octet correspondant aux 8 premiers bits à gauche d'un tuyau tampon. + +// Le tuyau est supposé contenir une séquence de bits (0 ou 1) de longueur au +// moins 8 Les 8 bits lus doivent être supprimés du tuyau. +int buffer_to_byte(dequeue *buffer); + +// Fonction de compression du fichier input dans output. +// input doit être ouvert en lecture. +// output doit être ouvert en écriture. +// Le fichier output devra contenir dans l'ordre : +// 1) La taille de input codée sur 4 octets +// 2) La sauvegarde de l'arbre de Huffman obtenu à partir de input. +// 3) Le codage de input. +void compress_file(FILE *input, FILE *output); + +#endif diff --git a/tp-huffman/huffcomp.o b/tp-huffman/huffcomp.o new file mode 100644 index 0000000000000000000000000000000000000000..a512bee5f8cd10b1a05d416aef3fd77d8c7c5311 GIT binary patch literal 7832 zcmbtYdu$ZP8K1rL`OZGS&jA}le5SD>!FLA^7>8gmIDkz^AQ7~tA*}DQ=eu&Zce&kj zY)D$tpbC)(|KQ z;d^7{79^DszfXx6_1Ne41+Z$X3*>DV^dyp6{)^p3=uz!UJ=peLfSX?_%7CudZ3^}J zgvwIg-N7vM6BuszG_*r9e|1|WXj5QBf-VK_kszwTHVM`%aIXX#71%DphytS$j43cC z!Gr?4BsiqNZV9FoxNpS>#5t|N-p)|~IRz$U)MW)GC2$qkA9i5~a|%4r@eqL13Ov|4 z1>lnk91QISYfmfiQ0v10&MI)U`80@~SKyJA$Drq;0>`?u0G?OiQ5nvc6*%6o9dy2~ zfZ4bMz!e3iWo%a!NQF*-fop1d0>SQ!AlD9;sN2vY=ht^P^!t!*z*)nn8gUf>xdGZr z<|7NOB($X9DJ>WgKAc)w611YiUG+WJft5kjuMT0Gz#17|NcG$#8f*-8SSW%fTM0uiONcu{voixV96el+R$l1Z~216U@kE z8yxUsJKPqEWVN->ZSDKfr!)}i>cEbW@F6F4Lf!sxpyb0bh=N#JRV9qeUxU7;ye(E? zo_rT_O{Jw+A`jh)?^>#JYa-EMRQ$GT2-8(=6H0rBmyDTgA4za<=2?y#r9 zFeW3|XzUY{kp#F8M+_3^Yru{sa1}yVeS;Vw`fB$23a{&)jCh^3v>W{`k+8qFrx)qA zm9RQsNMO2+#se$3y*3`m0WKq$XDD)U%NE|e8}|YUjW5C#0NJBZ8;0>-OEXruVBvyB zuV)H?gyJ)LeXR|ut?zPyOSd==Lf&*A)PX_Kpn}5Aun}lH6EKbj)@=$HX97dx0psPs z=+1!gYM_6Ny6%K7f9rRAeu%*|OWCaH3Ul(HS+SBCv+P!cna(BQ(Qxu7E$nh~rHY%X zW<}n1tcq)b)uJuZkSy0SbC7~eKCSYHdBK61r9uYN>R8xT zb+S@P&WqH%Ye|zZxD$}N#fgE~tcvAeGF2RlyCKbwSMuN#rwHdp$cc$Ak#dr=mYR)> zRj?LCStzAX!0>TsL&7XVz-pFNc(4VQVHdM7dI$ ziKP>6Ifj;sN&CN%tU8rMA)iXjq|*s_Qq1Aau|nRi&c)yvNo*QQ?6pG@ewC?Z_5Wzw+N>gUm-hX#;Y$3A*zfgD4t^cHL~*@tPi0q6oUi&@3c=g{%2%Qh@_pcORfys9gKgale#6L+qhK-bdZ@$drUm*D_ zOkTf#f5PNnBl+JjK1SpH9kZj~@9#5tZKs)DqI|r4jE|810P%WU`h7Xdt5z~`i;RltRAB5g_x=is6RKUv~-$+hC}PY3?dz{fNhv2yU? zoGe;2kpHvl0ezes{XA%MW7IgJ394yY7uY^%A?JODu=BHcTc&XRbs&Rh!T(hs&*R)C zy4C)_PtQMcShy^HFQLd7T;4KAA5K#k9F%srP>!I0f1$GA^T};u$6@+tP(S0PsJwAm zd~b0M1*d32HcGA9jmzE-UCYJ)I(_hHeT*OX6&`;EIBpXtahCkQfWT9@Ebe#9`4=md z(jihn|M)e`{g;755gjKqW!ZqiLOISBhW4-PQy{aP{yE&BplsBF3NDOQ)6W9Goc=5H zffyw{U1>dCSdi`QN+&8LR!5HR^JGoKrSMz +#include + +// Lecture de la taille du fichier décompressé dans le fichier compressé. +// Le fichier doit être ouvert en lecture. +// La taille est codée sur les 4 premiers octets. +unsigned int read_size(FILE *in); + +// Lecture d'un code de Huffman à partir du buffer et du fichier compressé. +// Le fichier doit être ouvert en lecture. +// +// Lit un code entier et retourne la valeur qui lui est associée par l'arbre de +// Huffman. +// +// Tant que le buffer est non-vide, c'est dans celui-ci qu'on lit. +// +// Si le buffer est vide, on lit un octet dans le fichier pour insérer ses 8 +// bits dans le buffer. +// +// Le buffer est potentiellement non-vide à la fin de la lecture d'un code. Les +// bits qui restent dans le buffer font partie du prochain code à lire. +int read_huffcode(FILE *in, dequeue *deq, huffnode *thetree); + +// Procédure de décompression. +// Le flux in doit être ouvert en lecture. +// Le flux out doit être ouvert en écriture. +// Décompresse le fichier in et écrit la version décompressée dans out. +void decompress_file(FILE *in, FILE *out); + +#endif diff --git a/tp-huffman/huffdecomp.o b/tp-huffman/huffdecomp.o new file mode 100644 index 0000000000000000000000000000000000000000..8bc89e6ed53e8496846fe9dee5ecc062deb9905c GIT binary patch literal 6832 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 literal 0 HcmV?d00001 diff --git a/tp-huffman/hufftree.c b/tp-huffman/hufftree.c new file mode 100644 index 0000000..9cff40d --- /dev/null +++ b/tp-huffman/hufftree.c @@ -0,0 +1,85 @@ +#include "hufftree.h" + +/************************************/ +/* Primitives des arbres de Huffman */ +/************************************/ + +/* Création d'une feuille */ +huffnode *create_huffleaf(int byte, int freq) { + // À écrire + return NULL; +} + +/* Fusion de deux arbres avec un nouveau noeud racine */ +huffnode *merge_hufftree(huffnode *pl, huffnode *pr) { + // À écrire + return NULL; +} + +/* Teste si un noeud est une feuille */ +bool isleaf_huffnode(huffnode *p) { + // À écrire + return true; +} + +/* Retourne la valeur de l'octet correspondant à un noeud */ +int getbyte_huffnode(huffnode *p) { + // À écrire + return 0; +} + +/* Retournent les fils d'un noeud */ + +huffnode *getleft_huffnode(huffnode *p) { + // À écrire + return NULL; +} +huffnode *getright_huffnode(huffnode *p) { + // À écrire + return NULL; +} + +/* Libération d'un arbre */ + +void free_hufftree(huffnode *p) { + // À écrire +} + +/**********************************************/ +/* Fonctions manipulant les arbres de Huffman */ +/**********************************************/ + +/* Comparaison de deux arbres */ +bool compare_hufftree(void *p1, void *p2) { + // À écrire + return true; +} + +/* Création de l'arbre de Huffman à partir du fichier à compresser */ +huffnode *datafile_to_hufftree(FILE *input) { + /* Phase 1: création du tableau de fréquences */ + + // À écrire + + /* Phase 2: intialisation de la file de priorité à partir du tableau de + * fréquences */ + + // À écrire + + /* Phase 3: création de l'arbre de Huffman à partir de la file de priorités */ + + // À écrire + + return NULL; +} + +/* Écriture de l'arbre de Huffman dans le futur fichier compressé */ +void save_hufftree(huffnode *p, FILE *f) { + // À écrire +} + +/* Lecture de l'arbre de Huffman dans le fichier compressé */ +huffnode *read_hufftree(FILE *f) { + // À écrire + return NULL; +} diff --git a/tp-huffman/hufftree.d b/tp-huffman/hufftree.d new file mode 100644 index 0000000..419befa --- /dev/null +++ b/tp-huffman/hufftree.d @@ -0,0 +1 @@ +hufftree.o: hufftree.c hufftree.h alloc.h error.h binheap.h diff --git a/tp-huffman/hufftree.h b/tp-huffman/hufftree.h new file mode 100644 index 0000000..1ca106a --- /dev/null +++ b/tp-huffman/hufftree.h @@ -0,0 +1,98 @@ +/**************************************/ +/** Les arbres de Huffman **/ +/** Implémentation par des pointeurs **/ +/**************************************/ + +#ifndef HUFFTREE_H_ +#define HUFFTREE_H_ + +#include "alloc.h" +#include "binheap.h" +#include +#include + +/*******************************************/ +/* Type utilisé pour les arbres de Huffman */ +/*******************************************/ + +// Chaque objet correspond à un noeud de l'arbre. +// On identifie un arbre avec un pointeur vers son noeud racine. +// +// Cela explique pourquoi les fonctions manipulant les arbres prennent en +// argument un pointeur vers un noeud, et que leur nom se termine soit par +// _huffnode, soit par _hufftree. + +typedef struct huffnode { + // Fréquence + int freq; + + // Octet codé par le noeud (significatif seulement si le noeud est une + // feuille) + int byte; + + // Enfant gauche (NULL si pas de fils gauche) + struct huffnode *leftchild; + + // Enfant droit (NULL si pas de fils droit) + struct huffnode *rightchild; +} huffnode; + +/************************************/ +/* Primitives des arbres de Huffman */ +/************************************/ + +// Création d'une feuille. +// Les paramètres servent à initialiser les champs byte et freq (dans cet +// ordre). +huffnode *create_huffleaf(int byte, int freq); + +// Fusion de deux arbres non-vides en utilisant un nouveau noeud racine. +// La fréquence du nouveau noeud sera la somme de celles de ses deux enfants +// Le champ byte du nouveau noeud n'est pas significatif (car ce n'est pas une +// feuille). +huffnode *merge_hufftree(huffnode *pl, huffnode *pr); + +// Teste si un arbre est réduit à une seule feuille. +// On doit tester si les deux enfants du noeud racine sont NULL +bool isleaf_huffnode(huffnode *p); + +// Retourne la valeur de l'octet codé dans un noeud. +// Ne doit être utilisé que sur les feuilles. +int getbyte_huffnode(huffnode *p); + +// Retourne les enfants gauche et droit d'un noeud. +huffnode *getleft_huffnode(huffnode *p); +huffnode *getright_huffnode(huffnode *p); + +// Libération complète d'un arbre de Huffman. +void free_hufftree(huffnode *p); + +/**********************************************/ +/* Fonctions manipulant les arbres de Huffman */ +/**********************************************/ + +// Fonction de comparaison entre deux arbres de Huffman à utiliser pour le tas +// binaire. Les deux paramètres sont donc donnés par des void *. Il faut les +// convertir ces pointeurs de façon appropriée dans la fonction +// compare_hufftree. +// +// Le plus petit de deux arbres est celui dont la racine a la plus petite +// fréquence. +bool compare_hufftree(void *p1, void *p2); + +// Création de l'arbre de Huffman à partir du fichier à compresser. +// Le fichier doit être ouvert en lecture. +// L'algorithme est basé sur les files de priorités. +huffnode *datafile_to_hufftree(FILE *input); + +// Écriture de l'arbre de Huffman dans le futur fichier compressé. +// Le fichier doit être ouvert en lecture. +// On stocke l'arbre par une représentation préfixe. +void save_hufftree(huffnode *p, FILE *output); + +// Lecture de l'arbre de Huffman dans un fichier. +// Le fichier doit être ouvert en lecture. +// La tête de lecture doit être positionnée au début du codage de l'arbre. +huffnode *read_hufftree(FILE *in); + +#endif diff --git a/tp-huffman/hufftree.o b/tp-huffman/hufftree.o new file mode 100644 index 0000000000000000000000000000000000000000..b6f41bedd78b6577902f0c4a2c4db51738058ec9 GIT binary patch literal 8392 zcmbtZYiwM_6`s2fXOoTBcASJ52fT(PCLz0vod+R_gX27iAt4WuHZ-Bv`?&j1*1Oxg zcS91O4G*=Xv_K@<0tzh>RY}Vqsv1X6p>%sIYy zk8S8^o=g z`{Zov@vSQdz zCtj|?OEA3<0O80yMB$ju60r_Mq2FAw0ZG$HIAkQ2t_z2teWki0(Mrt&JB>`ulYLWA zW6DqUV>xmTE@5LhAByUCk>S`tNSWA2*3By-sV5?`asD@;95diX4Z023q`@)+ZqguW zz-A4uGhmAbHyE&0gG~mEYA|NNm1E z0cwXj`U8{SF`z-j)LgR|RWSorYS67B-vUmrt&UY;EbE1LD84j|?VHp^xpf}dP*EKk zK<`55$|~|U6c%FrJ`yQkeE`)BweMms*d#NEC-O7&24ddxw`Awamo%<|N60%Xz)ToCzdfTOU^_d{-3 z*2jrX%<%q%9~1^);@VTl8VGgiM~2Vq`&oAjs~O_0YoZx7fBH`8i!OLJYTX&#I2>JY z2@BUk;i0y|>JehrWT-GW615(RUcZA(QeYBJJb*@PhNIS{=ruPRVJHNy+IGEIv^`}{ z?6+MfTd*6RtL%I^TdApL<+OuU&2ruKa;>7OG^dQ~N>F^a`V;T5IHFGF8krPu22e zw_dBanyFUp?nb-tvU*%QVg&vjsg#Y)ww)&1}|wSs8@ zjqPGJTWU^+0qg91%Y{)?TT?a7^MLGnwSb{+I$%aQjvYG<_6O4dgFEiHsx4AB%3P;u z<21|+B+lO5ZUsV#)2HVv*=7%s*7FkxHJIqJ>dCXK_55)f&xo?8cy>*rI5539aOO>1 zz#2_xxCIMNFtwgpzi?g*kAusB#vdlV=WS1Pe>JqDvtus^fWtaG zL|}qVMJcYo-LF4}JS4q6bN#J;{k^7o&ieD8QGe+(>ffe%*tC5AcKiK*LiKa`zg%x1 zbNj#bGwP3hNLT&J{K(~p0SQCaMu&R0&+}zWZME|Y-gQjeSR9@ErduiN|$4ee8nrnt)!vzz`k|@YwIubPsJ3 z{7b~&EO=ahnE0iO{r>`Weut^nd_T3r zpT0Q$qohla9rHU0_Y3|b!q*8tM*eINJicvX8W;R+#P1jU5+hgqjAnlZNLLa1PHN|b z;LC)~#}#uQ;kr6Ny!o`^^Jl1?XGA;Kl0QEZ{5;bCRPg2l5PV+|JU-Vj{aWzbDQtFAM&!g?ZL33&>k#`?=GlsG<`gv&Kl zKs}xZ%m-YhRterFyhiX36HW{M1;W97AKQPEc-~LA-#-!0^Tzz&h`)t$=07Bi=S)n@ ze{7)Q^}_soT34T=dgi-{pCn$!CrLa`6HS$7#stsvJ1O`TgwF_`*W0s#=kdQHcplH6 z1wToc&pYfV-;YTeAM<>_j|rZi83lF!;0upC+ggrwkt;vQrKR=Kss_?>!6&-&fq)7!`P(Gf&}Ts0N{gT<~7R%J=ay zOOp0Opuw}?|7t%Bwz5s^miu24JiO1MT?-sOg2vz%Oc&^Z(oF|dT>q%!b1Qtp)(P+P z+4|>z@_CZvGqeZhus44}DRl!IQZD)f2pFZ_qYoB8)5yQb@#DIf R&AuBSOpy4!(V&^}`!`g#qhSC5 literal 0 HcmV?d00001 diff --git a/tp-huffman/main.c b/tp-huffman/main.c new file mode 100644 index 0000000..771e006 --- /dev/null +++ b/tp-huffman/main.c @@ -0,0 +1,312 @@ +#include "alloc.h" +#include "binheap.h" +#include "error.h" +#include "huffcomp.h" +#include "huffdecomp.h" +#include "hufftree.h" +#include "testprint.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void test_heap(int *tab, int size); + +/********************************/ +/* Fonction main pour les tests */ +/********************************/ + +// clang-format off +static struct option long_options[] = { + {"help" , no_argument, NULL, 'h'}, + {"tree" , no_argument , NULL, 'T'}, + {"dict" , no_argument , NULL, 'D'}, + {"decomp" , no_argument, NULL, 'd'}, + {"heap" , optional_argument, NULL, 'H'}, + {"output" , required_argument, NULL, 'o'}, + {"seed" , required_argument, NULL, 's'}, + // + {NULL, 0, NULL, 0}}; +// clang-format on + +#define DEFAULT_HEAP_SIZE 10 +int size_heap = DEFAULT_HEAP_SIZE; +int seed = -1; +bool decompress_mode = false, test_binheap_mode = false, huffdict = false, + hufftree = false; +char *outfilename = NULL; + +static void usage(char *progname) { + printf("\nUsage: %s [options]\n\n", progname); + printf("Options disponibles :\n" + "\t--help ou -h :" + "\n\t\tAffiche cette aide.\n" + "\n" + "\t--tree ou -T:" + "\n\t\tAffiche l'arbre de Huffman en cas de compression (ce n'est pas " + "fait par défaut).\n" + "\n" + "\t--dict ou -D:" + "\n\t\tAffiche le dictionnaire en cas de compression (ce n'est pas " + "fait par " + "défaut).\n" + "\n" + "\t--heap=ou -H:" + "\n\t\tTeste les fonctions de tas sur un tas de taille (%d " + "par défaut).\n" + "\n" + "\t--output= ou -o :" + "\n\t\tDéfinit le nom du fichier de sortie pour la décompression.\n" + "\n" + "\t--seed= ou -s :" + "\n\t\tDéfinit la graine du générateur aléatoire pour générer un " + "tableau.\n" + "\n", + DEFAULT_HEAP_SIZE); +} + +static void parse_argv(int argc, char *argv[]) { + for (;;) { + int c = getopt_long(argc, argv, "hTdDs:o:H::", long_options, NULL); + if (c == -1) + break; // fin de lecture des options + + switch (c) { + case 'h': + usage(argv[0]); + exit(EXIT_SUCCESS); + + case 'H': + test_binheap_mode = true; + size_heap = (optarg == NULL) ? DEFAULT_HEAP_SIZE : atoi(optarg); + break; + + case 's': + seed = atoi(optarg); + if (seed <= -1) { + ERROR("La graine doit être positive\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } + break; + + case 'd': + decompress_mode = true; + break; + + case 'D': + huffdict = true; + break; + + case 'T': + hufftree = true; + break; + + case 'o': + outfilename = strdup(optarg); + break; + + default: + break; + } + } +} + +int main(int argc, char *argv[]) { + parse_argv(argc, argv); + + // Initialisation du générateur de nombres aléatoires + // Voir man 3 srandom. + if (seed == -1) { + seed = time(NULL) % 1000; + INFO("Pour rejouer avec les mêmes tirages aléatoires: %s --seed=%d", + argv[0], seed); + } + srandom(seed); + + // Vous pouvez ajouter des tests pour les tas binaires et les arbres de + // Huffman. + // + // Pensez à utiliser les fonctions disponibles dans testprint.h + // pour afficher les tas binaires et les arbres de Huffman + + // printf("binheap null - \n"); print_binheap(NULL); + // binheap *heap = create_binheap(fcmp_int); + // print_binheap(heap); + // int v10 = 10; + // push_binheap(heap, &v10); + // print_binheap(heap); + // int v5 = 5; + // push_binheap(heap, &v5); + // print_binheap(heap); + // int v7 = 7; + // push_binheap(heap, &v7); + // push_binheap(heap, &v7); + // print_binheap(heap); + // popmin_binheap(heap); + // print_binheap(heap); + // popmin_binheap(heap); + // print_binheap(heap); + + // Test de binheap. Dans ce cas, on ne fait pas de compression/décompression. + if (test_binheap_mode) { + INFO("TEST DES TAS BINAIRES"); + INFO("---------------------\n"); + int *array = random_array(size_heap, 100); + + INFO("\nTableau avant tri:"); + print_array(array, size_heap); + + test_heap(array, size_heap); + + INFO("\nTableau après tri:"); + print_array(array, size_heap); + free(array); + return EXIT_SUCCESS; + } + + // Ici, compression ou décompression. + // La compression du fichier f est faite dans un fichier f.huff. + // La décompression du fichier f.huff est faite dans le fichier f. + + if (!decompress_mode) { + // Compression : tous les arguments suivants de main sont considérés comme + // des noms de fichiers à compresser. + + for (int i = optind; i < argc; i++) { + struct stat b; + + if (stat(argv[i], &b) != 0) { + ERROR("Impossible de calculer la taille du fichier \"%s\"", argv[i]); + continue; + } + + if (b.st_size == 0) { + WARNING("Fichier \"%s\" de taille nulle", argv[i]); + continue; + } + + INFO("Compression du fichier \"%s\" de taille %lld", argv[i], + (long long)b.st_size); + + FILE *infile = fopen(argv[i], "r"); + if (infile == NULL) { + ERROR("Impossible d'ouvrir le fichier à compresser \"%s\"", argv[i]); + continue; + } + + huffnode *t = datafile_to_hufftree(infile); + + // Arbre de Huffman + if (hufftree) { + INFO("Arbre de Huffman"); + print_hufftree(t); + } + + huffcode **d = create_huffdict(t); + if (huffdict) { + INFO("Affichage du dictionnaire"); + print_huffdict(d); + } + + // Création éventuelle du nom de fichier de sortie + if (outfilename == NULL) { + MALLOC(outfilename, strlen(argv[i]) + 6); + strcpy(outfilename, argv[i]); + strcpy(outfilename + strlen(outfilename), ".huff"); + } + + FILE *outfile = fopen(outfilename, "w"); + if (outfile == NULL) { + ERROR("Impossible d'ouvrir le fichier de sortie \"%s\"", outfilename); + continue; + } + + INFO("Fichier compressé -> \"%s\"", outfilename); + + // Appel de la fonction de compression + compress_file(infile, outfile); + + free(outfilename); + + // Fermeture des fichiers + fclose(infile); + fclose(outfile); + } + } + + if (decompress_mode) { + // Décompression : tous les arguments suivants de main sont considérés comme + // des noms de fichiers à décompresser. + for (int i = optind; i < argc; i++) { + FILE *infile = fopen(argv[i], "r"); + if (infile == NULL) { + ERROR("Impossible d'ouvrir le fichier d'entrée à décompresser \"%s\"", + argv[i]); + continue; + } + + INFO("Décompression de %s", argv[i]); + + // Création éventuelle du nom de fichier de sortie + if (outfilename == NULL) { + MALLOC(outfilename, strlen(argv[i]) + 8); + strcpy(outfilename, argv[i]); + strcpy(outfilename + strlen(outfilename), ".dehuff"); + } + + // Ouverture du fichier de sortie + FILE *outfile = fopen(outfilename, "w"); + if (outfile == NULL) { + ERROR("Impossible d'ouvrir le fichier de sortie \"%s\"", outfilename); + continue; + } + + // Appel de la fonction de décompression + decompress_file(infile, outfile); + + free(outfilename); + + // Fermeture des fichiers + fclose(infile); + fclose(outfile); + } + } + return EXIT_SUCCESS; +} + +// Implémentation du tri par les tas +void test_heap(int *tab, int size) { + int i; + int temp[size]; + for (i = 0; i < size; i++) { + temp[i] = tab[i]; + } + + binheap *p = create_binheap(&fcmp_int); + + printf("\nTest de push_binheap"); + printf("\n********************\n\n"); + for (i = 0; i < size; i++) { + printf("Push de %d\n", temp[i]); + push_binheap(p, temp + i); + print_binheap(p); + } + printf("\n"); + printf("\nTest de pop_binheap"); + printf("\n*******************\n\n"); + if (p == NULL) { + WARNING("Essai de pop sur un tas NULL, rien ne se passe\n"); + return; + } + for (i = 0; i < size; i++) { + tab[i] = *(int *)popmin_binheap(p); + printf("Élément supprimé: %d\n", tab[i]); + print_binheap(p); + } +} diff --git a/tp-huffman/main.d b/tp-huffman/main.d new file mode 100644 index 0000000..0f0ebf1 --- /dev/null +++ b/tp-huffman/main.d @@ -0,0 +1,2 @@ +main.o: main.c alloc.h error.h binheap.h huffcomp.h dequeue.h hufftree.h \ + huffdecomp.h testprint.h diff --git a/tp-huffman/main.o b/tp-huffman/main.o new file mode 100644 index 0000000000000000000000000000000000000000..e060e5a449fed9a23b6770c848370f10b75758da GIT binary patch literal 30040 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

GV zClikSM87`H&~W|wxIx1)4m>|^)a2{!{;x5fpa|j4E!IdeSbo@8P9VX zzpnQa4cGPJ8?Bfy4v4efd;_0LaW5y_)a%yx_4c}6xY@6|HGHz>?;%6ZH6;I- z#;^PPj~cGWllMt5Zuq~M_Os3-0g3U)2>-~ye?a&j4g3khFBtf*m00nqfj>k1{HPF% z@&6FvSr}YMjLY9K0@`WdhlxMmz>gAMY~Vj5ywt$)IR>T?2L21eM;Z9rgu4y=SA}{RTdU@HPYgi2Q0d@CxGZ zH1I14j~O`c|86qy29kf9fzKd0cNq8_!nYatwS?bo;0p=A$H1>6e3yY=Pxu1{&i3p! z@KwaW$H2ct_+A6&{p&{!`~`}GYIXH|o>(O0rUGO`oVFiCoq^LbLu@c`eskdt1IK%N zOnc=qr5B$KVCt906h4kW#oOlV&*{Nwc*6YFPOp=!;B zdGwb;DT}xs^1~M|$;8jm5J$cEoE+0abxPXPK|yUaa3aNW0}oT6*BJQgB!9huk0;z` z;Oet)A#O2nwl8ep>bq9>h|<9QWKXw&ze_<%82Ah1@4W`j^UH$kof{9KalTu=7AXz=%uoYxF|g>p;$(!lw;`&$ElhV1`?fj>dCyeNW9w&x0R zjGtpNev$0t{>3<6lQ4}VJ&gaDXk~;_HT-$wc2};Ox)+ z2L2G)!|Mu`|2FCUp~0U={LdTs{bc{E29Cdkf$41nf0X2$GVuQ-{&G6AJ+p{^yn)|J z@tofj>p`hX$Tc{hZr@?c7X!6DY2X|CZu2&A=ZbdcJ|@ zkUiHMcpJrGt%39UIbh&hiH;aJuiLqt?L0_&?=krKx!t!6d==4uW#C^{-9bEM;P^fu zrhWte0mbd-2F}l$|H;6=N%Z>$evIrNN$taa;d`B!CJ~M#sg!t)!O!hFN8`um$eb1# z{J$i<@M{M$p?qF@Be2fk@27SQX#BW;&M9Q@U!a1oYW(~zJQj5u{G-UZdo}(t77pj# z2LBGS|51&f?-8)t4-I~v-=Ed^abJx09X!YT$n)e)YRvsq4!kYDa#a z$n6^A(w zNe=IKGX5Irea(<_faJet;BOKCMFT%Z{AIby50-zL^i~@9BV^}I20nxORm{MDP5ieJ zj%J`}eoy;RgP*TcFB^CZ$@ymk=Xvd{CLc}V?V8o_WpSe~s+<(7^wRaQra` zOjwNfr&m)PY7KlJ>8&T6<8up*AHRWLO>w`|z!wsJpCO<1?lW-K`=lYKiu^fe@ZU}C z^?QSVAvy^umo{! zUN^Bl_?v{7n$;<3{~W^G44kiz9R_{_@kb0CzYD>1t2!m+ZzTLS1MedIP6NN4@Erzz z58*uq{w>0H88|=R(f7x&Kkz=lw+;U1NzNk%{tDrb8u%N8A29G=68;q7Nb3FHO*mpY zUT5Gut~VGs&)eL8Sq@)cM0Ip?2mUfwHGJ@(&TX8F1loPoG5FY0RLk$1tDB-xQ7zF( zSRs5 zzz4AbW&q1Li?CPH@Wm+pY_6ydg=2wg_{|0Q4F&iq0TL2ugKy9A*+UxeRsb zX$la?W7eNZ^|8>*KRr zOxVxU`QOhs0a&Odx0c83eE3hNzwJwkalbmrck}R)Zt7nPn4v<}=qCdcbiE=mm+-EF zf^_Kzl6Q%92*=kav* z@4ZFwPo>IeKZe4zALnUPCRVAc#AE9DkfJW-#pe|1>Mx}F{2q6v`VT=tI{S~4{e2Wa zv>(?eru}%mNB!(4WMw*p0}Ik}V`5-i`TQf`Nmt)>m8>pKGNU4szB2rBhWa1iOQw+A z@|ZesJwE>oia4L*g7pb+sOw-F-jjqG-Aoiy{k>4GCypOuzk*D<_}@(nhYiGt@yDr< z>+|?W+fChAkU%)uk +#include +#include +#include +#include + +#define BAR "-" // un tiret + +typedef char *string; + +// Type utilisé pour représenter les arbres de Huffman en utilisant +// des tableaux (plus pratique pour écrire la fonction d'affichage) +typedef struct { + bool *array_af; + int *array_val; + int size; +} arraytree; + +// Affichage d'un tableau d'entiers +void print_array(int *tab, int size) { + int i; + printf("{"); + for (i = 0; i < size - 1; i++) { + printf("%d, ", tab[i]); + } + printf("%d}\n", tab[size - 1]); +} + +// Affichage d'un tableau de pointeurs sur des entiers +void print_point_array(int **tab, int size) { + int i; + printf("{"); + for (i = 0; i < size - 1; i++) { + printf("%d, ", *tab[i]); + } + printf("%d}\n", *tab[size - 1]); +} + +// Génération d'un tableau d'entiers aléatoire +int *random_array(int size, int max) { + int *array; + MALLOC(array, size); + int i; + for (i = 0; i < size; i++) { + array[i] = random() % (max + 1); + } + return array; +} + +// Génération d'un tas à partir d'un tableau d'entiers +binheap *array_to_binheap(int *array, int size) { + binheap *heap = create_binheap(&fcmp_int); + int i; + for (i = 0; i < size; i++) { + push_binheap(heap, (void *)(array + i)); + } + return heap; +} + +// Affiche n fois le même la chaîne s +static void rule(int n, string s) { + for (int i = 0; i < n; i++) + printf("%s", s); +} + +// Affichage d'un tas binaire +void print_binheap(binheap *p) { + rule(10, BAR); + printf("\n"); + + if (p == NULL) { + printf("Trying to print a NULL tree\n\n"); + return; + } + + int h = 0; // Calcul de la hauteur de l'arbre (=nombre de lignes) + int j = p->size_heap; + while (j > 0) { + h++; + j = j >> 1; + } + + int s = 1; // nombre de caractères avant le milieu du pattern + int B = 1; // B = nombre de patterns dans la ligne + j = 0; // j = nombre d'éléments déjà affichés + int sons = 0; + + int y; + for (y = h - 1; y >= 0; y--, B <<= 1) { + // On part du haut de l'arbre + + int pm = (s + 1) * (1 << y) - 1; + int lb = (s + 1) * (1 << (y - 1)) - 1; + int ep = 2 * pm + 1 - 2 * s; + + // ligne avec les éléments + rule(pm - s, " "); + for (int b = 0; b < B && (j < p->size_heap); b++) { + // printf(" "); // cas pair + printf("%03i ", ((int *)p->array[j])[0]); + j++; + if (b < B - 1) + rule(ep - 1, " "); // -1 pour l'espace terminal + } + printf("\n"); + if (y == 0) + break; // fini si dernière ligne d'éléments + + // ligne avec les branchements + rule(lb, " "); + for (int b = 0; b < B; b++) { + if (right_binheap(sons) < p->size_heap) { + printf("┌"); + rule(lb, "─"); + printf("┴"); + rule(lb, "─"); + printf("┐"); + if (b < B - 1) + rule(pm, " "); + } else if (left_binheap(sons) < p->size_heap) { + printf("┌"); + rule(lb, "─"); + printf("┘"); + if (b < B - 1) + rule(pm + 2, " "); + } + sons++; + } + printf("\n"); + } + + rule(10, BAR); + printf("\n\n"); +} + +// Affichage d'un arbre de Huffman +static int maxoftwo(int a, int b) { + if (a < b) { + return b; + } else { + return a; + } +} + +static int hufftree_maxsize(huffnode *n) { + if (n == NULL) { + return 0; + } else { + return 2 * maxoftwo(hufftree_maxsize(n->leftchild), + hufftree_maxsize(n->rightchild)) + + 1; + } +} + +static void hufftree_fillarray(huffnode *n, int *arrayval, bool *arraytv, + int pos) { + if (n != NULL) { + arrayval[pos] = n->byte; + arraytv[pos] = true; + hufftree_fillarray(n->leftchild, arrayval, arraytv, 2 * pos + 1); + hufftree_fillarray(n->rightchild, arrayval, arraytv, 2 * pos + 2); + } +} + +static arraytree *hufftree_to_array(huffnode *n) { + int size = hufftree_maxsize(n); + // printf("%d\n",size); + arraytree *new; + MALLOC(new, 1); + MALLOC(new->array_af, size); + MALLOC(new->array_val, size); + new->size = size; + int i; + for (i = 0; i < size; i++) { + new->array_af[i] = false; + } + hufftree_fillarray(n, new->array_val, new->array_af, 0); + return new; +} + +void print_hufftree(huffnode *n) { + arraytree *p = hufftree_to_array(n); + + rule(10, BAR); + printf("\n"); + + if (p == NULL) { + WARNING("Essai d'affichage d'un arbre de Huffman NULL\n\n"); + return; + } + + if (p->size == 0) { + WARNING("Essai d'affichage d'un arbre de Huffman vide\n\n"); + return; + } + + if (p->size == 1) { + printf(" %c\n", n->byte); + rule(10, BAR); + printf("\n\n"); + return; + } + + int h = 0; // Calcul de la hauteur de l'arbre (=nombre de lignes) + int j = p->size; + while (j > 0) { + h++; + j = j >> 1; + } + + int s = 0; // nombre de caractères avant le milieu du pattern + int B = 1; // B = nombre de patterns dans la ligne + j = 1; // j = nombre d'éléments déjà affichés + int mine1 = 1; + int sons = 0; + + int y; + for (y = h - 1; y >= 0; y--, B <<= 1) { + // On part du haut de l'arbre + + int pm = (s + 1) * (1 << y) - 1; + int lb = (s + 1) * (1 << (y - 1)) - 1; + int ep = 2 * pm + 1 - 2 * s; + + // ligne avec les éléments + if (y != h - 1) { + rule(pm - s, " "); + for (int b = 0; b < B && (mine1 < p->size); b++) { + // printf(" "); // cas pair + if (p->array_af[mine1] && mine1 % 2 == 1) { + printf("│0"); + } else if (p->array_af[mine1] && mine1 % 2 == 0) { + printf("│1"); + } else { + printf(" "); + } + mine1++; + if (b < B - 1) + rule(ep - 1, " "); // -1 pour l'espace terminal + } + printf("\n"); + + rule(pm - s, " "); + for (int b = 0; b < B && (j < p->size); b++) { + // printf(" "); // cas pair + if (p->array_af[j] && !p->array_af[2 * j + 1] && + !p->array_af[2 * j + 2]) { + char thechar = (char)p->array_val[j]; + if (thechar == '\n') { + printf("⏎ "); + } else if (thechar == ' ') { + printf("␠ "); + } else { + printf("%c ", (char)p->array_val[j]); + } + } else if (p->array_af[j]) { + printf("│ "); + } else { + printf(" "); + } + j++; + if (b < B - 1) + rule(ep - 1, " "); // -1 pour l'espace terminal + } + printf("\n"); + + if (y == 0) + break; // fini si dernière ligne d'éléments + } + + // ligne avec les branchements + rule(lb, " "); + for (int b = 0; b < B; b++) { + if (p->array_af[2 * sons + 1] && p->array_af[2 * sons + 2]) { + printf("┌"); + rule(lb, "─"); + printf("┴"); + rule(lb, "─"); + printf("┐"); + if (b < B - 1) + rule(pm, " "); + } else if (p->array_af[2 * sons + 1]) { + printf("┌"); + rule(lb, "─"); + printf("┘"); + rule(lb + 1, " "); + if (b < B - 1) + rule(pm, " "); + } else if (p->array_af[2 * sons + 2]) { + rule(lb + 1, " "); + printf("└"); + rule(lb, "─"); + printf("┐"); + if (b < B - 1) + rule(pm, " "); + + } else { + rule(2 * lb + 3, " "); + if (b < B - 1) + rule(pm, " "); + } + sons++; + } + printf("\n"); + } + + rule(10, BAR); + printf("\n\n"); +} + +/* Affichage d'un code de Huffman */ +void print_code(huffcode *e) { + CHECK_NULL(2, e, "The code entry", e->code, "The array in the code entry"); + int i; + for (i = 0; i < e->size; i++) { + printf("%d", e->code[i]); + } + printf("\n"); +} + +/* Affichage d'un tableau de codes de Huffman */ +void print_huffdict(huffcode **codes) { + int i; + for (i = 0; i < 256; i++) { + if (codes[i] != NULL) { + printf("Valeur: %3d ", i); + if (i == '\n') { + printf("ASCII: ⏎ Code: "); + } else if (i == ' ') { + printf("ASCII: ␠ Code: "); + } else { + printf("ASCII: %c Code: ", i); + } + print_code(codes[i]); + printf("\n"); + } + } +} diff --git a/tp-huffman/testprint.d b/tp-huffman/testprint.d new file mode 100644 index 0000000..7ff5974 --- /dev/null +++ b/tp-huffman/testprint.d @@ -0,0 +1,2 @@ +testprint.o: testprint.c testprint.h alloc.h error.h binheap.h huffcomp.h \ + dequeue.h hufftree.h huffdecomp.h diff --git a/tp-huffman/testprint.h b/tp-huffman/testprint.h new file mode 100644 index 0000000..75aa573 --- /dev/null +++ b/tp-huffman/testprint.h @@ -0,0 +1,74 @@ +/******************************************/ +/******************************************/ +/** Fonctions d'affichage pour les tests **/ +/******************************************/ +/******************************************/ + +#ifndef TESTPRINT_H_ +#define TESTPRINT_H_ + +#include "alloc.h" +#include "binheap.h" +#include "huffcomp.h" +#include "huffdecomp.h" +#include "hufftree.h" +#include +#include + +/************/ +/* Tableaux */ +/************/ + +// Affichage d'un tableau d'entiers. +void print_array(int *tab, int size); + +// Affichage d'un tableau de pointeurs sur des entiers. +void print_point_array(int **tab, int size); + +// Génération d'un tableau d'entiers aléatoire. +// Les entiers générés sont compris entre 0 et max. +int *random_array(int size, int max); + +/****************/ +/* Tas binaires */ +/****************/ + +// Génération d'un tas à partir d'un tableau d'entiers. +// +// Attention, les éléments dans le tas seront des pointeurs vers +// les éléments du tableau pris en entrée. Il ne faut donc plus +// modifier les valeurs référencées par les pointeurs dans le +// tableau (sous peine de casser le tas). +binheap *array_to_binheap(int *array, int size); + +// Affichage d'un tas binaire. +// +// Prévu pour un tas dont les éléments sont des pointeurs vers des entiers. +// On peut en construire un avec les fonctions précédentes. +// Attention à ne pas afficher des tas "trop gros". Ils sont trop larges +// pour un terminal et les retours à la ligne rendent l'affichage illisible. +void print_binheap(binheap *); + +/*********************/ +/* Arbres de Huffman */ +/*********************/ + +// Affichage d'un arbre de Huffman. +// +// À nouveau, l'affichage n'est lisible que pour de "petits" arbres de Huffman. +// Faites attention à tester vos fonctions sur des fichiers qui ne contiennent +// pas beaucoup de caractères distincts (afin de minimiser la taille des +// arbres). +void print_hufftree(huffnode *); + +/*******************/ +/* Code de Huffman */ +/*******************/ + +// Affichage d'un code de Huffman. +void print_code(huffcode *e); + +// Affichage d'un tableau de codes de Huffman. +void print_huffdict(huffcode **dict); + +#endif diff --git a/tp-huffman/testprint.o b/tp-huffman/testprint.o new file mode 100644 index 0000000000000000000000000000000000000000..f48fee5502c78dc664cb253661a3945d9c33e670 GIT binary patch literal 24280 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 xf2;N1EkNZ~$Z^Z>PiY>