From f6f0eca79f733eb32802093296e80fdaab7f1372 Mon Sep 17 00:00:00 2001 From: AlgaLaptop Date: Mon, 29 Dec 2025 00:09:11 +0100 Subject: [PATCH] pif ok --- PlaningDeTavail.md | 7 +- makefile | 5 + src/fr/iutfbleau/sae/ConverterController.java | 17 ++- src/fr/iutfbleau/sae/Convertisseur.java | 32 ++--- src/fr/iutfbleau/sae/mpif/PIFWriter.java | 111 +++++++++++++++++- .../sae/vconverter/ConverterWindow.java | 3 +- 6 files changed, 149 insertions(+), 26 deletions(-) diff --git a/PlaningDeTavail.md b/PlaningDeTavail.md index dfaf499..9414f46 100644 --- a/PlaningDeTavail.md +++ b/PlaningDeTavail.md @@ -84,13 +84,12 @@ Objectif : Écriture du format `.pif` + finalisation convertisseur | US | Assigné | Statut | | Description | |------------|---------|--------|-----|-------------| | US-D2 | AA | DONE | 🟩 | Vérifier BitOutputStream avec flux réel | -| US-C5 | AD | DOING | 🟨 | Implémenter PIFWriter (header + tables + pixels compressés) | -| US-U6 | AD | DOING | 🟨 | Exporter une image en `.pif` | +| US-C5 | AD | DONE | 🟩 | Implémenter PIFWriter (header + tables + pixels compressés) | +| US-U6 | AD | DONE | 🟩 | Exporter une image en `.pif` | | US-P1 | AA | DONE | 🟩 | Finaliser affichage des fréquences | | US-P2 | AA | DONE | 🟩 | Finaliser affichage codes Huffman | | US-P3 | AA | DONE | 🟩 | Finaliser affichage codes canoniques | -| US-U7 | AD | DOING | 🟨 | Implémenter l’aperçu (PreviewPanel) | -| US-D3..D6 | YB | TODO | 🟥 | Lier interface convertisseur -> compression | +| US-U7 | AD | DONE | 🟩 | Implémenter l’aperçu (PreviewPanel) | ## Fichiers à créer – Sprint 2 diff --git a/makefile b/makefile index 44ef038..ba774ed 100644 --- a/makefile +++ b/makefile @@ -97,6 +97,11 @@ $(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class: $(BIN) \ # Compilation des classes mpif +$(BIN)/$(PKG_PATH)/mpif/PIFWriter.class: $(BIN) \ + $(BIN)/$(PKG_PATH)/mimage/RGBImage.class \ + $(SRC)/$(PKG_PATH)/util/BitOutputStream.class \ + $(SRC)/$(PKG_PATH)/mpif/PIFWriter.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mpif/PIFWriter.java # Compilation du controleur diff --git a/src/fr/iutfbleau/sae/ConverterController.java b/src/fr/iutfbleau/sae/ConverterController.java index 2229c20..9127580 100644 --- a/src/fr/iutfbleau/sae/ConverterController.java +++ b/src/fr/iutfbleau/sae/ConverterController.java @@ -4,6 +4,7 @@ import fr.iutfbleau.sae.mhuffman.FrequencyTable; import fr.iutfbleau.sae.mhuffman.HuffmanTree; import fr.iutfbleau.sae.mimage.Pixel; import fr.iutfbleau.sae.mimage.RGBImage; +import fr.iutfbleau.sae.mpif.PIFWriter; import fr.iutfbleau.sae.vconverter.ConverterWindow; import java.awt.image.BufferedImage; import java.io.File; @@ -134,8 +135,20 @@ public class ConverterController { } - public void saveAsPIF(String filepath) { - // À implémenter : sauvegarder l'image convertie au format PIF + 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."); + return; + } + + try { + 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); + } } public RGBImage getImage(){ diff --git a/src/fr/iutfbleau/sae/Convertisseur.java b/src/fr/iutfbleau/sae/Convertisseur.java index 6e048bd..a4193ef 100644 --- a/src/fr/iutfbleau/sae/Convertisseur.java +++ b/src/fr/iutfbleau/sae/Convertisseur.java @@ -1,12 +1,4 @@ package fr.iutfbleau.sae; -import java.util.HashMap; -import java.util.Map; -import fr.iutfbleau.sae.mhuffman.FrequencyTable; -import fr.iutfbleau.sae.mhuffman.HuffmanNode; -import fr.iutfbleau.sae.mhuffman.HuffmanTree; -import fr.iutfbleau.sae.mhuffman.CanonicalCode; -import fr.iutfbleau.sae.mimage.*; - import fr.iutfbleau.sae.vconverter.ConverterWindow; public class Convertisseur { public static void main(String[] args) { @@ -15,19 +7,27 @@ public class Convertisseur { // je la passe au controleur ConverterController controller = new ConverterController(window); - // chemin de l'image de test - String testIMG = "temp/test1.jpg"; - controller.loadImage(testIMG); // je charge l'image + // chemins de l'image + String inpuPath; + String outputPath; + if (args.length >= 1) { + inpuPath = args[0]; + } + if (args.length >= 2) { + outputPath = args[1]; + } - // Logique de conversion dans lordre + // je charge l'image + controller.loadImage(testIMG); + + // je place la logique de conversion dans lordre controller.computeFrequencies(); controller.computeHuffman(); controller.computeCanonical(); + if (condition) { + + } - - - - //System.out.println("DLKSLDKSLKDSLKSLKSLDKSLDKLSdkslkdl"); } } \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/mpif/PIFWriter.java b/src/fr/iutfbleau/sae/mpif/PIFWriter.java index 7c47a73..1deb45e 100644 --- a/src/fr/iutfbleau/sae/mpif/PIFWriter.java +++ b/src/fr/iutfbleau/sae/mpif/PIFWriter.java @@ -1,17 +1,124 @@ package fr.iutfbleau.sae.mpif; + +import fr.iutfbleau.sae.mimage.RGBImage; import fr.iutfbleau.sae.util.BitOutputStream; +import java.io.FileOutputStream; import java.util.Map; + public class PIFWriter { + // 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 >> 8 & 0xFF, 8); // octet de poids fort + out.writeBits(width & 0xFF, 8); // octet de poids faible + + out.writeBits(height >> 8 & 0xFF, 8); // octet de poids fort + out.writeBits(height & 0xFF, 8); // octet de poids faible + } catch (Exception e) { + System.err.println("Erreur lors de l’écriture de l’en-tête du fichier PIF"); + } } - public void writeTables(BitOutputStream out, Map canonicalCodes){ + public void writeTables(BitOutputStream out, Map canonR, + Map canonG, Map canonB){ + + try { + // Écriture des longueurs des codes canoniques pour chaque composante + for (int i = 0; i < 10; i++) { + int len; + if (canonR.containsKey(i)) { // petite securité (au cas où) + len = canonR.get(i).length(); + }else { + len = 0; + } + out.writeBits(len, 8); + + } + for (int i = 0; i < 10; i++) { + int len; + if (canonG.containsKey(i)) { + len = canonG.get(i).length(); + }else { + len = 0; + } + out.writeBits(len, 8); + } + for (int i = 0; i < 10; i++) { + int len; + if (canonB.containsKey(i)) { + len = canonB.get(i).length(); + }else { + len = 0; + } + out.writeBits(len, 8); + } + } catch (Exception e) { + System.err.println("Erreur lors de l’écriture des tables de fréquences dans le fichier PIF"); + } + } + + private void writeBitFromString(BitOutputStream out, String code){ + try { + for (int i = 0; i < code.length(); i++) { + if (code.charAt(i) == '1') { + out.writeBit(1); + } else { + out.writeBit(0); + } + } + } catch (Exception e) { + System.err.println("Erreur lors de l’écriture des bits dans le fichier PIF"); + } + } + + // Méthode pour encoder les pixels de l'image en utilisant les codes canoniques + public void encodePixels(BitOutputStream out, RGBImage image, Map canonRED, Map canonGREEN, Map canonBLUE){ + try { + int width = image.getWidth(); + int height = image.getHeight(); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + // Récupérer les valeurs R, G, B du pixel + int r = image.getPixel(x, y).getR(); + int g = image.getPixel(x, y).getG(); + int b = image.getPixel(x, y).getB(); + + // Écrire les codes dans le flux binaire + writeBitFromString(out, canonRED.get(r)); + writeBitFromString(out, canonGREEN.get(g)); + writeBitFromString(out, canonBLUE.get(b)); + + } + } + } catch (Exception e) { + System.err.println("Erreur lors de l’encodage des pixels dans le fichier PIF"); + } } - public void encodePixels(BitOutputStream out){ + public void writeTOFile(String filepath, RGBImage image, + Map canonR, + Map canonG, + Map canonB) + throws Exception { + // Création du flux de sortie binaire + FileOutputStream fos =new FileOutputStream(filepath); + BitOutputStream ecriveur =new BitOutputStream(fos); + + // Écriture de l'en-tête + writeHeader(ecriveur, image.getWidth(), image.getHeight()); + + // Écriture des tables de longueurs des codes canoniques + writeTables(ecriveur, canonR, canonG, canonB); + + // Ecriture des pixels + encodePixels(ecriveur, image, canonR, canonG, canonB); + + ecriveur.fermerFlux(); + + System.err.println("SYSTEME"); } } diff --git a/src/fr/iutfbleau/sae/vconverter/ConverterWindow.java b/src/fr/iutfbleau/sae/vconverter/ConverterWindow.java index 75e75f3..d16707c 100644 --- a/src/fr/iutfbleau/sae/vconverter/ConverterWindow.java +++ b/src/fr/iutfbleau/sae/vconverter/ConverterWindow.java @@ -1,9 +1,8 @@ package fr.iutfbleau.sae.vconverter; -import fr.iutfbleau.sae.util.Config; import java.awt.*; +import java.awt.image.BufferedImage; import java.util.Map; import javax.swing.*; -import java.awt.image.BufferedImage; /** * Fenêtre principale du convertisseur.