package fr.iutfbleau.sae.mhuffman; import java.util.*; /** * * Classe pour generer des codes canoniques de Huffman. * Les codes canoniques sont des codes de Huffman reorganises * pour faciliter la compression et le decodage. */ public class CanonicalCode { /** * Genere des codes canoniques a partir de codes de Huffman. * * @param codesHuffman les codes de Huffman initiaux * @return les codes canoniques generes */ public Map generateCodes(Map codesHuffman) { // On recupere les entrees des codes Huffman pour pouvoir les trier List> liste = new ArrayList<>(codesHuffman.entrySet()); // On trie par longueur de la valeur ou sinon par la cle Collections.sort(liste, new ComparateurCanonique()); Map canonicalCodes = new HashMap<>(); int code = 0; // Code canonique a attribuer int temp = 0; // Garde la longueur du code precedent, pour gerer le decalage for (Map.Entry entree : liste) { int valeur = entree.getKey(); // Symbole actuel int longueur = entree.getValue().length(); // Longueur du code actuel code <<= (longueur - temp); // Permet de decaler le code actuel si la longueur augmente String codeBinaire = Integer.toBinaryString(code); // Permet d'ajouter des zeros si necessaire while (codeBinaire.length() < longueur) { codeBinaire = "0" + codeBinaire; } canonicalCodes.put(valeur, codeBinaire); // Ajout dans le dictionnaire code++; // Incrementation pour la valeur qui suit temp = longueur; // Mise a jour de la longueur precedente } return canonicalCodes; } /** * Recupere le code canonique d'une valeur. * * @param canonicalCodes la table des codes canoniques * @param value la valeur dont on veut le code * @return le code canonique correspondant */ public String getCode(Map canonicalCodes, int value) { return canonicalCodes.get(value); } /** * Recupere la longueur d'un code pour une valeur donnee. * * @param codesH la table des codes * @param value la valeur dont on veut la longueur * @return la longueur du code en bits */ public int getLength(Map codesH, int value) { return codesH.get(value).length(); } }