petit push sprint 3 fini

This commit is contained in:
AlgaLaptop
2026-01-05 10:19:59 +01:00
parent d20ef2c406
commit 6ec6ac85a4
52 changed files with 1059 additions and 842 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
+68 -50
View File
@@ -32,12 +32,14 @@ all: \
# Compilation des classes main # Compilation des classes main
$(BIN)/$(PKG_PATH)/Convertisseur.class: $(BIN) \ $(BIN)/$(PKG_PATH)/Convertisseur.class: $(BIN) \
$(BIN)/$(PKG_PATH)/ConverterController.class \ $(BIN)/$(PKG_PATH)/ConverterController.class \
$(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class \ $(BIN)/$(PKG_PATH)/ConverterWindow.class \
$(BIN)/$(PKG_PATH)/ExportButtonListener.class \ $(BIN)/$(PKG_PATH)/ExportButtonListener.class \
$(SRC)/$(PKG_PATH)/Convertisseur.java $(SRC)/$(PKG_PATH)/Convertisseur.java
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/Convertisseur.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/Convertisseur.java
$(BIN)/$(PKG_PATH)/Viewer.class: $(BIN) \ $(BIN)/$(PKG_PATH)/Viewer.class: $(BIN) \
$(BIN)/$(PKG_PATH)/ViewerWindow.class \
$(BIN)/$(PKG_PATH)/ViewerControleur.class \
$(SRC)/$(PKG_PATH)/Viewer.java $(SRC)/$(PKG_PATH)/Viewer.java
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/Viewer.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/Viewer.java
@@ -50,9 +52,9 @@ $(DOC):
# Compilation des classes util # Compilation des classes util
$(BIN)/$(PKG_PATH)/util/ByteUtils.class: $(BIN) \ $(BIN)/$(PKG_PATH)/util/DecodeNode.class: $(BIN) \
$(SRC)/$(PKG_PATH)/util/ByteUtils.java $(SRC)/$(PKG_PATH)/util/DecodeNode.java
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/ByteUtils.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/DecodeNode.java
$(BIN)/$(PKG_PATH)/util/BitInputStream.class: $(BIN) \ $(BIN)/$(PKG_PATH)/util/BitInputStream.class: $(BIN) \
$(SRC)/$(PKG_PATH)/util/BitInputStream.java $(SRC)/$(PKG_PATH)/util/BitInputStream.java
@@ -62,15 +64,19 @@ $(BIN)/$(PKG_PATH)/util/BitOutputStream.class: $(BIN) \
$(SRC)/$(PKG_PATH)/util/BitOutputStream.java $(SRC)/$(PKG_PATH)/util/BitOutputStream.java
$(JAVAC) -cp $(BIN) -d $(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 # Compilation des classes mhuffman
# Ajout de la classe ComparateurCanonique :
$(BIN)/$(PKG_PATH)/mhuffman/ComparateurCanonique.class: $(BIN) \ $(BIN)/$(PKG_PATH)/mhuffman/ComparateurCanonique.class: $(BIN) \
$(SRC)/$(PKG_PATH)/mhuffman/ComparateurCanonique.java $(SRC)/$(PKG_PATH)/mhuffman/ComparateurCanonique.java
$(JAVAC) -cp $(BIN) -d $(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) \ $(BIN)/$(PKG_PATH)/mhuffman/CanonicalCode.class: $(BIN) \
$(SRC)/$(PKG_PATH)/mhuffman/CanonicalCode.java \ $(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 $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/CanonicalCode.java
$(BIN)/$(PKG_PATH)/mhuffman/FrequencyTable.class: $(BIN) \ $(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 $(SRC)/$(PKG_PATH)/mhuffman/FrequencyTable.java
$(JAVAC) -cp $(BIN) -d $(BIN) $(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/HuffmanTree.class: $(BIN) \
$(BIN)/$(PKG_PATH)/mhuffman/HuffmanNode.class \ $(BIN)/$(PKG_PATH)/util/HuffmanNode.class \
$(SRC)/$(PKG_PATH)/mhuffman/HuffmanTree.java $(SRC)/$(PKG_PATH)/mhuffman/HuffmanTree.java
$(JAVAC) -cp $(BIN) -d $(BIN) $(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 # Interface graphique
$(BIN)/$(PKG_PATH)/vconverter/ImagePreviewPanel.class: $(BIN) \ $(BIN)/$(PKG_PATH)/ImagePreviewPanel.class: $(BIN) \
$(SRC)/$(PKG_PATH)/vconverter/ImagePreviewPanel.java $(SRC)/$(PKG_PATH)/ImagePreviewPanel.java
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/ImagePreviewPanel.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/ImagePreviewPanel.java
$(BIN)/$(PKG_PATH)/vconverter/FrequencyTablePanel.class: $(BIN) \ $(BIN)/$(PKG_PATH)/FrequencyTablePanel.class: $(BIN) \
$(SRC)/$(PKG_PATH)/vconverter/FrequencyTablePanel.java $(SRC)/$(PKG_PATH)/FrequencyTablePanel.java
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/FrequencyTablePanel.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/FrequencyTablePanel.java
$(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class: $(BIN) \ $(BIN)/$(PKG_PATH)/CodeTablePanel.class: $(BIN) \
$(SRC)/$(PKG_PATH)/vconverter/CodeTablePanel.java $(SRC)/$(PKG_PATH)/CodeTablePanel.java
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/CodeTablePanel.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/CodeTablePanel.java
# $(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class: $(BIN) \ $(BIN)/$(PKG_PATH)/ViewerWindow.class: $(BIN) \
# $(BIN)/$(PKG_PATH)/ConverterController.class \ $(SRC)/$(PKG_PATH)/ViewerWindow.java
# $(BIN)/$(PKG_PATH)/vconverter/ImagePreviewPanel.class \ $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/ViewerWindow.java
# $(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
# 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)/mpif/PIFWriter.class: $(BIN) \
$(BIN)/$(PKG_PATH)/mimage/RGBImage.class \ $(BIN)/$(PKG_PATH)/mpif/RGBImage.class \
$(BIN)/$(PKG_PATH)/util/BitOutputStream.class \ $(BIN)/$(PKG_PATH)/util/BitOutputStream.class \
$(SRC)/$(PKG_PATH)/mpif/PIFWriter.java $(SRC)/$(PKG_PATH)/mpif/PIFWriter.java
$(JAVAC) -cp $(BIN) -d $(BIN) $(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 # GROSSE compilation du listener + ConvertController + ConvertWindow + PIFSaverTask car il y a une dependance cirulaire
$(BIN)/$(PKG_PATH)/ConverterController.class \ $(BIN)/$(PKG_PATH)/ConverterController.class \
$(BIN)/$(PKG_PATH)/ExportButtonListener.class \ $(BIN)/$(PKG_PATH)/ExportButtonListener.class \
$(BIN)/$(PKG_PATH)/PIFSaveTask.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)/ConverterController.java \
$(SRC)/$(PKG_PATH)/ExportButtonListener.java \ $(SRC)/$(PKG_PATH)/ExportButtonListener.java \
$(SRC)/$(PKG_PATH)/PIFSaveTask.java \ $(SRC)/$(PKG_PATH)/PIFSaveTask.java \
$(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java \ $(SRC)/$(PKG_PATH)/ConverterWindow.java \
$(BIN)/$(PKG_PATH)/mimage/Pixel.class \ $(BIN)/$(PKG_PATH)/mpif/Pixel.class \
$(BIN)/$(PKG_PATH)/mimage/RGBImage.class \ $(BIN)/$(PKG_PATH)/mpif/RGBImage.class \
$(BIN)/$(PKG_PATH)/mhuffman/FrequencyTable.class \ $(BIN)/$(PKG_PATH)/mhuffman/FrequencyTable.class \
$(BIN)/$(PKG_PATH)/mhuffman/HuffmanTree.class \ $(BIN)/$(PKG_PATH)/mhuffman/HuffmanTree.class \
$(BIN)/$(PKG_PATH)/mhuffman/CanonicalCode.class \ $(BIN)/$(PKG_PATH)/mhuffman/CanonicalCode.class \
$(BIN)/$(PKG_PATH)/vconverter/ImagePreviewPanel.class \ $(BIN)/$(PKG_PATH)/ImagePreviewPanel.class \
$(BIN)/$(PKG_PATH)/vconverter/FrequencyTablePanel.class \ $(BIN)/$(PKG_PATH)/FrequencyTablePanel.class \
$(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class \ $(BIN)/$(PKG_PATH)/CodeTablePanel.class \
$(BIN)/$(PKG_PATH)/util/GestionErreur.class \
$(BIN)/$(PKG_PATH)/mpif/PIFWriter.class | $(BIN) $(BIN)/$(PKG_PATH)/mpif/PIFWriter.class | $(BIN)
@$(JAVAC) -cp $(BIN) -d $(BIN) \ @$(JAVAC) -cp $(BIN) -d $(BIN) \
$(SRC)/$(PKG_PATH)/ConverterController.java \ $(SRC)/$(PKG_PATH)/ConverterController.java \
$(SRC)/$(PKG_PATH)/ExportButtonListener.java \ $(SRC)/$(PKG_PATH)/ExportButtonListener.java \
$(SRC)/$(PKG_PATH)/PIFSaveTask.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 # Exécution
run-conv: all run-conv: all
$(JAVA) -cp $(BIN) $(MAIN_CONVERTER) $(ARGS) $(JAVA) -cp $(BIN) $(MAIN_CONVERTER) $(ARGS)
run-view: all run-view: $(BIN)/$(PKG_PATH)/Viewer.class
$(JAVA) -cp $(BIN) $(MAIN_VIEWER) $(JAVA) -cp $(BIN) $(MAIN_VIEWER) $(ARGS)
# Documentation # Documentation
doc: $(DOC) doc: $(DOC)
@@ -1,110 +1,110 @@
package fr.iutfbleau.sae.vconverter; package fr.iutfbleau.sae;
import javax.swing.*; import java.awt.*;
import java.awt.*; import java.util.Map;
import java.util.Map; import javax.swing.*;
/** /**
* Panneau d'affichage des codes Huffman et canoniques. * Panneau d'affichage des codes Huffman et canoniques.
* Affiche les codes pour chaque composante de couleur (rouge, vert, bleu). * Affiche les codes pour chaque composante de couleur (rouge, vert, bleu).
* @author Algassimou * @author Algassimou
*/ */
public class CodeTablePanel extends JPanel { public class CodeTablePanel extends JPanel {
// Zones de texte pour les codes Huffman // Zones de texte pour les codes Huffman
private JTextArea textHuffRouge, textHuffVert, textHuffBleu; private JTextArea textHuffRouge, textHuffVert, textHuffBleu;
// Zones de texte pour les codes canoniques // Zones de texte pour les codes canoniques
private JTextArea textCanonRouge, textCanonVert, textCanonBleu; private JTextArea textCanonRouge, textCanonVert, textCanonBleu;
/** /**
* Constructeur qui initialise l'interface utilisateur. * Constructeur qui initialise l'interface utilisateur.
*/ */
public CodeTablePanel() { public CodeTablePanel() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
// Titre pour les codes Huffman // Titre pour les codes Huffman
JLabel titreHuff = new JLabel("Codes Huffman"); JLabel titreHuff = new JLabel("Codes Huffman");
titreHuff.setFont(new Font("SansSerif", Font.BOLD, 16)); titreHuff.setFont(new Font("SansSerif", Font.BOLD, 16));
add(titreHuff); add(titreHuff);
add(Box.createVerticalStrut(10)); add(Box.createVerticalStrut(10));
// Création des zones de texte pour les codes Huffman // Création des zones de texte pour les codes Huffman
textHuffRouge = creerZoneTexte("Rouge"); textHuffRouge = creerZoneTexte("Rouge");
textHuffVert = creerZoneTexte("Vert"); textHuffVert = creerZoneTexte("Vert");
textHuffBleu = creerZoneTexte("Bleu"); textHuffBleu = creerZoneTexte("Bleu");
// Séparateur // Séparateur
add(Box.createVerticalStrut(20)); add(Box.createVerticalStrut(20));
// Titre pour les codes canoniques // Titre pour les codes canoniques
JLabel titreCanon = new JLabel("Codes Canoniques"); JLabel titreCanon = new JLabel("Codes Canoniques");
titreCanon.setFont(new Font("SansSerif", Font.BOLD, 16)); titreCanon.setFont(new Font("SansSerif", Font.BOLD, 16));
add(titreCanon); add(titreCanon);
add(Box.createVerticalStrut(10)); add(Box.createVerticalStrut(10));
// Création des zones de texte pour les codes canoniques // Création des zones de texte pour les codes canoniques
textCanonRouge = creerZoneTexte("Rouge (Canonique)"); textCanonRouge = creerZoneTexte("Rouge (Canonique)");
textCanonVert = creerZoneTexte("Vert (Canonique)"); textCanonVert = creerZoneTexte("Vert (Canonique)");
textCanonBleu = creerZoneTexte("Bleu (Canonique)"); textCanonBleu = creerZoneTexte("Bleu (Canonique)");
} }
/** /**
* Crée une zone de texte avec une étiquette. * Crée une zone de texte avec une étiquette.
* @param titre Le titre à afficher au-dessus de la zone de texte * @param titre Le titre à afficher au-dessus de la zone de texte
* @return La zone de texte configurée * @return La zone de texte configurée
*/ */
private JTextArea creerZoneTexte(String titre) { private JTextArea creerZoneTexte(String titre) {
add(new JLabel(titre + ":")); add(new JLabel(titre + ":"));
JTextArea zone = new JTextArea(8, 30); JTextArea zone = new JTextArea(8, 30);
zone.setEditable(false); zone.setEditable(false);
zone.setFont(new Font("Monospaced", Font.PLAIN, 12)); zone.setFont(new Font("Monospaced", Font.PLAIN, 12));
JScrollPane scroll = new JScrollPane(zone); JScrollPane scroll = new JScrollPane(zone);
scroll.setPreferredSize(new Dimension(300, 120)); scroll.setPreferredSize(new Dimension(300, 120));
add(scroll); add(scroll);
add(Box.createVerticalStrut(10)); add(Box.createVerticalStrut(10));
return zone; return zone;
} }
/** /**
* Met à jour l'affichage des codes Huffman. * Met à jour l'affichage des codes Huffman.
* @param rouge Les codes pour la composante rouge * @param rouge Les codes pour la composante rouge
* @param vert Les codes pour la composante verte * @param vert Les codes pour la composante verte
* @param bleu Les codes pour la composante bleue * @param bleu Les codes pour la composante bleue
*/ */
public void updateCodes(Map<Integer, String> rouge, public void updateCodes(Map<Integer, String> rouge,
Map<Integer, String> vert, Map<Integer, String> vert,
Map<Integer, String> bleu) { Map<Integer, String> bleu) {
mettreAJourZoneTexte(textHuffRouge, rouge); mettreAJourZoneTexte(textHuffRouge, rouge);
mettreAJourZoneTexte(textHuffVert, vert); mettreAJourZoneTexte(textHuffVert, vert);
mettreAJourZoneTexte(textHuffBleu, bleu); mettreAJourZoneTexte(textHuffBleu, bleu);
} }
/** /**
* Met à jour l'affichage des codes canoniques. * Met à jour l'affichage des codes canoniques.
* @param rouge Les codes pour la composante rouge * @param rouge Les codes pour la composante rouge
* @param vert Les codes pour la composante verte * @param vert Les codes pour la composante verte
* @param bleu Les codes pour la composante bleue * @param bleu Les codes pour la composante bleue
*/ */
public void updateCanonicalCodes(Map<Integer, String> rouge, public void updateCanonicalCodes(Map<Integer, String> rouge,
Map<Integer, String> vert, Map<Integer, String> vert,
Map<Integer, String> bleu) { Map<Integer, String> bleu) {
mettreAJourZoneTexte(textCanonRouge, rouge); mettreAJourZoneTexte(textCanonRouge, rouge);
mettreAJourZoneTexte(textCanonVert, vert); mettreAJourZoneTexte(textCanonVert, vert);
mettreAJourZoneTexte(textCanonBleu, bleu); mettreAJourZoneTexte(textCanonBleu, bleu);
} }
/** /**
* Met à jour le contenu d'une zone de texte avec les codes fournis. * Met à jour le contenu d'une zone de texte avec les codes fournis.
* @param zone La zone de texte à mettre à jour * @param zone La zone de texte à mettre à jour
* @param codes Les codes à afficher * @param codes Les codes à afficher
*/ */
private void mettreAJourZoneTexte(JTextArea zone, Map<Integer, String> codes) { private void mettreAJourZoneTexte(JTextArea zone, Map<Integer, String> codes) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Map.Entry<Integer, String> entry : codes.entrySet()) { for (Map.Entry<Integer, String> entry : codes.entrySet()) {
sb.append(String.format("%3d : %s%n", entry.getKey(), entry.getValue())); sb.append(String.format("%3d : %s%n", entry.getKey(), entry.getValue()));
} }
zone.setText(sb.toString()); zone.setText(sb.toString());
} }
} }
+34 -43
View File
@@ -1,14 +1,15 @@
package fr.iutfbleau.sae; package fr.iutfbleau.sae;
import fr.iutfbleau.sae.mhuffman.*; import fr.iutfbleau.sae.mhuffman.*;
import fr.iutfbleau.sae.mimage.*;
import fr.iutfbleau.sae.mpif.PIFWriter; 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.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.Map; import java.util.Map;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
/** /**
* Contrôleur pour la conversion d'images. * Contrôleur pour la conversion d'images.
@@ -45,8 +46,6 @@ public class ConverterController {
this.fen = fen; this.fen = fen;
this.outputPath = out; this.outputPath = out;
this.inputPath = in; 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)); this.image.setPixel(x, y, new Pixel(r, g, b));
} }
} }
// Mettre à jour le GUI // Mettre à jour le GUI
this.fen.setImagePreview(buffimage); this.fen.setImagePreview(buffimage);
} catch (IOException e) {
} catch (Exception e) { GestionErreur.afficherErreur("Erreur lors du chargement : " + e.getMessage());
e.printStackTrace();
} }
} }
public void computeFrequencies() { 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(); this.frequencyTable = new FrequencyTable();
if (this.image == null) {
System.out.println("Gros pepin");
}
this.frequencyTable.computeFromImage(this.image); this.frequencyTable.computeFromImage(this.image);
// Mettre à jour le GUI avec les fréquences // Mettre à jour le GUI avec les fréquences
@@ -105,12 +99,6 @@ public class ConverterController {
public void computeHuffman() { 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 // Génération des arbres de Huffman pour chaque composante et stockage des codes
HuffmanTree arbreR = new HuffmanTree(this.frequencyTable.getRed()); HuffmanTree arbreR = new HuffmanTree(this.frequencyTable.getRed());
this.abrHuffmanR = arbreR.generateCodes(); this.abrHuffmanR = arbreR.generateCodes();
@@ -123,12 +111,7 @@ public class ConverterController {
this.fen.setHuffmanTable(this.abrHuffmanR, this.abrHuffmanG, this.abrHuffmanB); this.fen.setHuffmanTable(this.abrHuffmanR, this.abrHuffmanG, this.abrHuffmanB);
} }
public void computeCanonical() { 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;
}
CanonicalCode codeCanoniques = new CanonicalCode(); CanonicalCode codeCanoniques = new CanonicalCode();
this.canonRED = codeCanoniques.generateCodes(this.abrHuffmanR); this.canonRED = codeCanoniques.generateCodes(this.abrHuffmanR);
this.canonGREEN = codeCanoniques.generateCodes(this.abrHuffmanG); this.canonGREEN = codeCanoniques.generateCodes(this.abrHuffmanG);
@@ -139,10 +122,11 @@ public class ConverterController {
} }
public void saveAsPIF(String pathfile) { public void saveAsPIF(String pathfile) {
// je Vérifie que l'image et les codes canoniques sont disponibles // je vérifie que l'image et les codes canoniques sont disponibles
if(this.image == null || this.canonRED == null){ if(this.image == null || this.canonRED == null){
System.err.println("Impossible d'ecrire le fichier PIF : données manquantes."); GestionErreur.afficherErreur("Impossible de sauvegarder : image ou codes canoniques manquants.");
return; return;
} }
@@ -150,16 +134,15 @@ public class ConverterController {
PIFWriter ecriveur = new PIFWriter(); PIFWriter ecriveur = new PIFWriter();
ecriveur.writeTOFile(pathfile, this.image, this.canonRED, this.canonGREEN, this.canonBLUE); ecriveur.writeTOFile(pathfile, this.image, this.canonRED, this.canonGREEN, this.canonBLUE);
} catch (Exception e) { } 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() { public void saveViaBtn() {
try { try {
if (outputPath != null) { if (outputPath != null) {
saveAsPIF(outputPath); saveAsPIF(outputPath);
System.out.println("Sauvegarde dans : " + outputPath); GestionErreur.afficherInfo("Fichier sauvegardé avec succès. Chemin : " + outputPath);
return; return;
} }
@@ -170,23 +153,31 @@ public class ConverterController {
if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
//saveAsPIF(chooser.getSelectedFile().getAbsolutePath()); //saveAsPIF(chooser.getSelectedFile().getAbsolutePath());
// On lance la sauvegarde lourde dans un thread séparé // On lance la sauvegarde lourde dans un thread séparé
new Thread(() -> saveAsPIF(chooser.getSelectedFile().getAbsolutePath())).start(); new Thread(() -> {
System.out.println("Fichier sauvegardé : " + chooser.getSelectedFile().getAbsolutePath()); try {
JOptionPane.showMessageDialog(null, "Fichier sauvegardé avec succès : " + chooser.getSelectedFile().getName()); 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 e) {
GestionErreur.afficherErreur("Erreur lors de la sauvegarde : ");
} catch (Exception ex) {
System.out.println("Erreur lors de la sauvegarde : " + ex.getMessage());
} }
} }
public void StartconvessionProcess(){ public void convessionProcess(){
// chragement // chragement
if (this.inputPath != null) { if (this.inputPath != null) {
// Chargement direct depuis les arguments // Chargement direct depuis les arguments
File file = new File(inputPath); File file = new File(inputPath);
if (!file.exists()) {
GestionErreur.afficherErreur("Le fichier n'existe pas : " + inputPath);
System.exit(1);
return;
}
this.loadImage(file); this.loadImage(file);
}else{ }else{
// Sinon JFileChooser pour choisir l'image // Sinon JFileChooser pour choisir l'image
@@ -195,7 +186,7 @@ public class ConverterController {
if (choosser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { if (choosser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
this.loadImage(choosser.getSelectedFile()); this.loadImage(choosser.getSelectedFile());
}else { }else {
System.err.println("Aucune image choisie. Arrêt du programme."); GestionErreur.afficherErreur("Aucune image choisie. Arrêt du programme.");
System.exit(1); System.exit(1);
return; return;
} }
@@ -209,7 +200,7 @@ public class ConverterController {
// Sauvegarder: un second argument est donné sauvegarde automatique // Sauvegarder: un second argument est donné sauvegarde automatique
if (this.outputPath != null) { if (this.outputPath != null) {
this.saveAsPIF(this.outputPath); this.saveAsPIF(this.outputPath);
System.out.println("Fichier sauvegardé automatiquement : " + this.outputPath); GestionErreur.afficherInfo("Fichier sauvegardé automatiquement : " + this.outputPath);
}else{ }else{
// pas de deuxième argument j'ajoute un boutton pour choisir avec un jfilechoser // pas de deuxième argument j'ajoute un boutton pour choisir avec un jfilechoser
fen.addSaveButton(this); fen.addSaveButton(this);
@@ -1,161 +1,159 @@
package fr.iutfbleau.sae.vconverter; package fr.iutfbleau.sae;
import java.awt.image.BufferedImage; import java.awt.*;
import java.util.Map; import java.awt.image.BufferedImage;
import java.awt.*; import java.util.Map;
import javax.swing.*; import javax.swing.*;
import fr.iutfbleau.sae.ConverterController; /**
import fr.iutfbleau.sae.ExportButtonListener; * Fenêtre principale du convertisseur.
*
/** * <p>
* Fenêtre principale du convertisseur. * Cette classe correspond à la vue principale de lapplication.
* * Elle centralise laffichage des informations liées à la conversion
* <p> * dune image (aperçu, fréquences, codes).
* Cette classe correspond à la vue principale de lapplication. * </p>
* Elle centralise laffichage des informations liées à la conversion *
* dune image (aperçu, fréquences, codes). *
* </p> * <p>
* * Elle sert de point dentrée unique pour la partie graphique
* * </p>
* <p> */
* Elle sert de point dentrée unique pour la partie graphique public class ConverterWindow extends JFrame {
* </p>
*/ private ImagePreviewPanel imagePreviewPanel;
public class ConverterWindow extends JFrame { private FrequencyTablePanel frequencyTablePanel;
private CodeTablePanel codeTablePanel;
private ImagePreviewPanel imagePreviewPanel;
private FrequencyTablePanel frequencyTablePanel;
private CodeTablePanel codeTablePanel;
/**
* Crée la fenêtre principale du convertisseur.
*
/** * <p>
* 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 laffichage.
* <p> * </p>
* Le constructeur initialise la fenêtre et met en place */
* les différents panneaux graphiques utilisés pour laffichage.
* </p> public ConverterWindow() {
*/ // Configuration de la fenetre
this.setTitle("Convertisseur PIF - Visualisation des données");
public ConverterWindow() { this.setSize(900, 600);
// Configuration de la fenetre this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Convertisseur PIF - Visualisation des données"); this.setLocationRelativeTo(null); // Centre la fenêtre
this.setSize(900, 600); this.setResizable(true); // on autorise le
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(new BorderLayout());
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();
// Initialisation des panels this.codeTablePanel = new CodeTablePanel();
this.imagePreviewPanel = new ImagePreviewPanel();
this.frequencyTablePanel = new FrequencyTablePanel(); // Je gere le panel principal
this.codeTablePanel = new CodeTablePanel(); JPanel contentPanel = new JPanel();
contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
// Je gere le panel principal //contentPanel.setBackground(new Color(255, 0, 0)); // rouge vif pour demo
JPanel contentPanel = new JPanel(); contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
//contentPanel.setBackground(new Color(255, 0, 0)); // rouge vif pour demo // Titre
contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JLabel header = new JLabel(" Convertisseur PIF Visualisation des données ");
header.setFont(new Font("SansSerif", Font.BOLD, 18));
// Titre header.setAlignmentX(Component.CENTER_ALIGNMENT);
JLabel header = new JLabel(" Convertisseur PIF Visualisation des données "); contentPanel.add(header);
header.setFont(new Font("SansSerif", Font.BOLD, 18));
header.setAlignmentX(Component.CENTER_ALIGNMENT); contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); // espace
contentPanel.add(header);
// Ajout du panel d'aperçu
contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); // espace contentPanel.add(imagePreviewPanel);
contentPanel.add(Box.createRigidArea(new Dimension(0, 5)));
// Ajout du panel d'aperçu // Ajout du panel des fréquences
contentPanel.add(imagePreviewPanel); contentPanel.add(frequencyTablePanel);
contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); contentPanel.add(Box.createRigidArea(new Dimension(0, 5)));
// Ajout du panel des fréquences // Ajout panel des codes
contentPanel.add(frequencyTablePanel); contentPanel.add(codeTablePanel);
contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); contentPanel.add(Box.createRigidArea(new Dimension(0, 5)));
// Ajout panel des codes // la section du scrollpane
contentPanel.add(codeTablePanel); JScrollPane scrollPane = new JScrollPane(contentPanel);
contentPanel.add(Box.createRigidArea(new Dimension(0, 5))); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
// la section du scrollpane scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JScrollPane scrollPane = new JScrollPane(contentPanel); scrollPane.getVerticalScrollBar().setUnitIncrement(16); // scroll plus adouci fluide
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); this.add(scrollPane, BorderLayout.CENTER);
scrollPane.getVerticalScrollBar().setUnitIncrement(16); // scroll plus adouci fluide }
this.add(scrollPane, BorderLayout.CENTER);
this.setVisible(true);
} /**
* Met à jour limage affichée dans la zone daperçu.
*
* <p>
/** * Cette méthode est appelée lorsque limage à convertir
* Met à jour limage affichée dans la zone daperçu. * a été chargée. La fenêtre ne modifie pas limage :
* * elle la transmet simplement au panneau daperçu.
* <p> * </p>
* Cette méthode est appelée lorsque limage à convertir *
* a été chargée. La fenêtre ne modifie pas limage : * @param img image à afficher
* elle la transmet simplement au panneau daperçu. */
* </p> public void setImagePreview(BufferedImage img) {
* imagePreviewPanel.setImage(img);
* @param img image à afficher }
*/
public void setImagePreview(BufferedImage img) { /**
imagePreviewPanel.setImage(img); * Met à jour laffichage des tables de fréquences.
} */
public void setFrequencyTable(int[] freqR,int[] freqG,int[] freqB) {
/** frequencyTablePanel.updateFrequencies(freqR,freqG,freqB);
* Met à jour laffichage des tables de fréquences. }
*/
public void setFrequencyTable(int[] freqR,int[] freqG,int[] freqB) { /**
frequencyTablePanel.updateFrequencies(freqR,freqG,freqB); * Met à jour laffichage des codes Huffman.
} *
* <p>
/** * Elle permet uniquement dafficher les codes
* Met à jour laffichage des codes Huffman. * qui ont été produits par la partie traitement.
* * </p>
* <p> */
* Elle permet uniquement dafficher les codes public void setHuffmanTable(Map<Integer, String> codesRouge,
* qui ont été produits par la partie traitement. Map<Integer, String> codesVert,
* </p> Map<Integer, String> codesBleu) {
*/ codeTablePanel.updateCodes(codesRouge, codesVert, codesBleu);
public void setHuffmanTable(Map<Integer, String> codesRouge, }
Map<Integer, String> codesVert,
Map<Integer, String> codesBleu) { /**
codeTablePanel.updateCodes(codesRouge, codesVert, codesBleu); * Met à jour laffichage des codes canoniques.
} *
* <p>
/** * Les codes canoniques sont transmis au panneau
* Met à jour laffichage des codes canoniques. * chargé de leur affichage.
* * </p>
* <p> */
* Les codes canoniques sont transmis au panneau public void setCanonicalTable(Map<Integer, String> codesRouge,
* chargé de leur affichage. Map<Integer, String> codesVert,
* </p> Map<Integer, String> codesBleu) {
*/ codeTablePanel.updateCanonicalCodes(codesRouge, codesVert, codesBleu);
public void setCanonicalTable(Map<Integer, String> codesRouge,
Map<Integer, String> codesVert, this.setVisible(true); // je limage visible apre avoir tout ajouter
Map<Integer, String> codesBleu) { }
codeTablePanel.updateCanonicalCodes(codesRouge, codesVert, codesBleu);
} public void addSaveButton(ConverterController controller) {
JButton saveBtn = new JButton("Exporter en .pif");
public void addSaveButton(ConverterController controller) { ExportButtonListener ecouteur =new ExportButtonListener(controller);
JButton saveBtn = new JButton("Exporter en .pif"); saveBtn.addActionListener(ecouteur);
ExportButtonListener ecouteur =new ExportButtonListener(controller);
saveBtn.addActionListener(ecouteur); // panneau du bas
JPanel bottomPanel = new JPanel();
// panneau du bas bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
JPanel bottomPanel = new JPanel(); bottomPanel.add(saveBtn);
bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
bottomPanel.add(saveBtn); // ajoute au bas de la fenêtre
this.add(bottomPanel, BorderLayout.SOUTH);
// ajoute au bas de la fenêtre
this.add(bottomPanel, BorderLayout.SOUTH); // rafraîchir l'affichage
this.revalidate();
// rafraîchir l'affichage this.repaint();
this.revalidate(); }
this.repaint();
}
}
}
+2 -3
View File
@@ -1,7 +1,5 @@
package fr.iutfbleau.sae; package fr.iutfbleau.sae;
import fr.iutfbleau.sae.vconverter.ConverterWindow;
public class Convertisseur { public class Convertisseur {
public static void main(String[] args) { public static void main(String[] args) {
@@ -20,6 +18,7 @@ public class Convertisseur {
// je la passe au controleur // je la passe au controleur
ConverterController controller = new ConverterController(window, inpuPath, outputPath); ConverterController controller = new ConverterController(window, inpuPath, outputPath);
controller.StartconvessionProcess(); // je demare le programe de conversion
controller.convessionProcess();
} }
} }
@@ -1,70 +1,70 @@
package fr.iutfbleau.sae.vconverter; package fr.iutfbleau.sae;
import javax.swing.*; import java.awt.*;
import java.awt.*; import javax.swing.*;
public class FrequencyTablePanel extends JPanel { public class FrequencyTablePanel extends JPanel {
// 3 Zone de texte pour la fréquence du rouge , du vert et du bleu // 3 Zone de texte pour la fréquence du rouge , du vert et du bleu
private JTextArea freqRouge , freqVert , freqBleu; private JTextArea freqRouge , freqVert , freqBleu;
public FrequencyTablePanel() { public FrequencyTablePanel() {
setLayout(new BoxLayout(this , BoxLayout.Y_AXIS)); setLayout(new BoxLayout(this , BoxLayout.Y_AXIS));
setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
// Premiere étiquette pour les fréquences en géneral // Premiere étiquette pour les fréquences en géneral
JLabel etiquette1 = new JLabel("Frequence"); JLabel etiquette1 = new JLabel("Frequence");
etiquette1.setFont(new Font("SansSerif", Font.BOLD, 16)); etiquette1.setFont(new Font("SansSerif", Font.BOLD, 16));
super.add(etiquette1); super.add(etiquette1);
super.add(Box.createVerticalStrut(10)); super.add(Box.createVerticalStrut(10));
// Puis création de zone de texte pour le rouge , le vert et le bleu // Puis création de zone de texte pour le rouge , le vert et le bleu
this.freqRouge = creationZoneText("Rouge"); this.freqRouge = creationZoneText("Rouge");
this.freqVert = creationZoneText("Vert"); this.freqVert = creationZoneText("Vert");
this.freqBleu = creationZoneText("Bleu"); this.freqBleu = creationZoneText("Bleu");
} }
private JTextArea creationZoneText(String t) { private JTextArea creationZoneText(String t) {
super.add(new JLabel(t + ":")); super.add(new JLabel(t + ":"));
GridLayout gestionnaire_mise_en_page = new GridLayout(5,5,10,10); GridLayout gestionnaire_mise_en_page = new GridLayout(5,5,10,10);
JTextArea zone = new JTextArea(8, 30); JTextArea zone = new JTextArea(8, 30);
zone.setLayout(gestionnaire_mise_en_page); zone.setLayout(gestionnaire_mise_en_page);
zone.setEditable(false); zone.setEditable(false);
zone.setFont(new Font("Monospaced", Font.PLAIN, 12)); zone.setFont(new Font("Monospaced", Font.PLAIN, 12));
JScrollPane scroll = new JScrollPane(zone); JScrollPane scroll = new JScrollPane(zone);
scroll.setPreferredSize(new Dimension(300, 120)); scroll.setPreferredSize(new Dimension(300, 120));
add(scroll); add(scroll);
add(Box.createVerticalStrut(10)); add(Box.createVerticalStrut(10));
return zone; return zone;
} }
public void updateFrequencies(int[] freqR,int[] freqG,int[] freqB) { public void updateFrequencies(int[] freqR,int[] freqG,int[] freqB) {
mettreAJour(freqRouge,freqR); mettreAJour(freqRouge,freqR);
mettreAJour(freqVert,freqG); mettreAJour(freqVert,freqG);
mettreAJour(freqBleu,freqB); mettreAJour(freqBleu,freqB);
} }
public void mettreAJour(JTextArea zone,int[] frequence){ public void mettreAJour(JTextArea zone,int[] frequence){
StringBuilder string = new StringBuilder(); StringBuilder string = new StringBuilder();
for(int i = 0 ; i < frequence.length ; i++){ for(int i = 0 ; i < frequence.length ; i++){
string.append(String.format("%3d : %s%n", i, frequence[i])); string.append(String.format("%3d : %s%n", i, frequence[i]));
if(i%10 == 0 && i!=0){ if(i%10 == 0 && i!=0){
string.append("\n"); string.append("\n");
} }
} }
zone.setText(string.toString()); zone.setText(string.toString());
} }
} }
@@ -1,76 +1,76 @@
package fr.iutfbleau.sae.vconverter; package fr.iutfbleau.sae;
import java.awt.image.BufferedImage; import java.awt.*;
import javax.swing.JPanel; import java.awt.image.BufferedImage;
import java.awt.*; import javax.swing.JPanel;
/** /**
* Le panneau daperçu de limage. * Le panneau daperçu de limage.
* *
* <p> * <p>
* Ce panneau affiche un aperçu de limage en cours de conversion. * Ce panneau affiche un aperçu de limage en cours de conversion.
* </p> * </p>
*/ */
public class ImagePreviewPanel extends JPanel { public class ImagePreviewPanel extends JPanel {
private BufferedImage image; private BufferedImage image;
// je donne une taille préférée au panel // je donne une taille préférée au panel
public ImagePreviewPanel() { public ImagePreviewPanel() {
this.setPreferredSize(new Dimension(600, 800)); this.setPreferredSize(new Dimension(600, 800));
this.setMinimumSize(new Dimension(600, 800)); this.setMinimumSize(new Dimension(600, 800));
} }
public void setImage(BufferedImage img) { public void setImage(BufferedImage img) {
this.image = img; this.image = img;
repaint(); repaint();
} }
@Override @Override
protected void paintComponent(Graphics pinceau) { protected void paintComponent(Graphics pinceau) {
// Appel de la méthode parente pour effacer l'arrière-plan // Appel de la méthode parente pour effacer l'arrière-plan
super.paintComponent(pinceau); super.paintComponent(pinceau);
if (image == null) { if (image == null) {
return; return;
} }
// Recuperer les dimensions du panel pour centrer l'image // Recuperer les dimensions du panel pour centrer l'image
int panelWidth = this.getWidth(); int panelWidth = this.getWidth();
int panelHeight = this.getHeight(); int panelHeight = this.getHeight();
// Recuperer les dimensions de l'image // Recuperer les dimensions de l'image
int imgWidth = image.getWidth(); int imgWidth = image.getWidth();
int imgHeight = image.getHeight(); int imgHeight = image.getHeight();
// Je calcule le facteur du reduction (si l'image est trop grande) en gros le dezoom // Je calcule le facteur du reduction (si l'image est trop grande) en gros le dezoom
double scale = Math.min( double scale = Math.min(
(double) panelWidth / imgWidth, (double) panelWidth / imgWidth,
(double) panelHeight / imgHeight (double) panelHeight / imgHeight
); );
// Si l'image est plus petite que le panel, on ne la redimensionne pas donc scale = 1 // Si l'image est plus petite que le panel, on ne la redimensionne pas donc scale = 1
if (scale > 1.0) { if (scale > 1.0) {
scale = 1.0; scale = 1.0;
} }
// je recalcule les dimensions de l'image à dessiner // je recalcule les dimensions de l'image à dessiner
int drawWidth = (int) (imgWidth * scale); int drawWidth = (int) (imgWidth * scale);
int drawHeight = (int) (imgHeight * scale); int drawHeight = (int) (imgHeight * scale);
// Centrage de l'image dans le panel // Centrage de l'image dans le panel
int x = (panelWidth - drawWidth) / 2; int x = (panelWidth - drawWidth) / 2;
int y = (panelHeight - drawHeight) / 2; int y = (panelHeight - drawHeight) / 2;
Graphics2D pinceau2D = (Graphics2D) pinceau; Graphics2D pinceau2D = (Graphics2D) pinceau;
pinceau2D.setRenderingHint( pinceau2D.setRenderingHint(
RenderingHints.KEY_INTERPOLATION, RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR RenderingHints.VALUE_INTERPOLATION_BILINEAR
); );
pinceau2D.drawImage(image, x, y, drawWidth, drawHeight, this); pinceau2D.drawImage(image, x, y, drawWidth, drawHeight, this);
} }
} }
+15 -31
View File
@@ -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; package fr.iutfbleau.sae;
import java.io.BufferedReader; public class Viewer {
import java.io.FileReader; public static void main(String[] args) {
import java.io.IOException; // chemins de l'image
String inpuPath = null;
//teste avec ia if (args.length >= 1) {
private void chargerFichier() { inpuPath = args[0];
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");
} }
} catch (IOException e) {
JOptionPane.showMessageDialog(this,
"Erreur lors de l'ouverture du fichier",
"Erreur",
JOptionPane.ERROR_MESSAGE);
}
add(new JScrollPane(zoneTexte), BorderLayout.CENTER); ViewerWindow fen = new ViewerWindow();
setVisible(true); ViewerControleur controleur = new ViewerControleur(fen,inpuPath);
controleur.loadPIF();
}
} }
>>>>>>> 40f71dddd52fc07edc1d47d48d56fd65a2a79fe3
@@ -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;
}
}
+91
View File
@@ -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) {}
}
@@ -16,13 +16,7 @@ public class CanonicalCode{
List<Map.Entry<Integer, String>> liste = new ArrayList<>(codesHuffman.entrySet()); List<Map.Entry<Integer, String>> liste = new ArrayList<>(codesHuffman.entrySet());
// ici on comparer par longueur de la valeur ou sinon par la clé // ici on comparer par longueur de la valeur ou sinon par la clé
Collections.sort(liste, new ComparateurCanonique()); Collections.sort(liste, new ComparateurCanonique());
Map<Integer,String> canonicalCodes = new HashMap<>(); Map<Integer,String> canonicalCodes = new HashMap<>();
int code = 0; // code canonique à attribuer int code = 0; // code canonique à attribuer
int temp = 0; //garde la longueur du code précedent , pour gérer le décalage int temp = 0; //garde la longueur du code précedent , pour gérer le décalage
@@ -1,6 +1,6 @@
package fr.iutfbleau.sae.mhuffman; package fr.iutfbleau.sae.mhuffman;
import fr.iutfbleau.sae.mimage.Pixel; import fr.iutfbleau.sae.mpif.Pixel;
import fr.iutfbleau.sae.mimage.RGBImage; import fr.iutfbleau.sae.mpif.RGBImage;
/** /**
* Représente une table de fréquences pour une image RGB. * Représente une table de fréquences pour une image RGB.
@@ -33,13 +33,13 @@ import fr.iutfbleau.sae.mimage.RGBImage;
public class FrequencyTable { public class FrequencyTable {
/** Tableau des fréquences pour la composante rouge (valeurs de 0 à 255). */ /** 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). */ /** 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). */ /** 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. * Construit une table de fréquences vide.
@@ -4,7 +4,7 @@ import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
// test import fr.iutfbleau.sae.util.HuffmanNode;
/** /**
* Implémente un arbre de Huffman utilisé pour la compression de données. * 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 // 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<Integer, String> codes; private Map<Integer, String> 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. * Construit un arbre de Huffman.
+225 -43
View File
@@ -1,9 +1,14 @@
package fr.iutfbleau.sae.mpif; 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.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
@@ -15,73 +20,250 @@ public class PIFReader {
private int[] lenG; private int[] lenG;
private int[] lenB; private int[] lenB;
public RGBImage read(String filepath) /**
throws Exception { * Lit et décode un fichier PIF.
*
// j'Utilise d'un BufferedInputStream pour une meilleure performance * @param filepath chemin du fichier PIF
FileInputStream fis = new FileInputStream(filepath); * @return l'image RGB décodée
BufferedInputStream bis = new BufferedInputStream(fis); * @throws Exception si erreur de lecture
BitInputStream lecteur = new BitInputStream(bis); */
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.readHeader(lecteur);
this.readCanonicalTables(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<String, Integer> canonR = rebuildCanonical(lenR); Map<String, Integer> canonR = rebuildCanonical(lenR);
Map<String, Integer> canonG = rebuildCanonical(lenG); Map<String, Integer> canonG = rebuildCanonical(lenG);
Map<String, Integer> canonB = rebuildCanonical(lenB); Map<String, Integer> canonB = rebuildCanonical(lenB);
// Je construis les arbres de décodage
DecodeNode trieR = buildDecodageTree(canonR); DecodeNode trieR = buildDecodageTree(canonR);
DecodeNode trieG = buildDecodageTree(canonG); DecodeNode trieG = buildDecodageTree(canonG);
DecodeNode trieB = buildDecodageTree(canonB); DecodeNode trieB = buildDecodageTree(canonB);
// Je décode les pixels
RGBImage img = decodePixels(lecteur, trieR, trieG, trieB); RGBImage img = decodePixels(lecteur, trieR, trieG, trieB);
lecteur.closeFlux(); lecteur.closeFlux();
System.out.println("Fichier PIF lu avec succès : " + width + "x" + height);
return img; 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.width = in.readBits(16);
this.height = 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++){ 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<code, symbole> pour le décodage
*/
public Map<String, Integer> rebuildCanonical(int[] lengths) {
// je cree une liste de paires (symbole, longueur)
List<Map.Entry<Integer, Integer>> 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<String, Integer> codes = new HashMap<>();
int code = 0;
int previousLength = 0;
for (Map.Entry<Integer, Integer> 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<String (code binaire), symbole> 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<String,Integer> codes) {
DecodeNode root = new DecodeNode(); // la racine de larbre
for (Map.Entry<String, Integer> 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++){ return f.length() >= 772; // taille minimal pour un fichier pif longueur largeur et tables de frequance
lenB[k] = in.readBits(8);
}
}
public Map<String,Integer> rebuildCanonical(int[] lengths) {
// TODO: Implement canonical table reconstruction
return null;
} }
public RGBImage decodePixels(BitInputStream in, DecodeNode red, DecodeNode green, DecodeNode blue) {
// TODO: Implement pixel decoding
return null;
}
public DecodeNode buildDecodageTree(Map<String,Integer> codes) {
// TODO: Implement trie building
return null;
}
} }
+4 -33
View File
@@ -1,7 +1,5 @@
package fr.iutfbleau.sae.mpif; package fr.iutfbleau.sae.mpif;
import fr.iutfbleau.sae.mimage.RGBImage;
import fr.iutfbleau.sae.mimage.Pixel;
import fr.iutfbleau.sae.util.BitOutputStream; import fr.iutfbleau.sae.util.BitOutputStream;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@@ -31,17 +29,15 @@ public class PIFWriter {
encodePixels(ecriveur, image, canonR, canonG, canonB); encodePixels(ecriveur, image, canonR, canonG, canonB);
ecriveur.fermerFlux(); ecriveur.fermerFlux();
System.out.println("Fichier PIF écrit avec succès");
} }
// Ecriture de l'en-tête du fichier PIF (largeur et hauteur) // Ecriture de l'en-tête du fichier PIF (largeur et hauteur)
public void writeHeader(BitOutputStream out, int width, int height) { public void writeHeader(BitOutputStream out, int width, int height) {
try { try {
out.writeBits(width, 16); // ✅ Simplifié : 16 bits d'un coup out.writeBits(width, 16);
out.writeBits(height, 16); // ✅ Simplifié : 16 bits d'un coup out.writeBits(height, 16);
} catch (Exception e) { } catch (IOException e) {
System.err.println("Erreur lors de l'écriture de l'en-tête du fichier PIF"); 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) { } catch (IOException e) {
System.err.println("Erreur lors de l'écriture des tables de fréquences dans le fichier PIF"); 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 // Méthode pour encoder les pixels de l'image en utilisant les codes canoniques
@@ -1,38 +1,38 @@
package fr.iutfbleau.sae.mimage; package fr.iutfbleau.sae.mpif;
public class Pixel{ public class Pixel{
private int r; private int r;
private int g; private int g;
private int b; private int b;
//à completer //à completer
public Pixel(int red, int green, int blue){ public Pixel(int red, int green, int blue){
this.r=red; this.r=red;
this.g=green; this.g=green;
this.b=blue; this.b=blue;
} }
public int getB() { public int getB() {
return b; return b;
} }
public int getG() { public int getG() {
return g; return g;
} }
public int getR() { public int getR() {
return r; return r;
} }
public void setR(int r) { public void setR(int r) {
this.r = r; this.r = r;
} }
public void setB(int b) { public void setB(int b) {
this.b = b; this.b = b;
} }
public void setG(int g) { public void setG(int g) {
this.g = g; this.g = g;
} }
} }
@@ -1,30 +1,31 @@
package fr.iutfbleau.sae.mimage; package fr.iutfbleau.sae.mpif;
public class RGBImage { public class RGBImage {
private int width; private int width;
private int height; private int height;
private Pixel [][] pixels; private Pixel [][] pixels;
public RGBImage (int lar, int haut){ public RGBImage (int lar, int haut){
this.width=lar; this.width=lar;
this.height=haut; this.height=haut;
this.pixels = new Pixel[this.width][this.height]; this.pixels = new Pixel[this.width][this.height];
} }
public int getWidth() { public int getWidth() {
return width; return width;
} }
public int getHeight() { public int getHeight() {
return height; return height;
} }
public void setPixel(int x, int y, Pixel p) { public void setPixel(int x, int y, Pixel p) {
this.pixels[x][y] = p; this.pixels[x][y] = p;
} }
public Pixel getPixel(int x, int y) { public Pixel getPixel(int x, int y) {
return this.pixels[x][y]; return this.pixels[x][y];
} }
} }
-89
View File
@@ -1,89 +0,0 @@
package fr.iutfbleau.sae.util;
/**
* Classe utilitaire regroupant des opérations de conversion entre
* entiers et octets.
* <p>
* Elle est utilisée pour encoder et décoder les champs binaires
* du format PIF (largeur, hauteur, tailles, etc.).
* </p>
*
* <p>
* Cette classe :
* <ul>
* <li>ne lit aucun fichier</li>
* <li>n'écrit aucun fichier</li>
* <li>ne manipule pas les bits individuellement</li>
* </ul>
* Elle fournit uniquement des conversions octets ↔ entiers.
* </p>
*/
public final class ByteUtils {
/**
* Constructeur privé empêchant l'instanciation.
* <p>
* Cette classe est purement utilitaire et ne doit pas être instanciée.
* </p>
*/
private ByteUtils() {
// j'empêche l'instanciation
}
/**
* Convertit un entier non négatif en deux octets (ordre big-endian).
* <p>
* L'octet de poids fort est placé en première position,
* suivi de l'octet de poids faible.
* </p>
*
* @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).
* <p>
* L'octet de poids fort est replacé dans les bits 15 à 8,
* puis combiné avec l'octet de poids faible.
* </p>
*
* @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);
}
}
@@ -1,23 +1,23 @@
package fr.iutfbleau.sae.mpif; package fr.iutfbleau.sae.util;
public class DecodeNode { public class DecodeNode {
public DecodeNode left; public DecodeNode left;
public DecodeNode right; public DecodeNode right;
public Integer value; // null si pas une feuille public Integer value; // null si pas une feuille
public DecodeNode() { public DecodeNode() {
this.left = null; this.left = null;
this.right = null; this.right = null;
this.value = null; this.value = -1; // valeur non initialisée
} }
public DecodeNode(DecodeNode left, DecodeNode right, Integer value) { public DecodeNode(DecodeNode left, DecodeNode right, Integer value) {
this.left = left; this.left = left;
this.right = right; this.right = right;
this.value = value; this.value = value;
} }
public boolean isLeaf() { public boolean isLeaf() {
return this.left == null && this.right == null; return this.left == null && this.right == 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);
}
}
@@ -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);
}
}
@@ -1,4 +1,4 @@
package fr.iutfbleau.sae.mhuffman; package fr.iutfbleau.sae.util;
/** /**
* Représente un nœud de l'arbre de Huffman. * Représente un nœud de l'arbre de Huffman.
@@ -1,7 +0,0 @@
package fr.iutfbleau.sae.vviewer;
public class ImagePanel extends JPanel{
}
@@ -1,11 +0,0 @@
package fr.iutfbleau.sae.vviewer;
public class ViewerWindow extends JFrame{
}
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More