huffman/src/compress.c

85 lines
2.0 KiB
C

#include "../include/compress.h"
#include "../include/common.h"
#include "../include/display.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
/**
* Calculer un tableau de fréquences d'apparition des
* caractères ASCII dans le fichier de chemin donné
*
* (résultat à libérer avec `free`)
*/
static double* _createFrequencies(const char*);
double* _createFrequencies(const char *filepath) {
double *frequencies = malloc(NUM_CHARS * sizeof(*frequencies));
int totalChars = 0;
for (size_t i = 0; i < NUM_CHARS; i++) {
frequencies[i] = 0;
}
// Ouverture du fichier en lecture seule, et comptage
// des occurences de chaque caractère ASCII ainsi que
// du nombre total de caractères
FILE *file = fopen(filepath, "r");
if (file == NULL) {
fprintf(
stderr, "Impossible d'ouvrir '%s' : %s\n",
filepath, strerror(errno)
);
exit(1);
}
char current;
while ((current = fgetc(file)) != EOF) {
frequencies[(size_t) current]++;
totalChars++;
}
fclose(file);
// Conversion des effectifs des caractères en fréquences
for (size_t i = 0; i < NUM_CHARS; i++) {
frequencies[i] /= totalChars;
}
return frequencies;
}
void compress(const char *filepath) {
printVerbose("Calcul des fréquences d'apparition de chaque caractère\n");
double *frequencies = _createFrequencies(filepath);
if (isVerbose()) {
printFrequenciesTable(frequencies, NUM_CHARS);
}
printVerbose("\nConstruction de l'arbre de Huffman\n");
HufTree tree = createTree(frequencies);
free(frequencies);
frequencies = NULL;
if (isVerbose()) {
printTree(tree);
}
printVerbose("\nÉtiquetage des feuilles de l'arbre\n");
char** labels = createTreeLabels(tree);
freeTree(tree);
if (isVerbose()) {
printLabelsTable(labels, NUM_CHARS);
}
freeTreeLabels(labels);
}