This commit is contained in:
AlgaLaptop
2026-01-02 20:52:44 +01:00
parent 2e0f44d28d
commit bceb70c052
31 changed files with 197 additions and 341 deletions
@@ -45,6 +45,8 @@ public class ConverterController {
this.fen = fen;
this.outputPath = out;
this.inputPath = in;
System.out.println(this.inputPath+" ==> "+this.outputPath);
}
@@ -166,7 +168,9 @@ public class ConverterController {
chooser.setDialogTitle("Enregistrer le fichier .pif");
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é
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());
}
@@ -175,7 +179,6 @@ public class ConverterController {
} catch (Exception ex) {
System.out.println("Erreur lors de la sauvegarde : " + ex.getMessage());
ex.printStackTrace();
}
}
@@ -193,6 +196,7 @@ public class ConverterController {
this.loadImage(choosser.getSelectedFile());
}else {
System.err.println("Aucune image choisie. Arrêt du programme.");
System.exit(1);
return;
}
}
@@ -1,16 +1,17 @@
package fr.iutfbleau.sae;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.SwingUtilities;
public class ExportButtonListener implements ActionListener {
private ConverterController controller;
private PIFSaveTask saveTask;
public ExportButtonListener(ConverterController controller){
this.controller = controller;
this.saveTask = new PIFSaveTask(controller);
}
@Override
public void actionPerformed(ActionEvent e){
controller.saveViaBtn();
SwingUtilities.invokeLater(saveTask);
}
}
+13
View File
@@ -0,0 +1,13 @@
package fr.iutfbleau.sae;
public class PIFSaveTask implements Runnable{
private ConverterController controller;
public PIFSaveTask(ConverterController c) {
this.controller = c;
}
@Override
public void run() {
controller.saveViaBtn();
}
}
+23
View File
@@ -0,0 +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;
}
}
+70
View File
@@ -0,0 +1,70 @@
package fr.iutfbleau.sae.mpif;
import fr.iutfbleau.sae.util.BitInputStream;
import fr.iutfbleau.sae.util.BitOutputStream;
import java.io.FileInputStream;
import java.util.Map;
import fr.iutfbleau.sae.mimage.RGBImage;
public class PIFReader {
private int width;
private int height;
private int[] lenR;
private int[] lenG;
private int[] lenB;
public RGBImage read(String filepath)
throws Exception {
FileInputStream fis = new FileInputStream(filepath);
BitInputStream lecteur = new BitInputStream(fis);
// je lis l'entê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
Map<String, Integer> canonR = rebuildCanonical(lenR);
Map<String, Integer> canonG = rebuildCanonical(lenG);
Map<String, Integer> canonB = rebuildCanonical(lenB);
DecodeNode trieR = buildDecodageTree(canonR);
DecodeNode trieG = buildDecodageTree(canonG);
DecodeNode trieB = buildDecodageTree(canonB);
RGBImage img = decodePixels(lecteur, trieR, trieG, trieB);
lecteur.closeFlux();
return img;
}
public void readHeader(BitInputStream in) {
// TODO: Implement header reading
}
public void readCanonicalTables(BitInputStream in) {
// TODO: Implement canonical table reading
}
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;
}
}
+46 -44
View File
@@ -2,11 +2,38 @@ package fr.iutfbleau.sae.mpif;
import fr.iutfbleau.sae.mimage.RGBImage;
import fr.iutfbleau.sae.util.BitOutputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
public class PIFWriter {
public void writeTOFile(String filepath, RGBImage image,
Map<Integer,String> canonR,
Map<Integer,String> canonG,
Map<Integer,String> canonB)
throws Exception {
// Création du flux de sortie binaire
FileOutputStream fos =new FileOutputStream(filepath);
BufferedOutputStream bos =new BufferedOutputStream(fos);
BitOutputStream ecriveur =new BitOutputStream(bos);
// É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");
}
// Ecriture de l'en-tête du fichier PIF (largeur et hauteur)
public void writeHeader(BitOutputStream out,int width, int height){
try {
@@ -26,7 +53,7 @@ public class PIFWriter {
try {
// Écriture des longueurs des codes canoniques pour chaque composante
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 256; i++) {
int len;
if (canonR.containsKey(i)) { // petite securité (au cas où)
len = canonR.get(i).length();
@@ -36,7 +63,7 @@ public class PIFWriter {
out.writeBits(len, 8);
}
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 256; i++) {
int len;
if (canonG.containsKey(i)) {
len = canonG.get(i).length();
@@ -45,7 +72,7 @@ public class PIFWriter {
}
out.writeBits(len, 8);
}
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 256; i++) {
int len;
if (canonB.containsKey(i)) {
len = canonB.get(i).length();
@@ -54,7 +81,7 @@ public class PIFWriter {
}
out.writeBits(len, 8);
}
} catch (Exception e) {
} catch (IOException e) {
System.err.println("Erreur lors de l’écriture des tables de fréquences dans le fichier PIF");
}
}
@@ -68,57 +95,32 @@ public class PIFWriter {
out.writeBit(0);
}
}
} catch (Exception e) {
} catch (IOException 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<Integer, String> canonRED, Map<Integer, String> canonGREEN, Map<Integer, String> 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();
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));
// É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 lencodage des pixels dans le fichier PIF");
}
}
public void writeTOFile(String filepath, RGBImage image,
Map<Integer,String> canonR,
Map<Integer,String> canonG,
Map<Integer,String> 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");
}
}
@@ -1,5 +1,4 @@
package fr.iutfbleau.sae.util;
import fr.iutfbleau.sae.util.BitOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -99,9 +98,14 @@ public class BitOutputStream {
if (fluxFerme) {
throw new IOException("Le flux de sortie est fermé");
}
while (this.positionBit >= 0) {
writeBit(0);
// Si l'octet nes pas vide on le complete avec des 0
if(this.positionBit < 7){
this.fluxSortie.write(this.octetEnConstruction);
this.octetEnConstruction = 0;
this.positionBit = 7;
}
this.fluxSortie.flush(); // Force l'écriture dans le flux sous-jacent dans le but de vider le buffer
}
@@ -21,7 +21,7 @@ import java.io.InputStream;
* @version 1.0
* @since 2025-12-13
*/
public class BitinputStream {
public class BitInputStream {
/** Flux d'entrée sous-jacent */
private final InputStream fluxEntree;
@@ -41,7 +41,7 @@ public class BitinputStream {
* @param fluxEntree flux d'entrée à décorer
* @throws IllegalArgumentException si le flux est nul
*/
public BitinputStream(InputStream fluxEntree) {
public BitInputStream(InputStream fluxEntree) {
if (fluxEntree == null) {
throw new IllegalArgumentException("Le flux d'entrée ne peut pas être nul");
}