diff --git a/build/fr/iutfbleau/sae/CodeTablePanel.class b/build/fr/iutfbleau/sae/CodeTablePanel.class new file mode 100644 index 0000000..cfb8ba4 Binary files /dev/null and b/build/fr/iutfbleau/sae/CodeTablePanel.class differ diff --git a/build/fr/iutfbleau/sae/ConverterController.class b/build/fr/iutfbleau/sae/ConverterController.class index 0e15a42..b8d962d 100644 Binary files a/build/fr/iutfbleau/sae/ConverterController.class and b/build/fr/iutfbleau/sae/ConverterController.class differ diff --git a/build/fr/iutfbleau/sae/vconverter/ConverterWindow.class b/build/fr/iutfbleau/sae/ConverterWindow.class similarity index 60% rename from build/fr/iutfbleau/sae/vconverter/ConverterWindow.class rename to build/fr/iutfbleau/sae/ConverterWindow.class index 1f24cd3..47aa483 100644 Binary files a/build/fr/iutfbleau/sae/vconverter/ConverterWindow.class and b/build/fr/iutfbleau/sae/ConverterWindow.class differ diff --git a/build/fr/iutfbleau/sae/Convertisseur.class b/build/fr/iutfbleau/sae/Convertisseur.class index e99a92a..f77d6e2 100644 Binary files a/build/fr/iutfbleau/sae/Convertisseur.class and b/build/fr/iutfbleau/sae/Convertisseur.class differ diff --git a/build/fr/iutfbleau/sae/FrequencyTablePanel.class b/build/fr/iutfbleau/sae/FrequencyTablePanel.class new file mode 100644 index 0000000..ed3f369 Binary files /dev/null and b/build/fr/iutfbleau/sae/FrequencyTablePanel.class differ diff --git a/build/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.class b/build/fr/iutfbleau/sae/ImagePreviewPanel.class similarity index 92% rename from build/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.class rename to build/fr/iutfbleau/sae/ImagePreviewPanel.class index 7dff39f..9130726 100644 Binary files a/build/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.class and b/build/fr/iutfbleau/sae/ImagePreviewPanel.class differ diff --git a/build/fr/iutfbleau/sae/Viewer.class b/build/fr/iutfbleau/sae/Viewer.class index e537982..f0c95a8 100644 Binary files a/build/fr/iutfbleau/sae/Viewer.class and b/build/fr/iutfbleau/sae/Viewer.class differ diff --git a/build/fr/iutfbleau/sae/ViewerControleur.class b/build/fr/iutfbleau/sae/ViewerControleur.class new file mode 100644 index 0000000..c2ce387 Binary files /dev/null and b/build/fr/iutfbleau/sae/ViewerControleur.class differ diff --git a/build/fr/iutfbleau/sae/ViewerWindow.class b/build/fr/iutfbleau/sae/ViewerWindow.class new file mode 100644 index 0000000..ac88a4e Binary files /dev/null and b/build/fr/iutfbleau/sae/ViewerWindow.class differ diff --git a/build/fr/iutfbleau/sae/mhuffman/CanonicalCode.class b/build/fr/iutfbleau/sae/mhuffman/CanonicalCode.class index d49fd34..0cfdd9a 100644 Binary files a/build/fr/iutfbleau/sae/mhuffman/CanonicalCode.class and b/build/fr/iutfbleau/sae/mhuffman/CanonicalCode.class differ diff --git a/build/fr/iutfbleau/sae/mhuffman/FrequencyTable.class b/build/fr/iutfbleau/sae/mhuffman/FrequencyTable.class index 3800669..a59dcbc 100644 Binary files a/build/fr/iutfbleau/sae/mhuffman/FrequencyTable.class and b/build/fr/iutfbleau/sae/mhuffman/FrequencyTable.class differ diff --git a/build/fr/iutfbleau/sae/mhuffman/HuffmanTree.class b/build/fr/iutfbleau/sae/mhuffman/HuffmanTree.class index faebc57..4e72772 100644 Binary files a/build/fr/iutfbleau/sae/mhuffman/HuffmanTree.class and b/build/fr/iutfbleau/sae/mhuffman/HuffmanTree.class differ diff --git a/build/fr/iutfbleau/sae/mpif/PIFReader.class b/build/fr/iutfbleau/sae/mpif/PIFReader.class new file mode 100644 index 0000000..e41e1ea Binary files /dev/null and b/build/fr/iutfbleau/sae/mpif/PIFReader.class differ diff --git a/build/fr/iutfbleau/sae/mpif/PIFWriter.class b/build/fr/iutfbleau/sae/mpif/PIFWriter.class index 78b8424..3983ada 100644 Binary files a/build/fr/iutfbleau/sae/mpif/PIFWriter.class and b/build/fr/iutfbleau/sae/mpif/PIFWriter.class differ diff --git a/build/fr/iutfbleau/sae/mimage/Pixel.class b/build/fr/iutfbleau/sae/mpif/Pixel.class similarity index 74% rename from build/fr/iutfbleau/sae/mimage/Pixel.class rename to build/fr/iutfbleau/sae/mpif/Pixel.class index 424078e..e1ac50a 100644 Binary files a/build/fr/iutfbleau/sae/mimage/Pixel.class and b/build/fr/iutfbleau/sae/mpif/Pixel.class differ diff --git a/build/fr/iutfbleau/sae/mimage/RGBImage.class b/build/fr/iutfbleau/sae/mpif/RGBImage.class similarity index 58% rename from build/fr/iutfbleau/sae/mimage/RGBImage.class rename to build/fr/iutfbleau/sae/mpif/RGBImage.class index 351c0e6..62eca0d 100644 Binary files a/build/fr/iutfbleau/sae/mimage/RGBImage.class and b/build/fr/iutfbleau/sae/mpif/RGBImage.class differ diff --git a/build/fr/iutfbleau/sae/util/BitInputStream.class b/build/fr/iutfbleau/sae/util/BitInputStream.class new file mode 100644 index 0000000..b803134 Binary files /dev/null and b/build/fr/iutfbleau/sae/util/BitInputStream.class differ diff --git a/build/fr/iutfbleau/sae/util/DecodeNode.class b/build/fr/iutfbleau/sae/util/DecodeNode.class new file mode 100644 index 0000000..c62d827 Binary files /dev/null and b/build/fr/iutfbleau/sae/util/DecodeNode.class differ diff --git a/build/fr/iutfbleau/sae/util/GestionErreur.class b/build/fr/iutfbleau/sae/util/GestionErreur.class new file mode 100644 index 0000000..4677f52 Binary files /dev/null and b/build/fr/iutfbleau/sae/util/GestionErreur.class differ diff --git a/build/fr/iutfbleau/sae/mhuffman/HuffmanNode.class b/build/fr/iutfbleau/sae/util/HuffmanNode.class similarity index 77% rename from build/fr/iutfbleau/sae/mhuffman/HuffmanNode.class rename to build/fr/iutfbleau/sae/util/HuffmanNode.class index 753c3ac..c7ba332 100644 Binary files a/build/fr/iutfbleau/sae/mhuffman/HuffmanNode.class and b/build/fr/iutfbleau/sae/util/HuffmanNode.class differ diff --git a/hommePommeJPG.pif b/hommePommeJPG.pif new file mode 100644 index 0000000..9ceb231 Binary files /dev/null and b/hommePommeJPG.pif differ diff --git a/makefile b/makefile index d0e1e42..3832326 100644 --- a/makefile +++ b/makefile @@ -32,12 +32,14 @@ all: \ # Compilation des classes main $(BIN)/$(PKG_PATH)/Convertisseur.class: $(BIN) \ $(BIN)/$(PKG_PATH)/ConverterController.class \ - $(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class \ + $(BIN)/$(PKG_PATH)/ConverterWindow.class \ $(BIN)/$(PKG_PATH)/ExportButtonListener.class \ $(SRC)/$(PKG_PATH)/Convertisseur.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/Convertisseur.java $(BIN)/$(PKG_PATH)/Viewer.class: $(BIN) \ + $(BIN)/$(PKG_PATH)/ViewerWindow.class \ + $(BIN)/$(PKG_PATH)/ViewerControleur.class \ $(SRC)/$(PKG_PATH)/Viewer.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/Viewer.java @@ -50,9 +52,9 @@ $(DOC): # Compilation des classes util -$(BIN)/$(PKG_PATH)/util/ByteUtils.class: $(BIN) \ - $(SRC)/$(PKG_PATH)/util/ByteUtils.java - $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/ByteUtils.java +$(BIN)/$(PKG_PATH)/util/DecodeNode.class: $(BIN) \ + $(SRC)/$(PKG_PATH)/util/DecodeNode.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/DecodeNode.java $(BIN)/$(PKG_PATH)/util/BitInputStream.class: $(BIN) \ $(SRC)/$(PKG_PATH)/util/BitInputStream.java @@ -62,15 +64,19 @@ $(BIN)/$(PKG_PATH)/util/BitOutputStream.class: $(BIN) \ $(SRC)/$(PKG_PATH)/util/BitOutputStream.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/BitOutputStream.java +$(BIN)/$(PKG_PATH)/util/GestionErreur.class: $(BIN) \ + $(SRC)/$(PKG_PATH)/util/GestionErreur.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/GestionErreur.java + +$(BIN)/$(PKG_PATH)/util/HuffmanNode.class: $(BIN) \ + $(SRC)/$(PKG_PATH)/util/HuffmanNode.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/HuffmanNode.java + # Compilation des classes mhuffman - -# Ajout de la classe ComparateurCanonique : $(BIN)/$(PKG_PATH)/mhuffman/ComparateurCanonique.class: $(BIN) \ $(SRC)/$(PKG_PATH)/mhuffman/ComparateurCanonique.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/ComparateurCanonique.java -# - $(BIN)/$(PKG_PATH)/mhuffman/CanonicalCode.class: $(BIN) \ $(SRC)/$(PKG_PATH)/mhuffman/CanonicalCode.java \ @@ -78,93 +84,105 @@ $(BIN)/$(PKG_PATH)/mhuffman/CanonicalCode.class: $(BIN) \ $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/CanonicalCode.java $(BIN)/$(PKG_PATH)/mhuffman/FrequencyTable.class: $(BIN) \ - $(BIN)/$(PKG_PATH)/mimage/RGBImage.class \ + $(BIN)/$(PKG_PATH)/mpif/RGBImage.class \ $(SRC)/$(PKG_PATH)/mhuffman/FrequencyTable.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/FrequencyTable.java -$(BIN)/$(PKG_PATH)/mhuffman/HuffmanNode.class: $(BIN) \ - $(SRC)/$(PKG_PATH)/mhuffman/HuffmanNode.java - $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/HuffmanNode.java - $(BIN)/$(PKG_PATH)/mhuffman/HuffmanTree.class: $(BIN) \ - $(BIN)/$(PKG_PATH)/mhuffman/HuffmanNode.class \ + $(BIN)/$(PKG_PATH)/util/HuffmanNode.class \ $(SRC)/$(PKG_PATH)/mhuffman/HuffmanTree.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/HuffmanTree.java -# Compilation des classes mimage -$(BIN)/$(PKG_PATH)/mimage/Pixel.class: $(BIN) \ - $(SRC)/$(PKG_PATH)/mimage/Pixel.java - $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mimage/Pixel.java -$(BIN)/$(PKG_PATH)/mimage/RGBImage.class: $(BIN) \ - $(BIN)/$(PKG_PATH)/mimage/Pixel.class \ - $(SRC)/$(PKG_PATH)/mimage/RGBImage.java - $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mimage/RGBImage.java # Interface graphique -$(BIN)/$(PKG_PATH)/vconverter/ImagePreviewPanel.class: $(BIN) \ - $(SRC)/$(PKG_PATH)/vconverter/ImagePreviewPanel.java - $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/ImagePreviewPanel.java +$(BIN)/$(PKG_PATH)/ImagePreviewPanel.class: $(BIN) \ + $(SRC)/$(PKG_PATH)/ImagePreviewPanel.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/ImagePreviewPanel.java -$(BIN)/$(PKG_PATH)/vconverter/FrequencyTablePanel.class: $(BIN) \ - $(SRC)/$(PKG_PATH)/vconverter/FrequencyTablePanel.java - $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/FrequencyTablePanel.java +$(BIN)/$(PKG_PATH)/FrequencyTablePanel.class: $(BIN) \ + $(SRC)/$(PKG_PATH)/FrequencyTablePanel.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/FrequencyTablePanel.java -$(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class: $(BIN) \ - $(SRC)/$(PKG_PATH)/vconverter/CodeTablePanel.java - $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/CodeTablePanel.java +$(BIN)/$(PKG_PATH)/CodeTablePanel.class: $(BIN) \ + $(SRC)/$(PKG_PATH)/CodeTablePanel.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/CodeTablePanel.java -# $(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class: $(BIN) \ -# $(BIN)/$(PKG_PATH)/ConverterController.class \ -# $(BIN)/$(PKG_PATH)/vconverter/ImagePreviewPanel.class \ -# $(BIN)/$(PKG_PATH)/vconverter/FrequencyTablePanel.class \ -# $(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class \ -# $(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java -# $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java +$(BIN)/$(PKG_PATH)/ViewerWindow.class: $(BIN) \ + $(SRC)/$(PKG_PATH)/ViewerWindow.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/ViewerWindow.java -# Compilation PIFWriter +# Compilation des classe mpif +$(BIN)/$(PKG_PATH)/mpif/Pixel.class: $(BIN) \ + $(SRC)/$(PKG_PATH)/mpif/Pixel.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mpif/Pixel.java + +$(BIN)/$(PKG_PATH)/mpif/RGBImage.class: $(BIN) \ + $(BIN)/$(PKG_PATH)/mpif/Pixel.class \ + $(SRC)/$(PKG_PATH)/mpif/RGBImage.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mpif/RGBImage.java + $(BIN)/$(PKG_PATH)/mpif/PIFWriter.class: $(BIN) \ - $(BIN)/$(PKG_PATH)/mimage/RGBImage.class \ + $(BIN)/$(PKG_PATH)/mpif/RGBImage.class \ $(BIN)/$(PKG_PATH)/util/BitOutputStream.class \ $(SRC)/$(PKG_PATH)/mpif/PIFWriter.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mpif/PIFWriter.java +$(BIN)/$(PKG_PATH)/mpif/PIFReader.class: $(BIN) \ + $(BIN)/$(PKG_PATH)/mpif/RGBImage.class \ + $(BIN)/$(PKG_PATH)/util/BitInputStream.class \ + $(BIN)/$(PKG_PATH)/util/DecodeNode.class \ + $(SRC)/$(PKG_PATH)/mpif/PIFReader.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mpif/PIFReader.java + + + # GROSSE compilation du listener + ConvertController + ConvertWindow + PIFSaverTask car il y a une dependance cirulaire $(BIN)/$(PKG_PATH)/ConverterController.class \ $(BIN)/$(PKG_PATH)/ExportButtonListener.class \ $(BIN)/$(PKG_PATH)/PIFSaveTask.class \ -$(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class: \ +$(BIN)/$(PKG_PATH)/ConverterWindow.class: \ $(SRC)/$(PKG_PATH)/ConverterController.java \ $(SRC)/$(PKG_PATH)/ExportButtonListener.java \ $(SRC)/$(PKG_PATH)/PIFSaveTask.java \ -$(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java \ -$(BIN)/$(PKG_PATH)/mimage/Pixel.class \ -$(BIN)/$(PKG_PATH)/mimage/RGBImage.class \ +$(SRC)/$(PKG_PATH)/ConverterWindow.java \ +$(BIN)/$(PKG_PATH)/mpif/Pixel.class \ +$(BIN)/$(PKG_PATH)/mpif/RGBImage.class \ $(BIN)/$(PKG_PATH)/mhuffman/FrequencyTable.class \ $(BIN)/$(PKG_PATH)/mhuffman/HuffmanTree.class \ $(BIN)/$(PKG_PATH)/mhuffman/CanonicalCode.class \ -$(BIN)/$(PKG_PATH)/vconverter/ImagePreviewPanel.class \ -$(BIN)/$(PKG_PATH)/vconverter/FrequencyTablePanel.class \ -$(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class \ +$(BIN)/$(PKG_PATH)/ImagePreviewPanel.class \ +$(BIN)/$(PKG_PATH)/FrequencyTablePanel.class \ +$(BIN)/$(PKG_PATH)/CodeTablePanel.class \ +$(BIN)/$(PKG_PATH)/util/GestionErreur.class \ $(BIN)/$(PKG_PATH)/mpif/PIFWriter.class | $(BIN) @$(JAVAC) -cp $(BIN) -d $(BIN) \ $(SRC)/$(PKG_PATH)/ConverterController.java \ $(SRC)/$(PKG_PATH)/ExportButtonListener.java \ $(SRC)/$(PKG_PATH)/PIFSaveTask.java \ - $(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java + $(SRC)/$(PKG_PATH)/ConverterWindow.java + +#Controleur de viewer +$(BIN)/$(PKG_PATH)/ViewerControleur.class: $(BIN) \ + $(BIN)/$(PKG_PATH)/mpif/RGBImage.class \ + $(BIN)/$(PKG_PATH)/util/GestionErreur.class \ + $(BIN)/$(PKG_PATH)/mpif/PIFReader.class \ + $(SRC)/$(PKG_PATH)/ViewerControleur.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/ViewerControleur.java + # Exécution run-conv: all $(JAVA) -cp $(BIN) $(MAIN_CONVERTER) $(ARGS) -run-view: all - $(JAVA) -cp $(BIN) $(MAIN_VIEWER) +run-view: $(BIN)/$(PKG_PATH)/Viewer.class + $(JAVA) -cp $(BIN) $(MAIN_VIEWER) $(ARGS) # Documentation doc: $(DOC) diff --git a/src/fr/iutfbleau/sae/vconverter/CodeTablePanel.java b/src/fr/iutfbleau/sae/CodeTablePanel.java similarity index 96% rename from src/fr/iutfbleau/sae/vconverter/CodeTablePanel.java rename to src/fr/iutfbleau/sae/CodeTablePanel.java index 836d949..1adcf21 100644 --- a/src/fr/iutfbleau/sae/vconverter/CodeTablePanel.java +++ b/src/fr/iutfbleau/sae/CodeTablePanel.java @@ -1,110 +1,110 @@ -package fr.iutfbleau.sae.vconverter; - -import javax.swing.*; -import java.awt.*; -import java.util.Map; - -/** - * Panneau d'affichage des codes Huffman et canoniques. - * Affiche les codes pour chaque composante de couleur (rouge, vert, bleu). - * @author Algassimou - */ -public class CodeTablePanel extends JPanel { - - // Zones de texte pour les codes Huffman - private JTextArea textHuffRouge, textHuffVert, textHuffBleu; - - // Zones de texte pour les codes canoniques - private JTextArea textCanonRouge, textCanonVert, textCanonBleu; - - /** - * Constructeur qui initialise l'interface utilisateur. - */ - public CodeTablePanel() { - setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); - - // Titre pour les codes Huffman - JLabel titreHuff = new JLabel("Codes Huffman"); - titreHuff.setFont(new Font("SansSerif", Font.BOLD, 16)); - add(titreHuff); - add(Box.createVerticalStrut(10)); - - // Création des zones de texte pour les codes Huffman - textHuffRouge = creerZoneTexte("Rouge"); - textHuffVert = creerZoneTexte("Vert"); - textHuffBleu = creerZoneTexte("Bleu"); - - // Séparateur - add(Box.createVerticalStrut(20)); - - // Titre pour les codes canoniques - JLabel titreCanon = new JLabel("Codes Canoniques"); - titreCanon.setFont(new Font("SansSerif", Font.BOLD, 16)); - add(titreCanon); - add(Box.createVerticalStrut(10)); - - // Création des zones de texte pour les codes canoniques - textCanonRouge = creerZoneTexte("Rouge (Canonique)"); - textCanonVert = creerZoneTexte("Vert (Canonique)"); - textCanonBleu = creerZoneTexte("Bleu (Canonique)"); - } - - /** - * Crée une zone de texte avec une étiquette. - * @param titre Le titre à afficher au-dessus de la zone de texte - * @return La zone de texte configurée - */ - private JTextArea creerZoneTexte(String titre) { - add(new JLabel(titre + ":")); - JTextArea zone = new JTextArea(8, 30); - zone.setEditable(false); - zone.setFont(new Font("Monospaced", Font.PLAIN, 12)); - JScrollPane scroll = new JScrollPane(zone); - scroll.setPreferredSize(new Dimension(300, 120)); - add(scroll); - add(Box.createVerticalStrut(10)); - return zone; - } - - /** - * Met à jour l'affichage des codes Huffman. - * @param rouge Les codes pour la composante rouge - * @param vert Les codes pour la composante verte - * @param bleu Les codes pour la composante bleue - */ - public void updateCodes(Map rouge, - Map vert, - Map bleu) { - mettreAJourZoneTexte(textHuffRouge, rouge); - mettreAJourZoneTexte(textHuffVert, vert); - mettreAJourZoneTexte(textHuffBleu, bleu); - } - - /** - * Met à jour l'affichage des codes canoniques. - * @param rouge Les codes pour la composante rouge - * @param vert Les codes pour la composante verte - * @param bleu Les codes pour la composante bleue - */ - public void updateCanonicalCodes(Map rouge, - Map vert, - Map bleu) { - mettreAJourZoneTexte(textCanonRouge, rouge); - mettreAJourZoneTexte(textCanonVert, vert); - mettreAJourZoneTexte(textCanonBleu, bleu); - } - - /** - * Met à jour le contenu d'une zone de texte avec les codes fournis. - * @param zone La zone de texte à mettre à jour - * @param codes Les codes à afficher - */ - private void mettreAJourZoneTexte(JTextArea zone, Map codes) { - StringBuilder sb = new StringBuilder(); - for (Map.Entry entry : codes.entrySet()) { - sb.append(String.format("%3d : %s%n", entry.getKey(), entry.getValue())); - } - zone.setText(sb.toString()); - } +package fr.iutfbleau.sae; + +import java.awt.*; +import java.util.Map; +import javax.swing.*; + +/** + * Panneau d'affichage des codes Huffman et canoniques. + * Affiche les codes pour chaque composante de couleur (rouge, vert, bleu). + * @author Algassimou + */ +public class CodeTablePanel extends JPanel { + + // Zones de texte pour les codes Huffman + private JTextArea textHuffRouge, textHuffVert, textHuffBleu; + + // Zones de texte pour les codes canoniques + private JTextArea textCanonRouge, textCanonVert, textCanonBleu; + + /** + * Constructeur qui initialise l'interface utilisateur. + */ + public CodeTablePanel() { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); + + // Titre pour les codes Huffman + JLabel titreHuff = new JLabel("Codes Huffman"); + titreHuff.setFont(new Font("SansSerif", Font.BOLD, 16)); + add(titreHuff); + add(Box.createVerticalStrut(10)); + + // Création des zones de texte pour les codes Huffman + textHuffRouge = creerZoneTexte("Rouge"); + textHuffVert = creerZoneTexte("Vert"); + textHuffBleu = creerZoneTexte("Bleu"); + + // Séparateur + add(Box.createVerticalStrut(20)); + + // Titre pour les codes canoniques + JLabel titreCanon = new JLabel("Codes Canoniques"); + titreCanon.setFont(new Font("SansSerif", Font.BOLD, 16)); + add(titreCanon); + add(Box.createVerticalStrut(10)); + + // Création des zones de texte pour les codes canoniques + textCanonRouge = creerZoneTexte("Rouge (Canonique)"); + textCanonVert = creerZoneTexte("Vert (Canonique)"); + textCanonBleu = creerZoneTexte("Bleu (Canonique)"); + } + + /** + * Crée une zone de texte avec une étiquette. + * @param titre Le titre à afficher au-dessus de la zone de texte + * @return La zone de texte configurée + */ + private JTextArea creerZoneTexte(String titre) { + add(new JLabel(titre + ":")); + JTextArea zone = new JTextArea(8, 30); + zone.setEditable(false); + zone.setFont(new Font("Monospaced", Font.PLAIN, 12)); + JScrollPane scroll = new JScrollPane(zone); + scroll.setPreferredSize(new Dimension(300, 120)); + add(scroll); + add(Box.createVerticalStrut(10)); + return zone; + } + + /** + * Met à jour l'affichage des codes Huffman. + * @param rouge Les codes pour la composante rouge + * @param vert Les codes pour la composante verte + * @param bleu Les codes pour la composante bleue + */ + public void updateCodes(Map rouge, + Map vert, + Map bleu) { + mettreAJourZoneTexte(textHuffRouge, rouge); + mettreAJourZoneTexte(textHuffVert, vert); + mettreAJourZoneTexte(textHuffBleu, bleu); + } + + /** + * Met à jour l'affichage des codes canoniques. + * @param rouge Les codes pour la composante rouge + * @param vert Les codes pour la composante verte + * @param bleu Les codes pour la composante bleue + */ + public void updateCanonicalCodes(Map rouge, + Map vert, + Map bleu) { + mettreAJourZoneTexte(textCanonRouge, rouge); + mettreAJourZoneTexte(textCanonVert, vert); + mettreAJourZoneTexte(textCanonBleu, bleu); + } + + /** + * Met à jour le contenu d'une zone de texte avec les codes fournis. + * @param zone La zone de texte à mettre à jour + * @param codes Les codes à afficher + */ + private void mettreAJourZoneTexte(JTextArea zone, Map codes) { + StringBuilder sb = new StringBuilder(); + for (Map.Entry entry : codes.entrySet()) { + sb.append(String.format("%3d : %s%n", entry.getKey(), entry.getValue())); + } + zone.setText(sb.toString()); + } } \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/ConverterController.java b/src/fr/iutfbleau/sae/ConverterController.java index 82db243..b0b0aa2 100644 --- a/src/fr/iutfbleau/sae/ConverterController.java +++ b/src/fr/iutfbleau/sae/ConverterController.java @@ -1,14 +1,15 @@ package fr.iutfbleau.sae; import fr.iutfbleau.sae.mhuffman.*; -import fr.iutfbleau.sae.mimage.*; import fr.iutfbleau.sae.mpif.PIFWriter; -import fr.iutfbleau.sae.vconverter.ConverterWindow; +import fr.iutfbleau.sae.mpif.Pixel; +import fr.iutfbleau.sae.mpif.RGBImage; +import fr.iutfbleau.sae.util.GestionErreur; import java.awt.image.BufferedImage; import java.io.File; +import java.io.IOException; import java.util.Map; import javax.imageio.ImageIO; import javax.swing.JFileChooser; -import javax.swing.JOptionPane; /** * Contrôleur pour la conversion d'images. @@ -45,8 +46,6 @@ public class ConverterController { this.fen = fen; this.outputPath = out; this.inputPath = in; - - System.out.println(this.inputPath+" ==> "+this.outputPath); } @@ -76,24 +75,19 @@ public class ConverterController { this.image.setPixel(x, y, new Pixel(r, g, b)); } } - // Mettre à jour le GUI this.fen.setImagePreview(buffimage); - - } catch (Exception e) { - e.printStackTrace(); + } catch (IOException e) { + GestionErreur.afficherErreur("Erreur lors du chargement : " + e.getMessage()); } } public void computeFrequencies() { - - if (this.image == null) { - System.err.println("Aucune image chargée pour le calcul des fréquences."); - return; - } - this.frequencyTable = new FrequencyTable(); + if (this.image == null) { + System.out.println("Gros pepin"); + } this.frequencyTable.computeFromImage(this.image); // Mettre à jour le GUI avec les fréquences @@ -105,12 +99,6 @@ public class ConverterController { public void computeHuffman() { - - if (this.frequencyTable == null) { - System.err.println("Les fréquences ne sont pas encore calculées."); - return; - } - // Génération des arbres de Huffman pour chaque composante et stockage des codes HuffmanTree arbreR = new HuffmanTree(this.frequencyTable.getRed()); this.abrHuffmanR = arbreR.generateCodes(); @@ -123,12 +111,7 @@ public class ConverterController { this.fen.setHuffmanTable(this.abrHuffmanR, this.abrHuffmanG, this.abrHuffmanB); } - public void computeCanonical() { - if (this.abrHuffmanR == null || this.abrHuffmanG == null || this.abrHuffmanB == null) { - System.err.println("Les codes de Huffman doivent être générés d'abord."); - return; - } - + public void computeCanonical(){ CanonicalCode codeCanoniques = new CanonicalCode(); this.canonRED = codeCanoniques.generateCodes(this.abrHuffmanR); this.canonGREEN = codeCanoniques.generateCodes(this.abrHuffmanG); @@ -139,10 +122,11 @@ public class ConverterController { } + public void saveAsPIF(String pathfile) { - // je Vérifie que l'image et les codes canoniques sont disponibles - if(this.image == null || this.canonRED == null){ - System.err.println("Impossible d'ecrire le fichier PIF : données manquantes."); + // je vérifie que l'image et les codes canoniques sont disponibles + if(this.image == null || this.canonRED == null){ + GestionErreur.afficherErreur("Impossible de sauvegarder : image ou codes canoniques manquants."); return; } @@ -150,16 +134,15 @@ public class ConverterController { PIFWriter ecriveur = new PIFWriter(); ecriveur.writeTOFile(pathfile, this.image, this.canonRED, this.canonGREEN, this.canonBLUE); } catch (Exception e) { - System.err.println("Erreur lors de l’écriture du fichier .pif : " + pathfile); + GestionErreur.afficherErreur("Erreur lors de l’écriture du fichier .pif : "); } } - public void saveViaBtn() { try { if (outputPath != null) { saveAsPIF(outputPath); - System.out.println("Sauvegarde dans : " + outputPath); + GestionErreur.afficherInfo("Fichier sauvegardé avec succès. Chemin : " + outputPath); return; } @@ -170,23 +153,31 @@ public class ConverterController { if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { //saveAsPIF(chooser.getSelectedFile().getAbsolutePath()); // On lance la sauvegarde lourde dans un thread séparé - new Thread(() -> saveAsPIF(chooser.getSelectedFile().getAbsolutePath())).start(); - System.out.println("Fichier sauvegardé : " + chooser.getSelectedFile().getAbsolutePath()); - JOptionPane.showMessageDialog(null, "Fichier sauvegardé avec succès : " + chooser.getSelectedFile().getName()); + new Thread(() -> { + try { + saveAsPIF(chooser.getSelectedFile().getAbsolutePath()); + GestionErreur.afficherInfo("Fichier sauvegardé avec succès : " + chooser.getSelectedFile().getName()); + } catch (Exception e) { + GestionErreur.afficherErreur("Erreur lors de la sauvegarde : " + e.getMessage()); + } + }).start(); } - System.out.println("Via BTN Sauvegarde terminée."); - - } catch (Exception ex) { - System.out.println("Erreur lors de la sauvegarde : " + ex.getMessage()); + } catch (Exception e) { + GestionErreur.afficherErreur("Erreur lors de la sauvegarde : "); } } - public void StartconvessionProcess(){ + public void convessionProcess(){ // chragement if (this.inputPath != null) { // Chargement direct depuis les arguments File file = new File(inputPath); + if (!file.exists()) { + GestionErreur.afficherErreur("Le fichier n'existe pas : " + inputPath); + System.exit(1); + return; + } this.loadImage(file); }else{ // Sinon JFileChooser pour choisir l'image @@ -195,7 +186,7 @@ public class ConverterController { if (choosser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { this.loadImage(choosser.getSelectedFile()); }else { - System.err.println("Aucune image choisie. Arrêt du programme."); + GestionErreur.afficherErreur("Aucune image choisie. Arrêt du programme."); System.exit(1); return; } @@ -209,7 +200,7 @@ public class ConverterController { // Sauvegarder: un second argument est donné sauvegarde automatique if (this.outputPath != null) { this.saveAsPIF(this.outputPath); - System.out.println("Fichier sauvegardé automatiquement : " + this.outputPath); + GestionErreur.afficherInfo("Fichier sauvegardé automatiquement : " + this.outputPath); }else{ // pas de deuxième argument j'ajoute un boutton pour choisir avec un jfilechoser fen.addSaveButton(this); diff --git a/src/fr/iutfbleau/sae/vconverter/ConverterWindow.java b/src/fr/iutfbleau/sae/ConverterWindow.java similarity index 94% rename from src/fr/iutfbleau/sae/vconverter/ConverterWindow.java rename to src/fr/iutfbleau/sae/ConverterWindow.java index 09df126..f41aa1a 100644 --- a/src/fr/iutfbleau/sae/vconverter/ConverterWindow.java +++ b/src/fr/iutfbleau/sae/ConverterWindow.java @@ -1,161 +1,159 @@ -package fr.iutfbleau.sae.vconverter; -import java.awt.image.BufferedImage; -import java.util.Map; -import java.awt.*; -import javax.swing.*; - -import fr.iutfbleau.sae.ConverterController; -import fr.iutfbleau.sae.ExportButtonListener; - -/** - * Fenêtre principale du convertisseur. - * - *

- * Cette classe correspond à la vue principale de l’application. - * Elle centralise l’affichage des informations liées à la conversion - * d’une image (aperçu, fréquences, codes). - *

- * - * - *

- * Elle sert de point d’entrée unique pour la partie graphique - *

- */ -public class ConverterWindow extends JFrame { - - private ImagePreviewPanel imagePreviewPanel; - private FrequencyTablePanel frequencyTablePanel; - private CodeTablePanel codeTablePanel; - - - - /** - * Crée la fenêtre principale du convertisseur. - * - *

- * Le constructeur initialise la fenêtre et met en place - * les différents panneaux graphiques utilisés pour l’affichage. - *

- */ - - public ConverterWindow() { - // Configuration de la fenetre - this.setTitle("Convertisseur PIF - Visualisation des données"); - this.setSize(900, 600); - this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - this.setLocationRelativeTo(null); // Centre la fenêtre - this.setResizable(true); // on autorise le - this.setLayout(new BorderLayout()); - - - - // Initialisation des panels - this.imagePreviewPanel = new ImagePreviewPanel(); - this.frequencyTablePanel = new FrequencyTablePanel(); - this.codeTablePanel = new CodeTablePanel(); - - // Je gere le panel principal - JPanel contentPanel = new JPanel(); - contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS)); - //contentPanel.setBackground(new Color(255, 0, 0)); // rouge vif pour demo - contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - // Titre - JLabel header = new JLabel(" Convertisseur PIF – Visualisation des données "); - header.setFont(new Font("SansSerif", Font.BOLD, 18)); - header.setAlignmentX(Component.CENTER_ALIGNMENT); - contentPanel.add(header); - - contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); // espace - - // Ajout du panel d'aperçu - contentPanel.add(imagePreviewPanel); - contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); - // Ajout du panel des fréquences - contentPanel.add(frequencyTablePanel); - contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); - // Ajout panel des codes - contentPanel.add(codeTablePanel); - contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); - // la section du scrollpane - JScrollPane scrollPane = new JScrollPane(contentPanel); - scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); - scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - scrollPane.getVerticalScrollBar().setUnitIncrement(16); // scroll plus adouci fluide - - this.add(scrollPane, BorderLayout.CENTER); - this.setVisible(true); - } - - - - /** - * Met à jour l’image affichée dans la zone d’aperçu. - * - *

- * Cette méthode est appelée lorsque l’image à convertir - * a été chargée. La fenêtre ne modifie pas l’image : - * elle la transmet simplement au panneau d’aperçu. - *

- * - * @param img image à afficher - */ - public void setImagePreview(BufferedImage img) { - imagePreviewPanel.setImage(img); - } - - /** - * Met à jour l’affichage des tables de fréquences. - */ - public void setFrequencyTable(int[] freqR,int[] freqG,int[] freqB) { - frequencyTablePanel.updateFrequencies(freqR,freqG,freqB); - } - - /** - * Met à jour l’affichage des codes Huffman. - * - *

- * Elle permet uniquement d’afficher les codes - * qui ont été produits par la partie traitement. - *

- */ - public void setHuffmanTable(Map codesRouge, - Map codesVert, - Map codesBleu) { - codeTablePanel.updateCodes(codesRouge, codesVert, codesBleu); - } - - /** - * Met à jour l’affichage des codes canoniques. - * - *

- * Les codes canoniques sont transmis au panneau - * chargé de leur affichage. - *

- */ - public void setCanonicalTable(Map codesRouge, - Map codesVert, - Map codesBleu) { - codeTablePanel.updateCanonicalCodes(codesRouge, codesVert, codesBleu); - } - - public void addSaveButton(ConverterController controller) { - JButton saveBtn = new JButton("Exporter en .pif"); - ExportButtonListener ecouteur =new ExportButtonListener(controller); - saveBtn.addActionListener(ecouteur); - - // panneau du bas - JPanel bottomPanel = new JPanel(); - bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); - bottomPanel.add(saveBtn); - - // ajoute au bas de la fenêtre - this.add(bottomPanel, BorderLayout.SOUTH); - - // rafraîchir l'affichage - this.revalidate(); - this.repaint(); -} - - -} +package fr.iutfbleau.sae; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.Map; +import javax.swing.*; + +/** + * Fenêtre principale du convertisseur. + * + *

+ * Cette classe correspond à la vue principale de l’application. + * Elle centralise l’affichage des informations liées à la conversion + * d’une image (aperçu, fréquences, codes). + *

+ * + * + *

+ * Elle sert de point d’entrée unique pour la partie graphique + *

+ */ +public class ConverterWindow extends JFrame { + + private ImagePreviewPanel imagePreviewPanel; + private FrequencyTablePanel frequencyTablePanel; + private CodeTablePanel codeTablePanel; + + + + /** + * Crée la fenêtre principale du convertisseur. + * + *

+ * Le constructeur initialise la fenêtre et met en place + * les différents panneaux graphiques utilisés pour l’affichage. + *

+ */ + + public ConverterWindow() { + // Configuration de la fenetre + this.setTitle("Convertisseur PIF - Visualisation des données"); + this.setSize(900, 600); + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setLocationRelativeTo(null); // Centre la fenêtre + this.setResizable(true); // on autorise le + this.setLayout(new BorderLayout()); + + + + // Initialisation des panels + this.imagePreviewPanel = new ImagePreviewPanel(); + this.frequencyTablePanel = new FrequencyTablePanel(); + this.codeTablePanel = new CodeTablePanel(); + + // Je gere le panel principal + JPanel contentPanel = new JPanel(); + contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS)); + //contentPanel.setBackground(new Color(255, 0, 0)); // rouge vif pour demo + contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + // Titre + JLabel header = new JLabel(" Convertisseur PIF – Visualisation des données "); + header.setFont(new Font("SansSerif", Font.BOLD, 18)); + header.setAlignmentX(Component.CENTER_ALIGNMENT); + contentPanel.add(header); + + contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); // espace + + // Ajout du panel d'aperçu + contentPanel.add(imagePreviewPanel); + contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); + // Ajout du panel des fréquences + contentPanel.add(frequencyTablePanel); + contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); + // Ajout panel des codes + contentPanel.add(codeTablePanel); + contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); + // la section du scrollpane + JScrollPane scrollPane = new JScrollPane(contentPanel); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.getVerticalScrollBar().setUnitIncrement(16); // scroll plus adouci fluide + + this.add(scrollPane, BorderLayout.CENTER); + } + + + + /** + * Met à jour l’image affichée dans la zone d’aperçu. + * + *

+ * Cette méthode est appelée lorsque l’image à convertir + * a été chargée. La fenêtre ne modifie pas l’image : + * elle la transmet simplement au panneau d’aperçu. + *

+ * + * @param img image à afficher + */ + public void setImagePreview(BufferedImage img) { + imagePreviewPanel.setImage(img); + } + + /** + * Met à jour l’affichage des tables de fréquences. + */ + public void setFrequencyTable(int[] freqR,int[] freqG,int[] freqB) { + frequencyTablePanel.updateFrequencies(freqR,freqG,freqB); + } + + /** + * Met à jour l’affichage des codes Huffman. + * + *

+ * Elle permet uniquement d’afficher les codes + * qui ont été produits par la partie traitement. + *

+ */ + public void setHuffmanTable(Map codesRouge, + Map codesVert, + Map codesBleu) { + codeTablePanel.updateCodes(codesRouge, codesVert, codesBleu); + } + + /** + * Met à jour l’affichage des codes canoniques. + * + *

+ * Les codes canoniques sont transmis au panneau + * chargé de leur affichage. + *

+ */ + public void setCanonicalTable(Map codesRouge, + Map codesVert, + Map codesBleu) { + codeTablePanel.updateCanonicalCodes(codesRouge, codesVert, codesBleu); + + this.setVisible(true); // je limage visible apre avoir tout ajouter + } + + public void addSaveButton(ConverterController controller) { + JButton saveBtn = new JButton("Exporter en .pif"); + ExportButtonListener ecouteur =new ExportButtonListener(controller); + saveBtn.addActionListener(ecouteur); + + // panneau du bas + JPanel bottomPanel = new JPanel(); + bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); + bottomPanel.add(saveBtn); + + // ajoute au bas de la fenêtre + this.add(bottomPanel, BorderLayout.SOUTH); + + // rafraîchir l'affichage + this.revalidate(); + this.repaint(); +} + + +} diff --git a/src/fr/iutfbleau/sae/Convertisseur.java b/src/fr/iutfbleau/sae/Convertisseur.java index 717df12..9d2afbf 100644 --- a/src/fr/iutfbleau/sae/Convertisseur.java +++ b/src/fr/iutfbleau/sae/Convertisseur.java @@ -1,7 +1,5 @@ package fr.iutfbleau.sae; -import fr.iutfbleau.sae.vconverter.ConverterWindow; - public class Convertisseur { public static void main(String[] args) { @@ -20,6 +18,7 @@ public class Convertisseur { // je la passe au controleur ConverterController controller = new ConverterController(window, inpuPath, outputPath); - controller.StartconvessionProcess(); + // je demare le programe de conversion + controller.convessionProcess(); } } \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/vconverter/FrequencyTablePanel.java b/src/fr/iutfbleau/sae/FrequencyTablePanel.java similarity index 94% rename from src/fr/iutfbleau/sae/vconverter/FrequencyTablePanel.java rename to src/fr/iutfbleau/sae/FrequencyTablePanel.java index dbe1f95..031ae79 100644 --- a/src/fr/iutfbleau/sae/vconverter/FrequencyTablePanel.java +++ b/src/fr/iutfbleau/sae/FrequencyTablePanel.java @@ -1,70 +1,70 @@ -package fr.iutfbleau.sae.vconverter; - -import javax.swing.*; -import java.awt.*; - - -public class FrequencyTablePanel extends JPanel { - // 3 Zone de texte pour la fréquence du rouge , du vert et du bleu - private JTextArea freqRouge , freqVert , freqBleu; - - public FrequencyTablePanel() { - setLayout(new BoxLayout(this , BoxLayout.Y_AXIS)); - setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); - - // Premiere étiquette pour les fréquences en géneral - JLabel etiquette1 = new JLabel("Frequence"); - etiquette1.setFont(new Font("SansSerif", Font.BOLD, 16)); - super.add(etiquette1); - super.add(Box.createVerticalStrut(10)); - - - // Puis création de zone de texte pour le rouge , le vert et le bleu - this.freqRouge = creationZoneText("Rouge"); - this.freqVert = creationZoneText("Vert"); - this.freqBleu = creationZoneText("Bleu"); - - - - - } - - private JTextArea creationZoneText(String t) { - super.add(new JLabel(t + ":")); - GridLayout gestionnaire_mise_en_page = new GridLayout(5,5,10,10); - JTextArea zone = new JTextArea(8, 30); - zone.setLayout(gestionnaire_mise_en_page); - zone.setEditable(false); - zone.setFont(new Font("Monospaced", Font.PLAIN, 12)); - JScrollPane scroll = new JScrollPane(zone); - scroll.setPreferredSize(new Dimension(300, 120)); - add(scroll); - add(Box.createVerticalStrut(10)); - return zone; - } - - - public void updateFrequencies(int[] freqR,int[] freqG,int[] freqB) { - mettreAJour(freqRouge,freqR); - mettreAJour(freqVert,freqG); - mettreAJour(freqBleu,freqB); - - } - - - public void mettreAJour(JTextArea zone,int[] frequence){ - StringBuilder string = new StringBuilder(); - - for(int i = 0 ; i < frequence.length ; i++){ - string.append(String.format("%3d : %s%n", i, frequence[i])); - - if(i%10 == 0 && i!=0){ - string.append("\n"); - } - - } - - - zone.setText(string.toString()); - } -} +package fr.iutfbleau.sae; + +import java.awt.*; +import javax.swing.*; + + +public class FrequencyTablePanel extends JPanel { + // 3 Zone de texte pour la fréquence du rouge , du vert et du bleu + private JTextArea freqRouge , freqVert , freqBleu; + + public FrequencyTablePanel() { + setLayout(new BoxLayout(this , BoxLayout.Y_AXIS)); + setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); + + // Premiere étiquette pour les fréquences en géneral + JLabel etiquette1 = new JLabel("Frequence"); + etiquette1.setFont(new Font("SansSerif", Font.BOLD, 16)); + super.add(etiquette1); + super.add(Box.createVerticalStrut(10)); + + + // Puis création de zone de texte pour le rouge , le vert et le bleu + this.freqRouge = creationZoneText("Rouge"); + this.freqVert = creationZoneText("Vert"); + this.freqBleu = creationZoneText("Bleu"); + + + + + } + + private JTextArea creationZoneText(String t) { + super.add(new JLabel(t + ":")); + GridLayout gestionnaire_mise_en_page = new GridLayout(5,5,10,10); + JTextArea zone = new JTextArea(8, 30); + zone.setLayout(gestionnaire_mise_en_page); + zone.setEditable(false); + zone.setFont(new Font("Monospaced", Font.PLAIN, 12)); + JScrollPane scroll = new JScrollPane(zone); + scroll.setPreferredSize(new Dimension(300, 120)); + add(scroll); + add(Box.createVerticalStrut(10)); + return zone; + } + + + public void updateFrequencies(int[] freqR,int[] freqG,int[] freqB) { + mettreAJour(freqRouge,freqR); + mettreAJour(freqVert,freqG); + mettreAJour(freqBleu,freqB); + + } + + + public void mettreAJour(JTextArea zone,int[] frequence){ + StringBuilder string = new StringBuilder(); + + for(int i = 0 ; i < frequence.length ; i++){ + string.append(String.format("%3d : %s%n", i, frequence[i])); + + if(i%10 == 0 && i!=0){ + string.append("\n"); + } + + } + + + zone.setText(string.toString()); + } +} diff --git a/src/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.java b/src/fr/iutfbleau/sae/ImagePreviewPanel.java similarity index 94% rename from src/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.java rename to src/fr/iutfbleau/sae/ImagePreviewPanel.java index 5123983..11c4ae4 100644 --- a/src/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.java +++ b/src/fr/iutfbleau/sae/ImagePreviewPanel.java @@ -1,76 +1,76 @@ -package fr.iutfbleau.sae.vconverter; - -import java.awt.image.BufferedImage; -import javax.swing.JPanel; -import java.awt.*; - /** - * Le panneau d’aperçu de l’image. - * - *

- * Ce panneau affiche un aperçu de l’image en cours de conversion. - *

- */ - - -public class ImagePreviewPanel extends JPanel { - - private BufferedImage image; - - // je donne une taille préférée au panel - public ImagePreviewPanel() { - this.setPreferredSize(new Dimension(600, 800)); - this.setMinimumSize(new Dimension(600, 800)); - } - - - public void setImage(BufferedImage img) { - this.image = img; - repaint(); - - } - - @Override - protected void paintComponent(Graphics pinceau) { - // Appel de la méthode parente pour effacer l'arrière-plan - super.paintComponent(pinceau); - - if (image == null) { - return; - } - - // Recuperer les dimensions du panel pour centrer l'image - int panelWidth = this.getWidth(); - int panelHeight = this.getHeight(); - - // Recuperer les dimensions de l'image - int imgWidth = image.getWidth(); - int imgHeight = image.getHeight(); - - // Je calcule le facteur du reduction (si l'image est trop grande) en gros le dezoom - double scale = Math.min( - (double) panelWidth / imgWidth, - (double) panelHeight / imgHeight - ); - - // Si l'image est plus petite que le panel, on ne la redimensionne pas donc scale = 1 - if (scale > 1.0) { - scale = 1.0; - } - - // je recalcule les dimensions de l'image à dessiner - int drawWidth = (int) (imgWidth * scale); - int drawHeight = (int) (imgHeight * scale); - - // Centrage de l'image dans le panel - int x = (panelWidth - drawWidth) / 2; - int y = (panelHeight - drawHeight) / 2; - - Graphics2D pinceau2D = (Graphics2D) pinceau; - pinceau2D.setRenderingHint( - RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BILINEAR - ); - - pinceau2D.drawImage(image, x, y, drawWidth, drawHeight, this); - } +package fr.iutfbleau.sae; + +import java.awt.*; +import java.awt.image.BufferedImage; +import javax.swing.JPanel; + /** + * Le panneau d’aperçu de l’image. + * + *

+ * Ce panneau affiche un aperçu de l’image en cours de conversion. + *

+ */ + + +public class ImagePreviewPanel extends JPanel { + + private BufferedImage image; + + // je donne une taille préférée au panel + public ImagePreviewPanel() { + this.setPreferredSize(new Dimension(600, 800)); + this.setMinimumSize(new Dimension(600, 800)); + } + + + public void setImage(BufferedImage img) { + this.image = img; + repaint(); + + } + + @Override + protected void paintComponent(Graphics pinceau) { + // Appel de la méthode parente pour effacer l'arrière-plan + super.paintComponent(pinceau); + + if (image == null) { + return; + } + + // Recuperer les dimensions du panel pour centrer l'image + int panelWidth = this.getWidth(); + int panelHeight = this.getHeight(); + + // Recuperer les dimensions de l'image + int imgWidth = image.getWidth(); + int imgHeight = image.getHeight(); + + // Je calcule le facteur du reduction (si l'image est trop grande) en gros le dezoom + double scale = Math.min( + (double) panelWidth / imgWidth, + (double) panelHeight / imgHeight + ); + + // Si l'image est plus petite que le panel, on ne la redimensionne pas donc scale = 1 + if (scale > 1.0) { + scale = 1.0; + } + + // je recalcule les dimensions de l'image à dessiner + int drawWidth = (int) (imgWidth * scale); + int drawHeight = (int) (imgHeight * scale); + + // Centrage de l'image dans le panel + int x = (panelWidth - drawWidth) / 2; + int y = (panelHeight - drawHeight) / 2; + + Graphics2D pinceau2D = (Graphics2D) pinceau; + pinceau2D.setRenderingHint( + RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BILINEAR + ); + + pinceau2D.drawImage(image, x, y, drawWidth, drawHeight, this); + } } \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/Viewer.java b/src/fr/iutfbleau/sae/Viewer.java index 97446a7..6b102e0 100644 --- a/src/fr/iutfbleau/sae/Viewer.java +++ b/src/fr/iutfbleau/sae/Viewer.java @@ -1,36 +1,20 @@ -<<<<<<< HEAD -package fr.iutfbleau.sae; - -public class Viewer { - public static void main(String[] args) { - System.out.println("dqkdjqkdjqkdjqkdjqkdj"); - } -} -======= + package fr.iutfbleau.sae; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; - -//teste avec ia -private void chargerFichier() { - JTextArea zoneTexte = new JTextArea(); - zoneTexte.setEditable(false); - - try (BufferedReader br = new BufferedReader(new FileReader(fichierPif))) { - String ligne; - while ((ligne = br.readLine()) != null) { - zoneTexte.append(ligne + "\n"); +public class Viewer { + public static void main(String[] args) { + // chemins de l'image + String inpuPath = null; + if (args.length >= 1) { + inpuPath = args[0]; } - } catch (IOException e) { - JOptionPane.showMessageDialog(this, - "Erreur lors de l'ouverture du fichier", - "Erreur", - JOptionPane.ERROR_MESSAGE); - } - add(new JScrollPane(zoneTexte), BorderLayout.CENTER); - setVisible(true); + ViewerWindow fen = new ViewerWindow(); + ViewerControleur controleur = new ViewerControleur(fen,inpuPath); + + + controleur.loadPIF(); + + } } ->>>>>>> 40f71dddd52fc07edc1d47d48d56fd65a2a79fe3 + diff --git a/src/fr/iutfbleau/sae/ViewerControleur.java b/src/fr/iutfbleau/sae/ViewerControleur.java new file mode 100644 index 0000000..7dd786c --- /dev/null +++ b/src/fr/iutfbleau/sae/ViewerControleur.java @@ -0,0 +1,98 @@ +package fr.iutfbleau.sae; + +import fr.iutfbleau.sae.mpif.PIFReader; +import fr.iutfbleau.sae.mpif.Pixel; +import fr.iutfbleau.sae.mpif.RGBImage; +import fr.iutfbleau.sae.util.GestionErreur; +import java.awt.image.BufferedImage; +import java.io.File; +import javax.swing.JFileChooser; + +public class ViewerControleur { + + private RGBImage image; // L'image à décoder + private ViewerWindow window; // La fenêtre du visualiseur + private File file; + + public ViewerControleur(ViewerWindow window, String path) { + this.window = window; + if (path != null) { + this.file = new File(path); + } else { + this.file = null; + } + } + + public void loadPIF() { + File fichierPIF; + // Déterminer si on le charge avec jFilechoose ou pas + if (this.file != null) { + // Fichier fourni en argument + fichierPIF = this.file; + } else { + // Demander à l'utilisateur via JFileChooser + JFileChooser chooser = new JFileChooser(); + chooser.setDialogTitle("Choisissez un fichier PIF"); + + if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + fichierPIF = chooser.getSelectedFile(); + } else { + GestionErreur.afficherErreur("Aucun fichier sélectionné. Arrêt du programme."); + System.exit(1); + return; + } + } + + + // je Vérifi la conformiter du fichier avec isPIFFile + if (!PIFReader.isPIFFile(fichierPIF)) { + GestionErreur.afficherErreur("Le fichier fourni n'est pas au format PIF (.pif)"); + return; + } + + // je Charge et décoder le fichier PIF + try { + PIFReader lecteur = new PIFReader(); + this.image = lecteur.decodePifFile(fichierPIF); + + System.out.println("Image décodée : " + this.image.getWidth() + "x" + this.image.getHeight()); + + // je convertit RGBImage en BufferedImage + BufferedImage buffImg = convertToBufferedImage(this.image); + + // j'affiche l'image + this.window.displayImage(buffImg); + + } catch (Exception e) { + GestionErreur.afficherErreur("Erreur lors du chargement du fichier PIF : "); + } + } + + /** + * Convertit une RGBImage en BufferedImage. + * + * @param rgbImage l'image à convertir + * @return l'image convertie + */ + private BufferedImage convertToBufferedImage(RGBImage rgbImage) { + int width = rgbImage.getWidth(); + int height = rgbImage.getHeight(); + + BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + + // Copier tous les pixels + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + Pixel pixel = rgbImage.getPixel(x, y); + + // Composer la couleur RGB la couleur est coder sur 32 bit argb chacun a 8 bit + int rgb = (pixel.getR() << 16) | (pixel.getG() << 8) | pixel.getB(); + + // Définir le pixel dans le BufferedImage + buffImg.setRGB(x, y, rgb); + } + } + + return buffImg; + } +} \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/ViewerWindow.java b/src/fr/iutfbleau/sae/ViewerWindow.java new file mode 100644 index 0000000..18709d0 --- /dev/null +++ b/src/fr/iutfbleau/sae/ViewerWindow.java @@ -0,0 +1,91 @@ +package fr.iutfbleau.sae; + +import java.awt.*; +import java.awt.event.*; +import java.awt.image.BufferedImage; +import javax.swing.*; + +public class ViewerWindow extends JFrame implements MouseListener, MouseMotionListener { + + private BufferedImage image; + + private int offsetX = 0; + private int offsetY = 0; + + private int lastX; + private int lastY; + + public ViewerWindow() { + super("PIF Viewer"); + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setResizable(true); + this.addMouseListener(this); + this.addMouseMotionListener(this); + } + + + public void displayImage(BufferedImage img) { + this.image = img; + + // je prend la taille de l'ecran + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + + // je prend una taille de 90% pour etre raisonable + int maxW = (int)(screen.width * 0.9); + int maxH = (int)(screen.height * 0.9); + + int w = Math.min(img.getWidth(), maxW); + int h = Math.min(img.getHeight(), maxH); + + this.setSize(w, h); + this.setLocationRelativeTo(null); + this.setVisible(true); + } + + @Override + public void paint(Graphics g) { + + super.paint(g); + + if (image == null) return; + + int panelW = getWidth(); + int panelH = getHeight(); + + int imgW = image.getWidth(); + int imgH = image.getHeight(); + + int drawX = offsetX; + int drawY = offsetY; + + // centrage automatique si image plus petite + if (imgW < panelW) drawX = (panelW - imgW) / 2; + if (imgH < panelH) drawY = (panelH - imgH) / 2; + + g.drawImage(image, drawX, drawY, null); + } + + + @Override + public void mousePressed(MouseEvent e) { + lastX = e.getX(); + lastY = e.getY(); + } + + @Override + public void mouseDragged(MouseEvent e) { + offsetX += e.getX() - lastX; + offsetY += e.getY() - lastY; + + lastX = e.getX(); + lastY = e.getY(); + + repaint(); + } + + @Override public void mouseReleased(MouseEvent e) {} + @Override public void mouseClicked(MouseEvent e) {} + @Override public void mouseEntered(MouseEvent e) {} + @Override public void mouseExited(MouseEvent e) {} + @Override public void mouseMoved(MouseEvent e) {} +} diff --git a/src/fr/iutfbleau/sae/mhuffman/CanonicalCode.java b/src/fr/iutfbleau/sae/mhuffman/CanonicalCode.java index af8c9f7..2bd235d 100644 --- a/src/fr/iutfbleau/sae/mhuffman/CanonicalCode.java +++ b/src/fr/iutfbleau/sae/mhuffman/CanonicalCode.java @@ -16,13 +16,7 @@ public class CanonicalCode{ List> liste = new ArrayList<>(codesHuffman.entrySet()); // ici on comparer par longueur de la valeur ou sinon par la clé - - - Collections.sort(liste, new ComparateurCanonique()); - - - Map canonicalCodes = new HashMap<>(); int code = 0; // code canonique à attribuer int temp = 0; //garde la longueur du code précedent , pour gérer le décalage diff --git a/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java b/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java index 9768aa2..a34b8b9 100644 --- a/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java +++ b/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java @@ -1,6 +1,6 @@ package fr.iutfbleau.sae.mhuffman; -import fr.iutfbleau.sae.mimage.Pixel; -import fr.iutfbleau.sae.mimage.RGBImage; +import fr.iutfbleau.sae.mpif.Pixel; +import fr.iutfbleau.sae.mpif.RGBImage; /** * Représente une table de fréquences pour une image RGB. @@ -33,13 +33,13 @@ import fr.iutfbleau.sae.mimage.RGBImage; public class FrequencyTable { /** Tableau des fréquences pour la composante rouge (valeurs de 0 à 255). */ - private int[] freqR; + private final int[] freqR; /** Tableau des fréquences pour la composante verte (valeurs de 0 à 255). */ - private int[] freqG; + private final int[] freqG; /** Tableau des fréquences pour la composante bleue (valeurs de 0 à 255). */ - private int[] freqB; + private final int[] freqB; /** * Construit une table de fréquences vide. diff --git a/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java b/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java index 2d3482f..2dad2ca 100644 --- a/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java +++ b/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java @@ -4,7 +4,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; -// test +import fr.iutfbleau.sae.util.HuffmanNode; /** * Implémente un arbre de Huffman utilisé pour la compression de données. @@ -59,14 +59,7 @@ public class HuffmanTree { */ // j'ai retirer le static car chaque arbre a ses propres codes et j'utilise string plutot que int pour stocker les codes car on construit une chaine de 0 et de 1 private Map codes; - - /** - * Chaine de caracteres qui va nous permettre de sauvegader le code Huffman - * Permet en d'autres termes de construire la chaine de 1 et de 0 - */ - - private String chaineCarac; /** * Construit un arbre de Huffman. diff --git a/src/fr/iutfbleau/sae/mpif/PIFReader.java b/src/fr/iutfbleau/sae/mpif/PIFReader.java index 596da0b..2d219f0 100644 --- a/src/fr/iutfbleau/sae/mpif/PIFReader.java +++ b/src/fr/iutfbleau/sae/mpif/PIFReader.java @@ -1,9 +1,14 @@ package fr.iutfbleau.sae.mpif; -import fr.iutfbleau.sae.mimage.RGBImage; -import fr.iutfbleau.sae.util.BitInputStream; +import fr.iutfbleau.sae.util.BitInputStream; +import fr.iutfbleau.sae.util.DecodeNode; import java.io.BufferedInputStream; +import java.io.File; import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; @@ -15,73 +20,250 @@ public class PIFReader { private int[] lenG; private int[] lenB; - public RGBImage read(String filepath) - throws Exception { - - // j'Utilise d'un BufferedInputStream pour une meilleure performance - FileInputStream fis = new FileInputStream(filepath); - BufferedInputStream bis = new BufferedInputStream(fis); - BitInputStream lecteur = new BitInputStream(bis); + /** + * Lit et décode un fichier PIF. + * + * @param filepath chemin du fichier PIF + * @return l'image RGB décodée + * @throws Exception si erreur de lecture + */ + public RGBImage decodePifFile(File file) throws Exception { + FileInputStream fis = new FileInputStream(file); + BufferedInputStream bos = new BufferedInputStream(fis); + BitInputStream lecteur = new BitInputStream(bos); - // je lis l'entête et les tables canoniques + // Je lis l'en-tête et les tables canoniques this.readHeader(lecteur); this.readCanonicalTables(lecteur); - // je reconstructe les tables canoniques car dans le fichier on a juste les longueurs en bits + // Je reconstruis les tables canoniques car dans le fichier on a juste les longueurs en bits Map canonR = rebuildCanonical(lenR); Map canonG = rebuildCanonical(lenG); Map canonB = rebuildCanonical(lenB); + // Je construis les arbres de décodage DecodeNode trieR = buildDecodageTree(canonR); DecodeNode trieG = buildDecodageTree(canonG); DecodeNode trieB = buildDecodageTree(canonB); + // Je décode les pixels RGBImage img = decodePixels(lecteur, trieR, trieG, trieB); lecteur.closeFlux(); + System.out.println("Fichier PIF lu avec succès : " + width + "x" + height); return img; } - public void readHeader(BitInputStream in) { - - // La largeur et l'hauteur de l'image occupe chaqun deux octets soit 16 bits : + + /** + * Lit l'en-tête du fichier PIF (largeur et hauteur sur 16 bits chacune). + * @throws IOException si erreur de lecture + */ + public void readHeader(BitInputStream in) throws IOException { this.width = in.readBits(16); this.height = in.readBits(16); + System.out.println("Dimensions lues : " + this.width + "x" + this.height); } - public void readCanonicalTables(BitInputStream in) { - this.lenR = new int[256]; - this.lenG = new int[256]; - this.lenB = new int[256]; + /** + * Lit les trois tables de longueurs (R, G, B). + * Chaque table contient 256 valeurs sur 5 bits. + * @throws IOException si erreur de lecture + */ + public void readCanonicalTables(BitInputStream in) throws IOException { + // Table Rouge + this.lenR = new int[256]; for (int i = 0; i < 256; i++){ - lenR[i] = in.readBits(8); + this.lenR[i] = in.readBits(8); } - for (int j = 0; j < 256; j++){ - lenG[j] = in.readBits(8); + + // Table Vert + this.lenG = new int[256]; + for (int i = 0; i < 256; i++){ + this.lenG[i] = in.readBits(8); + } + + // Table Bleu + this.lenB = new int[256]; + for (int i = 0; i < 256; i++){ + this.lenB[i] = in.readBits(8); + } + + System.out.println("Tables de longueurs lues"); + } + + /** + * Reconstruit les codes canoniques à partir des longueurs. + * + * @param lengths tableau de 256 longueurs + * @return Map pour le décodage + */ + public Map rebuildCanonical(int[] lengths) { + // je cree une liste de paires (symbole, longueur) + List> entiers = new ArrayList<>(); + + for (int i = 0; i < lengths.length; i++) { + if (lengths[i] > 0) { + entiers.add(new java.util.AbstractMap.SimpleEntry<>(i, lengths[i])); + } + } + + // Je trie par longueur croissante, puis par symbole croissant + entiers.sort((a, b) -> { + int cmp = a.getValue().compareTo(b.getValue()); + if (cmp != 0) return cmp; + return a.getKey().compareTo(b.getKey()); + }); + + // je genere les codes canoniques + Map codes = new HashMap<>(); + int code = 0; + int previousLength = 0; + + for (Map.Entry entry : entiers) { + int symbol = entry.getKey(); + int length = entry.getValue(); + + // Decalage pour aligner le code sur la longueur courante + code <<= (length - previousLength); + + // je convertit ce code en texte binaire + String codeStr = Integer.toBinaryString(code); + // On s'assure que la chaîne a la bonne longueur en ajoutant des zéros à gauche si nécessaire + while (codeStr.length() < length) { + codeStr = "0" + codeStr; + } + // je restocke le code + symbole en inversant car la map est inverse dans l'encodage + codes.put(codeStr, symbol); + + code++; + previousLength = length; + + } + + return codes; + } + + /** + * Construit l'arbre de décodage à partir des codes canoniques. + * + * @param codes Map les codes canoniques avec les bits comme clés et les symboles comme valeurs + * @return la racine de l'arbre de décodage + */ + public DecodeNode buildDecodageTree(Map codes) { + DecodeNode root = new DecodeNode(); // la racine de larbre + + for (Map.Entry entry : codes.entrySet()) { + String code = entry.getKey(); // 101011101110 par exemple + int symbol = entry.getValue(); // 0,1,2,3 etc. par exemple + + DecodeNode current = root; + + // je parcours le code bit à bit + for (int i = 0; i < code.length(); i++) { + char bit = code.charAt(i); + + if(i == code.length() - 1) { + // Dernier bit: je cree une feuille avec la valeur du symbol + if(bit == '0') { + current.left = new DecodeNode(null, null, symbol); + } else { + current.right = new DecodeNode(null, null, symbol); + } + } else { + // Si c'est pas le dernier bit : je creer un node interne + if(bit == '0') { + if(current.left == null) { + current.left = new DecodeNode(); // Node interne + } + current = current.left; + } else { + if(current.right == null) { + current.right = new DecodeNode(); // node intern + } + current = current.right; + } + } + } + } + return root; + } + + + + /** + * Décode les pixels à partir des arbres de décodage. + * + * @param in flux d'entrée binaire + * @param red arbre de décodage pour la composante rouge + * @param green arbre de décodage pour la composante verte + * @param blue arbre de décodage pour la composante bleue + * @return l'image reconstruite + */ + public RGBImage decodePixels(BitInputStream in, DecodeNode red, DecodeNode green, DecodeNode blue) throws IOException{ + RGBImage image = new RGBImage(width, height); + + for(int y = 0; y < height; y++) { + for(int x = 0; x < width; x++) { + // je decode chaque composante en parcourant son arbre + int r = decodeSymbole(in, red); + int g = decodeSymbole(in, green); + int b = decodeSymbole(in, blue); + + // je cree et je place le pixel + Pixel pixel = new Pixel(r, g, b); + image.setPixel(x, y, pixel); + } + } + return image; + } + + /** + * Décode un symbole en parcourant l'arbre bit par bit + * @param in le flux d'entrée binaire + * @param root la racine de l'arbre de décodage + * @return le symbole décodé (valeur entre 0 et 255) + * @throws IOException si une erreur d'entrée/sortie se produit + */ + private int decodeSymbole(BitInputStream in, DecodeNode root) throws IOException { + DecodeNode current = root; + + // je parcours l'arbre en suivant les bits du flux jusqu'à atteindre une feuille + while (!current.isLeaf()) { + int bit = in.readBit(); + if (bit == 0) { + current = current.left; + } else { + current = current.right; + } + + if (current == null) { + throw new IOException("code invalide: noeud null rencontre"); + } + } + // si on est arrivé à une feuille, on retourne la valeur + if (current.value == -1) { + throw new IOException("Feuille sans valeur assignée"); + } + return current.value; + } + + + public static boolean isPIFFile(File f) { + if (f == null){ + return false; + } + if (!f.exists() || !f.isFile()){ + return false; + } + + //je verifi l'extension + String name = f.getName().toLowerCase(); + if (!name.endsWith(".pif")) { + return false; } - for (int k = 0; k < 256; k++){ - lenB[k] = in.readBits(8); - } -} - - public Map rebuildCanonical(int[] lengths) { - // TODO: Implement canonical table reconstruction - return null; + return f.length() >= 772; // taille minimal pour un fichier pif longueur largeur et tables de frequance } - - public RGBImage decodePixels(BitInputStream in, DecodeNode red, DecodeNode green, DecodeNode blue) { - // TODO: Implement pixel decoding - return null; - } - - public DecodeNode buildDecodageTree(Map codes) { - // TODO: Implement trie building - return null; - } - - - - } diff --git a/src/fr/iutfbleau/sae/mpif/PIFWriter.java b/src/fr/iutfbleau/sae/mpif/PIFWriter.java index 199ac17..72b4eda 100644 --- a/src/fr/iutfbleau/sae/mpif/PIFWriter.java +++ b/src/fr/iutfbleau/sae/mpif/PIFWriter.java @@ -1,7 +1,5 @@ package fr.iutfbleau.sae.mpif; -import fr.iutfbleau.sae.mimage.RGBImage; -import fr.iutfbleau.sae.mimage.Pixel; import fr.iutfbleau.sae.util.BitOutputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; @@ -31,17 +29,15 @@ public class PIFWriter { encodePixels(ecriveur, image, canonR, canonG, canonB); ecriveur.fermerFlux(); - - System.out.println("Fichier PIF écrit avec succès"); } // Ecriture de l'en-tête du fichier PIF (largeur et hauteur) public void writeHeader(BitOutputStream out, int width, int height) { try { - out.writeBits(width, 16); // ✅ Simplifié : 16 bits d'un coup - out.writeBits(height, 16); // ✅ Simplifié : 16 bits d'un coup - } catch (Exception e) { - System.err.println("Erreur lors de l'écriture de l'en-tête du fichier PIF"); + out.writeBits(width, 16); + out.writeBits(height, 16); + } catch (IOException e) { + System.err.println("Erreur lors de l'écriture de l'en-tête du fichier PIF: " + e.getMessage()); } } @@ -82,31 +78,6 @@ public class PIFWriter { } catch (IOException e) { System.err.println("Erreur lors de l'écriture des tables de fréquences dans le fichier PIF"); } - - - // Debug pour compter les symboles utilisés et calculer les longueurs moyennes - int totalBitsR = 0, totalBitsG = 0, totalBitsB = 0; - int countR = 0, countG = 0, countB = 0; - - for (int i = 0; i < 256; i++) { - if (canonR.containsKey(i)) { - totalBitsR += canonR.get(i).length(); - countR++; - } - if (canonG.containsKey(i)) { - totalBitsG += canonG.get(i).length(); - countG++; - } - if (canonB.containsKey(i)) { - totalBitsB += canonB.get(i).length(); - countB++; - } - } - - System.out.println("Longueur moyenne Rouge : " + (totalBitsR / (double)countR)); - System.out.println("Longueur moyenne Vert : " + (totalBitsG / (double)countG)); - System.out.println("Longueur moyenne Bleu : " + (totalBitsB / (double)countB)); - System.out.println("Symboles utilisés - R:" + countR + " G:" + countG + " B:" + countB); } // Méthode pour encoder les pixels de l'image en utilisant les codes canoniques diff --git a/src/fr/iutfbleau/sae/mimage/Pixel.java b/src/fr/iutfbleau/sae/mpif/Pixel.java similarity index 88% rename from src/fr/iutfbleau/sae/mimage/Pixel.java rename to src/fr/iutfbleau/sae/mpif/Pixel.java index eb8db1a..aa7c348 100644 --- a/src/fr/iutfbleau/sae/mimage/Pixel.java +++ b/src/fr/iutfbleau/sae/mpif/Pixel.java @@ -1,38 +1,38 @@ -package fr.iutfbleau.sae.mimage; - -public class Pixel{ - private int r; - private int g; - private int b; - - //à completer - public Pixel(int red, int green, int blue){ - this.r=red; - this.g=green; - this.b=blue; - } - - public int getB() { - return b; - } - - public int getG() { - return g; - } - - public int getR() { - return r; - } - - public void setR(int r) { - this.r = r; - } - - public void setB(int b) { - this.b = b; - } - - public void setG(int g) { - this.g = g; - } +package fr.iutfbleau.sae.mpif; + +public class Pixel{ + private int r; + private int g; + private int b; + + //à completer + public Pixel(int red, int green, int blue){ + this.r=red; + this.g=green; + this.b=blue; + } + + public int getB() { + return b; + } + + public int getG() { + return g; + } + + public int getR() { + return r; + } + + public void setR(int r) { + this.r = r; + } + + public void setB(int b) { + this.b = b; + } + + public void setG(int g) { + this.g = g; + } } \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/mimage/RGBImage.java b/src/fr/iutfbleau/sae/mpif/RGBImage.java similarity index 89% rename from src/fr/iutfbleau/sae/mimage/RGBImage.java rename to src/fr/iutfbleau/sae/mpif/RGBImage.java index a92b2f0..8c3bb71 100644 --- a/src/fr/iutfbleau/sae/mimage/RGBImage.java +++ b/src/fr/iutfbleau/sae/mpif/RGBImage.java @@ -1,30 +1,31 @@ -package fr.iutfbleau.sae.mimage; - -public class RGBImage { - - private int width; - private int height; - private Pixel [][] pixels; - - public RGBImage (int lar, int haut){ - this.width=lar; - this.height=haut; - this.pixels = new Pixel[this.width][this.height]; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public void setPixel(int x, int y, Pixel p) { - this.pixels[x][y] = p; - } - - public Pixel getPixel(int x, int y) { - return this.pixels[x][y]; - } +package fr.iutfbleau.sae.mpif; + +public class RGBImage { + + private int width; + private int height; + private Pixel [][] pixels; + + public RGBImage (int lar, int haut){ + this.width=lar; + this.height=haut; + this.pixels = new Pixel[this.width][this.height]; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public void setPixel(int x, int y, Pixel p) { + this.pixels[x][y] = p; + } + + public Pixel getPixel(int x, int y) { + return this.pixels[x][y]; + } + } \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/util/ByteUtils.java b/src/fr/iutfbleau/sae/util/ByteUtils.java deleted file mode 100644 index 864363b..0000000 --- a/src/fr/iutfbleau/sae/util/ByteUtils.java +++ /dev/null @@ -1,89 +0,0 @@ -package fr.iutfbleau.sae.util; - -/** - * Classe utilitaire regroupant des opérations de conversion entre - * entiers et octets. - *

- * Elle est utilisée pour encoder et décoder les champs binaires - * du format PIF (largeur, hauteur, tailles, etc.). - *

- * - *

- * Cette classe : - *

    - *
  • ne lit aucun fichier
  • - *
  • n'écrit aucun fichier
  • - *
  • ne manipule pas les bits individuellement
  • - *
- * Elle fournit uniquement des conversions octets ↔ entiers. - *

- */ -public final class ByteUtils { - - /** - * Constructeur privé empêchant l'instanciation. - *

- * Cette classe est purement utilitaire et ne doit pas être instanciée. - *

- */ - private ByteUtils() { - // j'empêche l'instanciation - } - - /** - * Convertit un entier non négatif en deux octets (ordre big-endian). - *

- * L'octet de poids fort est placé en première position, - * suivi de l'octet de poids faible. - *

- * - * @param value valeur entière à convertir (0 ≤ value ≤ 65535) - * @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) { - if (value < 0 || value > 0xFFFF) { - throw new IllegalArgumentException( - "La valeur doit être comprise entre 0 et 65535" - ); - } - - byte[] result = new byte[2]; - - /* - * Extraction de l'octet de poids fort : - * - décalage de 8 bits vers la droite - * - masquage pour ne conserver que les 8 bits utiles - */ - result[0] = (byte) ((value >>> 8) & 0xFF); - - /* - * Extraction de l'octet de poids faible : - * - aucun décalage nécessaire - * - masquage pour conserver les 8 bits de droite - */ - result[1] = (byte) (value & 0xFF); - - return result; - } - - /** - * Reconstruit un entier à partir de deux octets (ordre big-endian). - *

- * L'octet de poids fort est replacé dans les bits 15 à 8, - * puis combiné avec l'octet de poids faible. - *

- * - * @param high octet de poids fort - * @param low octet de poids faible - * @return entier reconstruit à partir des deux octets - */ - public static int toInt(byte high, byte low) { - /* - * - masquage pour supprimer le signe des octets Java - * - décalage de l'octet fort vers la gauche - * - combinaison des deux octets par un OU binaire - */ - return ((high & 0xFF) << 8) | (low & 0xFF); - } -} diff --git a/src/fr/iutfbleau/sae/mpif/DecodeNode.java b/src/fr/iutfbleau/sae/util/DecodeNode.java similarity index 85% rename from src/fr/iutfbleau/sae/mpif/DecodeNode.java rename to src/fr/iutfbleau/sae/util/DecodeNode.java index 800852d..96a8e3c 100644 --- a/src/fr/iutfbleau/sae/mpif/DecodeNode.java +++ b/src/fr/iutfbleau/sae/util/DecodeNode.java @@ -1,23 +1,23 @@ -package fr.iutfbleau.sae.mpif; - -public class DecodeNode { - public DecodeNode left; - public DecodeNode right; - public Integer value; // null si pas une feuille - - public DecodeNode() { - this.left = null; - this.right = null; - this.value = null; - } - - public DecodeNode(DecodeNode left, DecodeNode right, Integer value) { - this.left = left; - this.right = right; - this.value = value; - } - - public boolean isLeaf() { - return this.left == null && this.right == null; - } -} +package fr.iutfbleau.sae.util; + +public class DecodeNode { + public DecodeNode left; + public DecodeNode right; + public Integer value; // null si pas une feuille + + public DecodeNode() { + this.left = null; + this.right = null; + this.value = -1; // valeur non initialisée + } + + public DecodeNode(DecodeNode left, DecodeNode right, Integer value) { + this.left = left; + this.right = right; + this.value = value; + } + + public boolean isLeaf() { + return this.left == null && this.right == null; + } +} diff --git a/src/fr/iutfbleau/sae/util/GestErreur.java b/src/fr/iutfbleau/sae/util/GestErreur.java deleted file mode 100644 index be95dd0..0000000 --- a/src/fr/iutfbleau/sae/util/GestErreur.java +++ /dev/null @@ -1,8 +0,0 @@ -package fr.iutfbleau.sae.util; - -public class GestErreur { - public static void erreur(String message) { - System.err.println("Erreur : " + message); - System.exit(1); - } -} \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/util/GestionErreur.java b/src/fr/iutfbleau/sae/util/GestionErreur.java new file mode 100644 index 0000000..391a6cc --- /dev/null +++ b/src/fr/iutfbleau/sae/util/GestionErreur.java @@ -0,0 +1,12 @@ +package fr.iutfbleau.sae.util; +import javax.swing.*; + +public class GestionErreur { + public static void afficherErreur(String message) { + JOptionPane.showMessageDialog(null, message, "Erreur", JOptionPane.ERROR_MESSAGE); + } + + public static void afficherInfo(String message) { + JOptionPane.showMessageDialog(null, message, "Information", JOptionPane.INFORMATION_MESSAGE); + } +} \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/mhuffman/HuffmanNode.java b/src/fr/iutfbleau/sae/util/HuffmanNode.java similarity index 99% rename from src/fr/iutfbleau/sae/mhuffman/HuffmanNode.java rename to src/fr/iutfbleau/sae/util/HuffmanNode.java index e3dcefb..05a713c 100644 --- a/src/fr/iutfbleau/sae/mhuffman/HuffmanNode.java +++ b/src/fr/iutfbleau/sae/util/HuffmanNode.java @@ -1,4 +1,4 @@ -package fr.iutfbleau.sae.mhuffman; +package fr.iutfbleau.sae.util; /** * Représente un nœud de l'arbre de Huffman. diff --git a/src/fr/iutfbleau/sae/vviewer/ImagePanel.java b/src/fr/iutfbleau/sae/vviewer/ImagePanel.java deleted file mode 100644 index 17f6cda..0000000 --- a/src/fr/iutfbleau/sae/vviewer/ImagePanel.java +++ /dev/null @@ -1,7 +0,0 @@ -package fr.iutfbleau.sae.vviewer; - -public class ImagePanel extends JPanel{ - - - -} \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/vviewer/ViewerWindow.java b/src/fr/iutfbleau/sae/vviewer/ViewerWindow.java deleted file mode 100644 index 9df89f0..0000000 --- a/src/fr/iutfbleau/sae/vviewer/ViewerWindow.java +++ /dev/null @@ -1,11 +0,0 @@ -package fr.iutfbleau.sae.vviewer; - -public class ViewerWindow extends JFrame{ - - - - - - - -} \ No newline at end of file diff --git a/temp/2026png.pif b/temp/2026png.pif deleted file mode 100644 index 49ed9a3..0000000 Binary files a/temp/2026png.pif and /dev/null differ diff --git a/temp/bob1.pif b/temp/bob1.pif deleted file mode 100644 index 4bd454b..0000000 Binary files a/temp/bob1.pif and /dev/null differ diff --git a/temp/kikikikirou.pif b/temp/kikikikirou.pif new file mode 100644 index 0000000..1caa413 Binary files /dev/null and b/temp/kikikikirou.pif differ diff --git a/temp/test.pif b/temp/test.pif deleted file mode 100644 index 49ed9a3..0000000 Binary files a/temp/test.pif and /dev/null differ diff --git a/temp/test2.pif b/temp/test2.pif deleted file mode 100644 index 1b52740..0000000 Binary files a/temp/test2.pif and /dev/null differ diff --git a/temp/test_checkerboard_256bmp.bmp b/temp/test_checkerboard_256bmp.bmp new file mode 100644 index 0000000..c21a37e Binary files /dev/null and b/temp/test_checkerboard_256bmp.bmp differ diff --git a/temp/test_checkerboard_256bmp.pif b/temp/test_checkerboard_256bmp.pif new file mode 100644 index 0000000..1caa413 Binary files /dev/null and b/temp/test_checkerboard_256bmp.pif differ