88 lines
2.0 KiB
C
88 lines
2.0 KiB
C
#include "compress.h"
|
|
#include "common.h"
|
|
#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("Compression du fichier '%s'...\n", filepath);
|
|
printVerbose("Calcul des fréquences d'apparition des caractères.\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);
|
|
labels = NULL;
|
|
}
|