diff --git a/PlaningDeTavail.md b/PlaningDeTavail.md
index cf275f8..a97b236 100644
--- a/PlaningDeTavail.md
+++ b/PlaningDeTavail.md
@@ -20,8 +20,8 @@ Objectif : Mise en place des fondations techniques
|----------|---------|--------|-----|-------------|
| US-D1 | AD | TODO | 🟩 | Implémenter BitInputStream (lecture bit par bit) |
| US-D2 | AD | TODO | 🟩 | Implémenter BitOutputStream (écriture bit par bit) |
-| US-D3 | AD | TODO | 🟥 | Générer les tables de fréquences RGB |
-| US-D4 | AD | TODO | 🟥 | Construire l’arbre Huffman |
+| US-D3 | AD | TODO | 🟨 | Générer les tables de fréquences RGB |
+| US-D4 | AD | TODO | 🟨 | Construire l’arbre Huffman |
| US-D5 | AA | TODO | 🟥 | Générer les codes Huffman |
| US-D6 | AA | TODO | 🟥 | Générer les codes canoniques |
| US-U5 | YB | TODO | 🟥 | Chargement d’image via ImageIO |
@@ -104,11 +104,6 @@ Objectif : Écriture du format `.pif` + finalisation convertisseur
|----------------|-------|----|
| `SavePanel.java` *(optionnel)* | Interface de sauvegarde `.pif` | US-U6 |
-### `src/`
-| Nom du fichier | Rôle | US |
-|----------------|-------|----|
-| *(aucun nouveau fichier obligatoire)* | — | — |
-
---
diff --git a/README.md b/README.md
index 71d078a..655dda9 100644
--- a/README.md
+++ b/README.md
@@ -113,6 +113,20 @@ Le projet doit inclure :
---
+## Classes Java
+
+Les classes Java utilisées dans le projet :
+
+- [BitinputStream](src/fr/iutfbleau/sae/util/BitinputStream.java)
+- [BitOutputStream](src/fr/iutfbleau/sae/util/BitOutputStream.java)
+- [ByteUtils](src/fr/iutfbleau/sae/util/ByteUtils.java)
+- [CanonicalCode](src/fr/iutfbleau/sae/mhuffman/CanonicalCode.java)
+- [FrequencyTable](src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java)
+- [HuffmanNode](src/fr/iutfbleau/sae/mhuffman/HuffmanNode.java)
+- [HuffmanTree](src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java)
+
+---
+
## Rapport à produire
Un rapport PDF doit contenir :
diff --git a/UML/DiagrameConvertisseur_Sprint1EtSprint2.plantuml b/UML/DiagrameConvertisseur_Sprint1EtSprint2.plantuml
index f010783..b9fa697 100644
--- a/UML/DiagrameConvertisseur_Sprint1EtSprint2.plantuml
+++ b/UML/DiagrameConvertisseur_Sprint1EtSprint2.plantuml
@@ -6,29 +6,29 @@ skinparam packageStyle rectangle
' ============================
package mimage {
-class Pixel #aliceblue {
- - r : int
- - g : int
- - b : int
- + Pixel(r, g, b)
- + getR()
- + getG()
- + getB()
- + setR(r)
- + setG(g)
- + setB(b)
-}
+ class Pixel #aliceblue {
+ - r : int
+ - g : int
+ - b : int
+ + Pixel(r, g, b)
+ + getR()
+ + getG()
+ + getB()
+ + setR(r)
+ + setG(g)
+ + setB(b)
+ }
-class RGBImage #aliceblue {
- - width : int
- - height : int
- - pixels : Pixel[*]
- + RGBImage(width, height)
- + getWidth()
- + getHeight()
- + getPixel(x, y)
- + setPixel(x, y, p)
-}
+ class RGBImage #aliceblue {
+ - width : int
+ - height : int
+ - pixels : Pixel[*]
+ + RGBImage(width, height)
+ + getWidth()
+ + getHeight()
+ + getPixel(x, y)
+ + setPixel(x, y, p)
+ }
}
@@ -40,35 +40,35 @@ RGBImage *-- Pixel : contient
' ============================
package mhuffman {
-class FrequencyTable #aliceblue {
- - freqR : int[*]
- - freqG : int[*]
- - freqB : int[*]
- + computeFromImage(img)
- + getRed()
- + getGreen()
- + getBlue()
-}
+ class FrequencyTable #aliceblue {
+ - freqR : int[*]
+ - freqG : int[*]
+ - freqB : int[*]
+ + computeFromImage(img)
+ + getRed()
+ + getGreen()
+ + getBlue()
+ }
-class HuffmanNode #aliceblue {
- + value : int
- + frequency : int
- + left : HuffmanNode
- + right : HuffmanNode
- + isLeaf()
-}
+ class HuffmanNode #aliceblue {
+ + value : int
+ + frequency : int
+ + left : HuffmanNode
+ + right : HuffmanNode
+ + isLeaf()
+ }
-class HuffmanTree #aliceblue {
- - root : HuffmanNode
- + generateCodes()
-}
+ class HuffmanTree #aliceblue {
+ - root : HuffmanNode
+ + generateCodes()
+ }
-class CanonicalCode #aliceblue {
- - codeLengths : Map
- - canonicalCodes : Map
- + getCode(value)
- + getLength(value)
-}
+ class CanonicalCode #aliceblue {
+ - codeLengths : Map
+ - canonicalCodes : Map
+ + getCode(value)
+ + getLength(value)
+ }
}
@@ -82,36 +82,42 @@ CanonicalCode ..> HuffmanTree : dérive
' ============================
package util {
-class BitInputStream #aliceblue {
- - in
- - currentByte : int
- - bitPosition : int
- + BitInputStream(in)
- + readBit()
- + readBits(n)
- + close()
-}
+ class BitInputStream #aliceblue {
+ - fluxEntree
+ - octetCourant : int
+ - positionBit : int
+ - finDeFlux : boolean
-class BitOutputStream #aliceblue {
- - out
- - currentByte : int
- - bitCount : int
- + BitOutputStream(out)
- + writeBit(bit)
- + writeBits(value, n)
- + flush()
- + close()
-}
+ + BitInputStream(fluxEntree)
+ + readBit() : int
+ + readBits(nombreBits) : int
+ + closeFlux()
+ }
-class ByteUtils #aliceblue {
- + toInt(high, low)
- + toBytes(value)
-}
+ class BitOutputStream #aliceblue {
+ - fluxSortie
+ - octetEnConstruction : int
+ - positionBit : int
+ - fluxFerme : boolean
-class FileUtils #aliceblue {
- + isPIFFile(f)
- + readBinaryFile(path)
-}
+ + BitOutputStream(fluxSortie)
+ + writeBit(bit)
+ + writeBits(valeur, nombreBits)
+ + flush()
+ + fermerFlux()
+ }
+
+ class ByteUtils #aliceblue {
+ <
+ * Cette classe est utilisée dans le cadre de la compression de Huffman.
+ * Elle compte le nombre d'occurrences de chaque valeur possible (0 à 255)
+ * pour chacune des composantes de couleur : rouge, vert et bleu.
+ *
+ * Chaque composante est stockée dans un tableau de taille 256 :
+ *
+ *
+ * L'indice du tableau correspond à la valeur de la composante,
+ * et la valeur stockée correspond à sa fréquence d'apparition.
+ *
+ * Cette table de fréquences sert ensuite à construire les arbres de Huffman + * nécessaires à la compression des données de l'image. + *
+ * + * @author Algassimou Pellel Diallo + * @version 1.0 + * @since 2025-12-13 + */ +public class FrequencyTable { - public FrequencyTable(){ - // creation des 3 tableaux : la taille n'est pas definitive : ell est susceptible de changer (tres fortement) - this.freqR = new int[50]; - this.freqG = new int[50]; - this.freqB = new int[50]; - } + /** Tableau des fréquences pour la composante rouge (valeurs de 0 à 255). */ + private int[] freqR; + + /** Tableau des fréquences pour la composante verte (valeurs de 0 à 255). */ + private int[] freqG; + + /** Tableau des fréquences pour la composante bleue (valeurs de 0 à 255). */ + private int[] freqB; + + /** + * Construit une table de fréquences vide. + *+ * Les trois tableaux de fréquences sont initialisés + * avec 256 cases mises à zéro. + *
+ */ + public FrequencyTable() { + this.freqR = new int[256]; + this.freqG = new int[256]; + this.freqB = new int[256]; + } + + /** + * Calcule les fréquences des composantes RGB à partir d'une image. + *+ * Pour chaque pixel de l'image, la méthode récupère les valeurs + * rouge, verte et bleue, puis incrémente la case correspondante + * dans le tableau de fréquences associé. + *
+ * + * @param img l'image RGB à analyser + */ + public void computeFromImage(RGBImage img) { + /*Nb: une composante de couleur est un entier entre 0 et 255 qui représente la part de rouge,vert ou bleu + dans la couleur d'un pixel. + */ + /* pour chaque composante de couleur de chaque pixel, on incrémente la fréquence correspondante, + c'est-à-dire on compte le nombre de fois que la composante apparaît dans l'image. + ex: si un pixel P a une composante rouge de 150, on incrémente freqR[150] de 1. + puis on fait de même pour les composantes verte et bleue. + on répète ce processus pour tous les pixels de l'image. + */ + for (int i = 0; i < img.getWidth() * img.getHeight(); i++) { + // En un mot: frequence[Composante] += 1 + this.freqR[img.getPixel(i).getR()]++; // Incrémente la fréquence de la composante rouge + this.freqG[img.getPixel(i).getG()]++; // Incrémente la fréquence de la composante verte + this.freqB[img.getPixel(i).getB()]++; // Incrémente la fréquence de la composante bleue + } + } + + /** + * Retourne le tableau des fréquences de la composante rouge. + * + * @return un tableau de 256 entiers représentant les fréquences du rouge + */ + public int[] getRed() { + return this.freqR; + } + + /** + * Retourne le tableau des fréquences de la composante verte. + * + * @return un tableau de 256 entiers représentant les fréquences du vert + */ + public int[] getGreen() { + return this.freqG; + } + + /** + * Retourne le tableau des fréquences de la composante bleue. + * + * @return un tableau de 256 entiers représentant les fréquences du bleu + */ + public int[] getBlue() { + return this.freqB; + } +} - public void computeFromImage(BufferedImage image){ - } - public int[] getRed(){ - return this.freqR; - } - - public int[] getGreen(){ - return this.freqG; - } - - public int[] getBlue(){ - return this.freqB; - } -} \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/util/BitOutputStream.java b/src/fr/iutfbleau/sae/util/BitOutputStream.java index 9db7934..afffb76 100644 --- a/src/fr/iutfbleau/sae/util/BitOutputStream.java +++ b/src/fr/iutfbleau/sae/util/BitOutputStream.java @@ -10,11 +10,13 @@ import java.io.OutputStream; * l'écriture de bits individuellement ou par groupes. * Les bits sont accumulés afin de former des octets avant écriture. * - * ** Utilisée notamment pour l'encodage des fichiers compressés * (ex : format PIF utilisant des codes de Huffman). *
+ * @author Algassimou Pellel Diallo + * @version 1.0 + * @since 2025-12-13 */ public class BitOutputStream { @@ -100,7 +102,7 @@ public class BitOutputStream { while (this.positionBit >= 0) { writeBit(0); } - this.fluxSortie.flush(); // Force l'écriture dans le flux sous-jacent + this.fluxSortie.flush(); // Force l'écriture dans le flux sous-jacent dans le but de vider le buffer } /** diff --git a/src/fr/iutfbleau/sae/util/BitinputStream.java b/src/fr/iutfbleau/sae/util/BitinputStream.java index e81746c..43e3997 100644 --- a/src/fr/iutfbleau/sae/util/BitinputStream.java +++ b/src/fr/iutfbleau/sae/util/BitinputStream.java @@ -10,11 +10,17 @@ import java.io.InputStream; * des opérations de lecture bit par bit ou par groupes de bits. * Elle ne gère ni l'ouverture ni la sélection du fichier source. * - * + * ** Utilisée notamment pour le décodage des fichiers compressés * (ex : format PIF utilisant des codes de Huffman). *
+ * + * + * + * @author Algassimou Pellel Diallo + * @version 1.0 + * @since 2025-12-13 */ public class BitInputStream { @@ -83,7 +89,7 @@ public class BitInputStream { * @return valeur entière correspondant aux bits lus, * ou -1 si la fin du flux est atteinte prématurément * @throws IOException si une erreur de lecture survient - */ + */ public int readBits(int nombreBits) throws IOException { int res=0; for (int i = 0; i < nombreBits; i++) { @@ -96,8 +102,6 @@ public class BitInputStream { return res; } - - /** * Ferme le flux d'entrée sous-jacent. * diff --git a/src/fr/iutfbleau/sae/util/ByteUtils.java b/src/fr/iutfbleau/sae/util/ByteUtils.java index 5145973..8f0f8e4 100644 --- a/src/fr/iutfbleau/sae/util/ByteUtils.java +++ b/src/fr/iutfbleau/sae/util/ByteUtils.java @@ -27,7 +27,7 @@ public final class ByteUtils { * */ private ByteUtils() { - // empêche l'instanciation + // j'empêche l'instanciation } /** @@ -38,7 +38,7 @@ public final class ByteUtils { * * * @param value valeur entière à convertir (0 ≤ value ≤ 65535) - * @return tableau de deux octets : [octetFort, octetFaible] + * @return tableau de deux octets : [octetFort, octetFaible] M * @throws IllegalArgumentException si la valeur ne tient pas sur 2 octets */ public static byte[] toBytes(int value) {