ourg-en-resse nnée scolaire 08-09 rbres binaires - ompression de fichier texte urée : 2 4h ompte-rendu : voir avec votre encadrant. 1 Introduction Le codage de Huffman est un algorithme de compression qui fut mis au point en 1952 par avid Huffman. est une compression de type statistique qui grâce à une méthode d arbre que nous allons détailler plus loin permet de coder les octets revenant le plus fréquemment avec une séquence de bits beaucoup plus courte que d ordinaire. et algorithme offre des taux de compression démontrés les meilleurs possibles pour un codage par symbole. 1 Nous proposons dans ce TP d implémenter un programme complet de compression qui sera adapté à des fichiers textes écrits en français. eux modules vous sont fournis : une table des fréquences d apparition de chaque symbole SII pour la langue française (fichier table.h) accès à un fichier bit à bit en lecture et écriture (fichiers fbit.h et fbit.c) 2 Principe Le principe du codage est simple : plus un symbôle apparaît souvent statistiquement, moins on n utilise de bits pour le coder. Inversement, les symbôles les plus rares sont codés sur plus de bits. 2.1 ontruction de l arbre u début, on dispose d une liste de symbôles, avec des fréquences associées, par exemple : Le apparaît % du temps Le apparaît % du temps Le apparaît % du temps Le apparaît % du temps L algorithme consiste tout d abord à construire un tableau contenant des arbres avec une seule feuille. La feuille contient l information du symbôle et de sa fréquence. Ensuite, chaque étape de l algorithme sélectionne les deux arbres qui ont les fréquences cumulées les plus faibles à leur racine et les fusionne dans un nouveau nœud (ici les symbôles et ), la fréquence du nouveau nœud est la somme des deux branches : 1 source WikiPedia.fr Eric Guérin - rice Effantin 4 février 09 1/5
nnée scolaire 08-09 ourg-en-resse Première itération - fusion de et Seconde itération - fusion de et ernière itération - fusion de et Le code binaire associé à chaque symbole se déduit directement depuis le graphe. haque branche à gauche signifie 0 et chaque branche à droite signifie 1. Voici la table des correspondances symbôle/code : 0 Symbôle ode Taille en bits 0 1 1 3 2 111 3 insi pour coder la chaîne, il faudra 12 bits contre 14 pour un codage brut (2 par symbôle). 2.2 écodage Le principe de décodage est très simple, car il suffit d utiliser l arbre construit précédemment. On lit le flux d entrée bit par bit et à chaque fois que l on a un 0, on prend la branche gauche, 1 à droite jusqu à arriver sur une feuille où l on peut déduire le symbôle. 2.3 odage Le codage est un peu plus complexe, car il faut transformer des symbôles en codes. Or les symbôles se trouvent sur les feuilles de l arbre rendant obligatoire la parcours de l arbre à chaque fois pour trouver le bon symbôle. Il faut donc recourrir à une structure plus adaptée à la recherche de symbôle, ce peut être un tableau trié ou non, une table de hachage, etc. 3 Travail à effectuer 3.1 Structure de données Vous devez dans un premier temps définir la structure qui va vous servir à coder l arbre binaire. Réfléchissez aux informations qui devront se trouver sur chaque feuille (et nœud) de l arbre. 3.2 réation de l arbre à partir des fréquences odez la fonction qui permet à partir du tableau de symbôles et de fréquences (qui vous sont donnés) de construire l arbre. 3.3 odage/décodage odez deux fonctions qui auront presque le même prototype mais dont l une fera le codage (passage symbôles vers codes binaires) et l autre le décodage (passage codes binaires vers symbôles). es fonctions travailleront directement sur des fichiers : Listing 1 protos.h void decode_ file ( Fituffer * in, Fituffer * out, rbre * arbre ); int encode_ file ( Fituffer * in, Fituffer * out, rbre * arbre ); 2/5 4 février 09 Eric Guérin - rice Effantin
ourg-en-resse nnée scolaire 08-09 La fonction d encodage renverra un entier qui indiquera s il y a eu des symbôles non décrits dans la table des fréquences (et donc dans l arbre). 3.4 Tests Testez vos fonctions en faisant deux programmes, l un qui fera le codage et l autre le décodage. N oubliez pas de vérifier les paramètres en ligne de commande de ces deux commandes. 4 ompte-rendu Le compte-rendu devra reprendre votre démarche complète sur ce TP, il contiendra les résultats obtenus en compression. Vous comparerez votre algorithme à des outils de compression standard comme Zip ou gzip. Les codes sources seront joints en annexe. Eric Guérin - rice Effantin 4 février 09 3/5
nnée scolaire 08-09 ourg-en-resse 5 Les modules fournis 5.1 Module table Voici le fichier d en-tête de ce module : Listing 2 table.h int symboles [] = {0,, 32, 33, 37, 38, 39, 40, 41, 44, 45, 46, 47, 48, 49,, 51, 52, 53, 54, 55, 56, 57, 58, 59, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 111, 112, 113, 114, 115, 116, 117, 118, 119, 1, 121, 122, 169, 171, 183, 187, 192, 0, 1, 216, 224, 226, 231, 232, 233, 234, 238, 244, 248, 249, 251}; float frequences [] = {0.001121, 1.2989, 17.499187, 0.0173, 0.001121, 0.001121, 1.006422, 0.138971, 0.145696, 0.849519, 0.0866, 0.875296, 0.005604, 0.023535, 0.131126, 0.066123, 0.059399, 0.049312, 0.025777, 0.024656, 0.022415, 0.021294, 0.158024, 0.068365, 0.059399, 0.003362, 0.0974, 0.0385, 0.7336, 0.115436, 0.117677, 0.022415, 0.026898, 0.024656, 0.177076, 0.022415, 0.019053, 0.165869, 0.066123, 0.131126, 0.6470, 0.079572, 0.003362, 0.078452, 0.9832, 0.089659, 0.039226, 0.024656, 0.017932, 0.001121, 0.002241, 0.003362, 5.138579, 0.435967, 2.663992, 3.1392,.725453, 0.862967, 1.128582, 0.765463, 5.809901, 0.072848, 0.029139, 3.9294, 1.975859, 6.186468, 5.0646, 2.314322, 0.684770, 4.554675, 6.232418, 6.009392, 3.689466, 1.063579, 0.029139, 0.37, 0.7336, 0.021294, 0.001121, 0.069486, 0.035864, 0.069486, 0.004483, 0.002241, 0.013449, 0.001121, 0.3785, 0.0117, 0.069486, 0.166990, 1.554462, 0.080693, 0.016811, 0.023535, 0.001121, 0.006724, 0. 014570}; int nsymboles = sizeof ( symboles )/ sizeof ( int ); 5.2 Module fbit e module permet d écrire et lire dans un fichier des bits de manière séquentielle. Il a été conçu pour une utilisation la plus simple possible. Voici le fichier d en-tête de ce module : # ifndef FIT_H # define FIT_H Listing 3 fbit.h # include <stdio.h> typedef struct { unsigned char tampon ; char * mode ; int offset ; FILE * fid ; } Fituffer ; Fituffer * fopen_ bits ( char * fichier, char * mode ); void fclose_ bits ( Fituffer * buffer ); void fwrite_ bits ( int val, int nbits, Fituffer * buffer ); int fread_ bits ( int nbits, Fituffer * buffer ); 4/5 4 février 09 Eric Guérin - rice Effantin
ourg-en-resse nnée scolaire 08-09 int feof_ bits ( Fituffer * buffer ); # endif Voici deux programmes qui montrent l utilisation de ce module, en écriture puis en lecture. Le premier entier est codé sur 12 bits, le second sur 15 bits. # include " fbit.h" Listing 4 exempleecriture.c int main ( void ) { Fituffer * buffer ; buffer = fopen_bits (" fichier. dat ","wb"); fwrite_bits (7,3, buffer ); fwrite_bits (0,1, buffer ); fwrite_bits (3,2, buffer ); fwrite_bits (0,2, buffer ); fclose_bits ( buffer ); return 0; } # include " fbit.h" Listing 5 exemplelecture.c int main ( void ) { Fituffer * buffer ; int i; buffer = fopen_bits (" fichier. dat ","rb"); for (i =0;i <8; i ++) printf ("%d\n",fread_bits (1, buffer )); fclose_bits ( buffer ); return 0; } Eric Guérin - rice Effantin 4 février 09 5/5