85 lines
1.9 KiB
C
85 lines
1.9 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);
|
|
}
|