From 182cd2bd28ca59cd16daeac97621431a699241bc Mon Sep 17 00:00:00 2001
From: AlgaLaptop
Date: Sun, 4 Jan 2026 18:05:46 +0100
Subject: [PATCH] finir le sprint 3
---
.../sae/mhuffman/FrequencyTable.class | Bin 1002 -> 1135 bytes
.../iutfbleau/sae/mhuffman/HuffmanNode.class | Bin 1126 -> 2066 bytes
build/fr/iutfbleau/sae/mpif/PIFWriter.class | Bin 3732 -> 4427 bytes
.../iutfbleau/sae/util/BitOutputStream.class | Bin 1438 -> 1812 bytes
.../sae/mhuffman/FrequencyTable.java | 44 +++----
.../iutfbleau/sae/mhuffman/HuffmanNode.java | 54 ++++++--
.../iutfbleau/sae/mhuffman/HuffmanTree.java | 30 -----
src/fr/iutfbleau/sae/mpif/PIFReader.java | 13 +-
src/fr/iutfbleau/sae/mpif/PIFWriter.java | 116 ++++++++++--------
.../iutfbleau/sae/util/BitOutputStream.java | 24 ++++
10 files changed, 163 insertions(+), 118 deletions(-)
diff --git a/build/fr/iutfbleau/sae/mhuffman/FrequencyTable.class b/build/fr/iutfbleau/sae/mhuffman/FrequencyTable.class
index 980e373170bb6cd2e33fc597e99461f53da392b3..38006695022cb8cc5821e1425565b2686bdd8ac4 100644
GIT binary patch
delta 586
zcmaFG{+@&D)W2Q(7#J8_7;GnU&8TN*5Mg9c%1SIt)Xz!GOV{_z$w^I5%yBGAFU?KO
zD{-wzPAw?O%+KRs5MyMJ^HI;tO-xT!$V*iyNG&ZJ3>2Mg~R(1_oA;<2EobI5RMUtzrX<
rCNVHFSYlPnyMciLMQIiTBZC!0>E!*)Vxl1TLJTQpU}Ufc`@sePAA)Nh
delta 449
zcmaFQ@rs@6)W2Q(7#J8_7|bSe&EVx?5MdByXAt9I5ND8>EX!ynC&D1b!ywHd!N|aw
zo?7COnwg$a0#YT*!yv~XKe>?6m|KxSiJd{2he3rwV)A-MO-V%tH68|akQSEo)Dm|t
z21N!<9tJH2iOC-sA24c9zQkl$ufxE=AjZJTz`$U{z`|h6z{_C5AjV+IAkSdNz{sG>
zpvS<-pv}O*u#ka;frWvAA)MJ(Mtd8B@FE6(W;HLc{@>ri#JK$b`i%?>3``6l*C;V?FfcIqFmN&W
zGKetvF{m;4GgvSLFnBTeG6XRAFoZD#Gw3rgFbFWP{9#~X{KLS>_=~~$7XvE;BZC2h
zA;`Ux-!Y42gUn)MU}Rumh-P49FoMW1Ffhn6FoH!{L2lf@z`(!=wico^g@KX57^_kN
Pbfvirj0`4VSDOL=tL#M}
diff --git a/build/fr/iutfbleau/sae/mhuffman/HuffmanNode.class b/build/fr/iutfbleau/sae/mhuffman/HuffmanNode.class
index 460a57901bfc022ee4ab59a5898fe5071b118eb7..753c3ac112531638623737211513d55ae5ea11bd 100644
GIT binary patch
literal 2066
zcmX^0Z`VEs1_l>~AT9E#Rg~O{#ic%F)^FXA5LTZVEk*O&c13Lo`$Z}pr22l+kgvr4rMVWc&)|z1)
z4E&4?nm&mNX+?)u7M7;wC8sLnr79GpmX;_KBo;$W%{#m@J+UOSER~Z%kU@x@L70a@
zgh7;%K{c&NKeMzXEh#58u~fe}F;zb|qckloH!)A&148@dr=&76u$Cp}l%_H=FnWRv
z5a(f#0O{sTD@uh}2@;j!VUT8!VPs&*NlhzZWKj1Z%4}Q|bZlv)&$n3R*s$iN$1l9-(Bn^*wl
z2Wk)**hDJR3}a;ANlz_tgT*g6Ts;{X*wa%>e8ADGsi8@vVT=qM>8T|_pqPa)!ysvi
zqa+`aiWwP1G_ZseBLi1(erZv1s#_+=&jLsZQV$fjj0^%!`S~TqB}It^zNsY{`6%TFy$(SQo^voW}HF?cX|vNL#rV#S-0
zK?P(uB$H?6mE~ur>O-6fiDkFM1E%G{GzSAC
z11p0O10#bm0|P@J12Y3N0|SGN)^-L)>Ddfi(t-^CmoV_|W?+vL;@r-_yo+2F!(UAF!(a?F!(Wu
zF$6G3GXydyFa$BEG6XXiF@%7fBFw<_pMeML6m|wdb_PKP22KV>P0)F6g&RayDgz^fC4&_frIH&M7#NV1<}olbSYuTxi>|bsfsw%m?f`oRX0Qvzw6-xQ
z%>o6dTBMN1b_T8eT3Z+dKrUheyNC~*Dq0xW8Cn?x8QQ`AVP;?yWME{lWw3)f(Sv~r
zY?wUAu$c^kAR|B?+r^;Gz_0GN_ja4>MPGjQ=Ra5L~sd|@WX!NAAEz|X+L$iSIa
zlv-GtnwOjkQY6U3AjBX%*@n?rhl4?she3=%n2~|CC^J2ygo}ZLL4t=tl0k}*fi1Jx
zCp9sRk%3u5Gm4!-X7XW16-K$qFBnY}q!|==7+4t;85u-1e6kYD67_Qu^V0Q$ONuh{
z(ycYaCf6}3Pu|EB!p9q2l9-(Bn^+K%n3R(`nVC6xatE_qJ%b_x2LlrW0|N^K6Uem;
z3=B*lmx5^_24OHQ2Bz5=7#Ua@lo%Kplo=QpTp5@cm>C!tB(=6PFltF}WnkBm*~-AH
z#kiG007QsvWME)mWKdyXV31;9V_;y=V_;#>XW(QoVBljgWDsUBVvt}kt_Pc`3N_P(
zff;P34A@LL{*vi0*FjkC#m4Si5o`HqIfq|33k%5oFi9wpd
znSl`$XiyW)85kKD85kHuw6-t^9B1Iu+QJ}moPnKXIRgvx8U_Z2dM2<7*}#gt8PpgU
z7+4vYgd9M+)EP9OrpQ7~Vb$8gzzfm_@fSo_2m>R7CW96hr2-q^K>$%2%fQH>jiR&=
zO>)W2Q(7#J8_80K!|dd*=XK>zMvn16ivjh?X91PWr43-!kMGoy^g#xg>|5-#gSFjZ_*E2E*IOXS;
z6qghw7Wk%?WaOt5b1-x%c81xE408CDGBU71+|QuMAjiPOz`)1Az`)AD
z$iT|L#=yu>Gx*+U}ONfP>{i%fr+7(fuWv3
zih+%RfkBgjok5F%k3p9~kU^V4m_dg@nn91DnSp_Uoq;Kkoxz@yfssL#L5+clp@xBh
zX)gmS0}lfO<3?sPR#8?#MutTU7CNG=I~d${GWakt%w&*+@q(Bb4lsmmV~8+gTh747
zY{sT7$|k_EjlsHwm2vt1W0QAq3rN8==|YWwYnuFsTfH78EhWisvS&by3x^
z!T3n(*jhLlC0UTw$%?YW1&|c7w{S7Ga5FCdU$==tPn5M?l%qX=7ehP)!!`ypkO*75
zC?`lH87fk*C(7O~$^{ZifePt~a)@$@a_wSB1q(o8^$^2RhGPyUcwb3KATw9Vwln0zPU{P1DEy*g%iz?K@$+-Og{1y(z<^TIZsg47b>Z+g_
zjfbI`p$#4-ZVZA93=CxqYz*ZLJPcI~Vhq&`3JkRjTJ;Qd42BH#3>FLx4E7Ao41o+S
z3@Hq)4CM^f47ChZ49yH(3~dY@3>^%e3=P->;;qk4AVj76&C{|!wiO5409MH
E0i9U@qyPW_
delta 1443
zcmX@DG)0!{)W2Q(7#J8_7+N=Sy=G!gEh?J)gGrWyJvcHr#MRezvMFQL#cwszT1AhM9*~CKqLvloqAJ1SX$nmgII}aAjw3<6&@T@RE{0%+
zFdl|*21!N+ww%=c~NFbs#7LZE{uaAm65>`
zikU%jHLkUd4iHkvwp^S&2oS}k|K?vqFx1#)9Na!#!
z*i2UB(3^aMorg&?Y;!kTA+sZcB7+OnGU44e!M48jat3?dAo45ADQ3=#}_
z4AKmi3~~&v3=eBxD5{{?|hkEob1hV%fx?C*-(|!E7Vg^+pV)
z4E796V5ciFa4;}1XfW_GXfjALXfvoY=r9;D=rfoy=rWiy=rPzc7&0_4Ffgz)FqN`1
z*mE*4GN>}BF))GL#aPO~%)rjTz;J=tj8&9Xkda{#gN2SL>kbCzoeZ90Objy_Bw<{C
zCWZqH!P^)@Cr9zBNrB|S(z;O92e4W2DM=O#`8&L_^?E{4aL*iKILZ(K^-L6l
z7y|=?1p_yO6@w&$HG@8bErSt*J%bg41%m^F6N5K{3qvG>D?>hmJ3|qJCqos36GH=o
zH$yjrFT*SbKZcDA0SsFhf*AHNcrzSg2xBEvRFfcPtp3ARX
zAHfNYszwGTP~w6{RTl#j0}BHKg9)>ptj;!u&_xUiIF-IlLGgUI)fJ6Ly+VX&A`PF!yv*C%OJxL&!ET<&7jUupTeNU
zki?+Pkj!ArkP3F400Y|}1|~*HmR}64PV5X391M&MnhaWyxMFzEz{0@Gz`)S2vyDN-
zj7?`7gOnLNvl)jdhba3ZhH7RrPEk%#wnYrtI-;DS9NQSuwlQRxaUnSQX50u)ky$;D
zmbR`a7dWb6kyomvEy*IvjUmP=%7ZG_!pXS&|CAOE#^wK8K)DE#6wScy%Vc0<$YS7O
z$Yu~@$YD@m$YaoD$Y-!(C}41BC}xOaC}GHBC}n6eVaQ?VV8~|ZW2gpuUWkF^9|J!l
bBjXp3sQIKSBCx!WiVrBFy~>gV6bFl5Xed_OVrOv%uCk~E-A{)OJ`(Y%Sp{k
zFUeqJVAjy|1Sz-XVX$GaWn^GW&PXhBEMa6|(eTuC=3uaAWY7m$YJp~JN`7XELUMjy
zNornZkwRfxK94dWXb3@*_>IO(S33}vkar_7#JB885kKn8N3*n7+fd2u;|*kF)%QQF|aZ)FoZF1FoZMkGej_mGK4Wm
zGej|f^m8&W{b68X{KX)KVuT?B8`y~TES`*RlYg?P*Mk(ZFfa+qp{Vm_;038;U|?9x
zz|6qHz`)?GeVl=JHv@a5kkNJq?)}WRGTPf1OcpViYRhb6u(FdCFj&CAt;M{JL1#IG
zw5)(3h{povL3G)HbhR)sF8_aWBLf2i69dQxdJOg43=9kv3@i+l415eV3=#~r3~~&0
z3@Qxu3_1)A3`Pu%3|0)y3@!{c3|=Tqeg<}i2@Ko}
a6B&dUCNYRJOaWWS%)ls)VuLT(1AYK^B!e9Q
delta 295
zcmbQjH;zk%5)L
zjDeBCeDV%vOGb;ypP1DdEhkH{$S|5uHfJehw3xh-#a!N!fq{XIfkjwASdGDofq{XA
zfssLxfsw(Q!G?i}!F=+67F|Y*$-1o4N+6Y-3`~C*SQvjXh@mJpWMBg;&SLdsw3xhw
zRlN?Rn1z8!P!2_%Ekqpy1A`|669Xdy1A~Ot76$2A48mI57>u;GFz{_-FxFz(${@Xw
xfq{XE!GeK-L5zWwfq|i%ft{g(ft#U{L5QJ>L7bt60b~O+1EV;K1$JO<_5fSRDUtvH
diff --git a/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java b/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java
index e290162..9768aa2 100644
--- a/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java
+++ b/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java
@@ -1,4 +1,5 @@
package fr.iutfbleau.sae.mhuffman;
+import fr.iutfbleau.sae.mimage.Pixel;
import fr.iutfbleau.sae.mimage.RGBImage;
/**
@@ -26,7 +27,7 @@ import fr.iutfbleau.sae.mimage.RGBImage;
*
*
* @author Algassimou Pellel Diallo
- * @version 1.0
+ * @version 1.1
* @since 2025-12-13
*/
public class FrequencyTable {
@@ -62,22 +63,28 @@ public class FrequencyTable {
*
*
* @param img l'image RGB à analyser
+ * @throws IllegalArgumentException si l'image est null
*/
public void computeFromImage(RGBImage img) {
- /*Nb: une composante de couleur est un entier entre 0 et 255 qui représente la part de rouge,vert ou bleu
- dans la couleur d'un pixel.
- */
- /* pour chaque composante de couleur de chaque pixel, on incrémente la fréquence correspondante,
- c'est-à-dire on compte le nombre de fois que la composante apparaît dans l'image.
- ex: si un pixel P a une composante rouge de 150, on incrémente freqR[150] de 1.
- puis on fait de même pour les composantes verte et bleue.
- on répète ce processus pour tous les pixels de l'image.
- */
- for (int ligne = 0; ligne < img.getWidth(); ligne++) {
- for (int colonne = 0; colonne < img.getHeight(); colonne++) {
- this.freqR[img.getPixel(ligne, colonne).getR()]++; // Incrémente la fréquence de la composante rouge
- this.freqG[img.getPixel(ligne, colonne).getG()]++; // Incrémente la fréquence de la composante verte
- this.freqB[img.getPixel(ligne, colonne).getB()]++; // Incrémente la fréquence de la composante bleue
+ if (img == null) {
+ throw new IllegalArgumentException("L'image ne peut pas être null");
+ }
+
+ /* Pour chaque composante de couleur de chaque pixel, on incrémente la fréquence correspondante,
+ * c'est-à-dire on compte le nombre de fois que la composante apparaît dans l'image.
+ * Ex: si un pixel P a une composante rouge de 150, on incrémente freqR[150] de 1.
+ * Puis on fait de même pour les composantes verte et bleue.
+ * On répète ce processus pour tous les pixels de l'image.
+ */
+ for (int x = 0; x < img.getWidth(); x++) {
+ for (int y = 0; y < img.getHeight(); y++) {
+ // On récupère le pixel une seule fois pour optimiser
+ Pixel pixel = img.getPixel(x, y);
+
+ // Puis on incrémente les trois fréquences
+ this.freqR[pixel.getR()]++;
+ this.freqG[pixel.getG()]++;
+ this.freqB[pixel.getB()]++;
}
}
}
@@ -93,7 +100,6 @@ public class FrequencyTable {
/**
* Retourne le tableau des fréquences de la composante verte.
- *
* @return un tableau de 256 entiers représentant les fréquences du vert
*/
public int[] getGreen() {
@@ -108,8 +114,4 @@ public class FrequencyTable {
public int[] getBlue() {
return this.freqB;
}
-}
-
-
-
-
+}
\ No newline at end of file
diff --git a/src/fr/iutfbleau/sae/mhuffman/HuffmanNode.java b/src/fr/iutfbleau/sae/mhuffman/HuffmanNode.java
index 8c46124..e3dcefb 100644
--- a/src/fr/iutfbleau/sae/mhuffman/HuffmanNode.java
+++ b/src/fr/iutfbleau/sae/mhuffman/HuffmanNode.java
@@ -21,10 +21,14 @@ package fr.iutfbleau.sae.mhuffman;
*/
public class HuffmanNode {
- /** Valeur de la composante (cette valeur est appelée symbole, voir l'histoire de huffman, tres interressant) représentée par ce nœud (si feuille). c'est la part de la composante (rouge, verte ou bleue) dans la couleur d'un pixel. */
+ /**
+ * Valeur de la composante (symbole) représentée par ce nœud (uniquement pour les feuilles).
+ * Représente la part de la composante (rouge, verte ou bleue) dans la couleur d'un pixel.
+ * Pour les nœuds internes, cette valeur vaut -1.
+ */
private int value;
- /** Fréquence du symbole (somme des fréquences des enfants). */
+ /** Fréquence du symbole (somme des fréquences des enfants pour les nœuds internes). */
private int frequence;
/** Fils gauche du nœud (null si feuille). */
@@ -40,10 +44,18 @@ public class HuffmanNode {
* issue de la table de fréquences.
*
*
- * @param value la valeur (symbole) représentée par ce nœud
+ * @param value la valeur (symbole) représentée par ce nœud (entre 0 et 255)
* @param frequence la fréquence d'apparition de la valeur
+ * @throws IllegalArgumentException si la valeur n'est pas entre 0 et 255
+ * ou si la fréquence est négative
*/
public HuffmanNode(int value, int frequence) {
+ if (value < 0 || value > 255) {
+ throw new IllegalArgumentException("La valeur doit être entre 0 et 255");
+ }
+ if (frequence < 0) {
+ throw new IllegalArgumentException("La fréquence ne peut pas être négative");
+ }
this.value = value;
this.frequence = frequence;
this.left = null;
@@ -59,8 +71,13 @@ public class HuffmanNode {
*
* @param left le fils gauche
* @param right le fils droit
+ * @throws IllegalArgumentException si l'un des fils est null
*/
public HuffmanNode(HuffmanNode left, HuffmanNode right) {
+ if (left == null || right == null) {
+ throw new IllegalArgumentException("Les fils ne peuvent pas être null");
+ }
+ this.value = -1; // Valeur sentinelle pour les nœuds internes
this.left = left;
this.right = right;
this.frequence = left.frequence + right.frequence;
@@ -87,7 +104,7 @@ public class HuffmanNode {
/**
* Retourne le fils gauche du nœud.
*
- * @return le fils gauche
+ * @return le fils gauche, ou null si le nœud est une feuille
*/
public HuffmanNode getLeft() {
return this.left;
@@ -96,7 +113,7 @@ public class HuffmanNode {
/**
* Retourne le fils droit du nœud.
*
- * @return le fils droit
+ * @return le fils droit, ou null si le nœud est une feuille
*/
public HuffmanNode getRight() {
return this.right;
@@ -108,12 +125,29 @@ public class HuffmanNode {
* Cette méthode n'a de sens que si le nœud est une feuille.
*
*
- * @return la valeur du symbole
+ * @return la valeur du symbole (entre 0 et 255)
+ * @throws IllegalStateException si le nœud n'est pas une feuille
*/
public int getValue() {
- if (!this.isLeaf()) {
- throw new IllegalStateException("La valeur n'est définie que pour les feuilles.");
- }
+ if (!this.isLeaf()) {
+ throw new IllegalStateException("La valeur n'est définie que pour les feuilles.");
+ }
return this.value;
}
-}
+
+ /**
+ * Retourne une représentation textuelle du nœud.
+ *
+ * Utile pour le débogage et l'affichage de l'arbre.
+ *
+ *
+ * @return une chaîne décrivant le nœud
+ */
+ @Override
+ public String toString() {
+ if (this.isLeaf()) {
+ return "Feuille(valeur=" + this.value + ", freq=" + this.frequence + ")";
+ }
+ return "Noeud(freq=" + this.frequence + ")";
+ }
+}
\ No newline at end of file
diff --git a/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java b/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java
index d87c0b3..2d3482f 100644
--- a/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java
+++ b/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java
@@ -167,36 +167,6 @@ public class HuffmanTree {
generateCodesRec(node.getLeft(), prefiixe + "0");
// On va a droite en ajoutant "1" au code
generateCodesRec(node.getRight(), prefiixe + "1");
-
-
- // this.codes = new HashMap<>();
- // this.chaineCarac = new String();
-
- // if(root.isLeaf()){
- // codes.put(root.getValue(),Integer.parseInt(chaineCarac));
- // return codes;
- // }
-
- // HuffmanNode temp = root;
-
- // if (root.getLeft() != null) {
- // root = root.getLeft();
- // chaineCarac = chaineCarac + "0";
- // generateCodes();
- // // on retire le dernier bit lorsqu'on remonte car sinon les codes seront faussés
- // chaineCarac = chaineCarac.substring(0, chaineCarac.length() - 1);
- // }
-
- // if (temp.getRight() != null) {
- // root = temp.getRight();
- // chaineCarac = chaineCarac + "1";
- // generateCodes();
- // chaineCarac = chaineCarac.substring(0, chaineCarac.length() - 1);
- // }
-
-
- // root = temp;
- // return codes;
}
/**
diff --git a/src/fr/iutfbleau/sae/mpif/PIFReader.java b/src/fr/iutfbleau/sae/mpif/PIFReader.java
index 80b3c2e..1bfbeab 100644
--- a/src/fr/iutfbleau/sae/mpif/PIFReader.java
+++ b/src/fr/iutfbleau/sae/mpif/PIFReader.java
@@ -1,13 +1,11 @@
package fr.iutfbleau.sae.mpif;
-
+import fr.iutfbleau.sae.mimage.RGBImage;
import fr.iutfbleau.sae.util.BitInputStream;
-import fr.iutfbleau.sae.util.BitOutputStream;
+import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.util.Map;
-import fr.iutfbleau.sae.mimage.RGBImage;
-
public class PIFReader {
@@ -19,8 +17,11 @@ public class PIFReader {
public RGBImage read(String filepath)
throws Exception {
+
+ // j'Utilise d'un BufferedInputStream pour une meilleure performance
FileInputStream fis = new FileInputStream(filepath);
- BitInputStream lecteur = new BitInputStream(fis);
+ BufferedInputStream bis = new BufferedInputStream(fis);
+ BitInputStream lecteur = new BitInputStream(bis);
// je lis l'entête et les tables canoniques
this.readHeader(lecteur);
@@ -42,7 +43,7 @@ public class PIFReader {
}
public void readHeader(BitInputStream in) {
- // TODO: Implement header reading
+
}
public void readCanonicalTables(BitInputStream in) {
diff --git a/src/fr/iutfbleau/sae/mpif/PIFWriter.java b/src/fr/iutfbleau/sae/mpif/PIFWriter.java
index a941a18..199ac17 100644
--- a/src/fr/iutfbleau/sae/mpif/PIFWriter.java
+++ b/src/fr/iutfbleau/sae/mpif/PIFWriter.java
@@ -1,6 +1,7 @@
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;
@@ -16,9 +17,9 @@ public class PIFWriter {
throws Exception {
// Création du flux de sortie binaire
- FileOutputStream fos =new FileOutputStream(filepath);
- BufferedOutputStream bos =new BufferedOutputStream(fos);
- BitOutputStream ecriveur =new BitOutputStream(bos);
+ 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());
@@ -31,96 +32,109 @@ public class PIFWriter {
ecriveur.fermerFlux();
- System.err.println("SYSTEME");
+ 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){
+ 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
+ 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");
+ System.err.println("Erreur lors de l'écriture de l'en-tête du fichier PIF");
}
-
}
public void writeTables(BitOutputStream out, Map canonR,
- Map canonG, Map canonB){
+ Map canonG, Map canonB) {
try {
// Écriture des longueurs des codes canoniques pour chaque composante
for (int i = 0; i < 256; i++) {
int len;
- if (canonR.containsKey(i)) { // petite securité (au cas où)
+ if (canonR.containsKey(i)) {
len = canonR.get(i).length();
- }else {
+ } else {
len = 0;
}
- out.writeBits(len, 8);
-
+ out.writeBits(len, 8);
}
+
for (int i = 0; i < 256; i++) {
int len;
if (canonG.containsKey(i)) {
len = canonG.get(i).length();
- }else {
+ } else {
len = 0;
}
- out.writeBits(len, 8);
+ out.writeBits(len, 8);
}
+
for (int i = 0; i < 256; i++) {
int len;
if (canonB.containsKey(i)) {
len = canonB.get(i).length();
- }else {
+ } else {
len = 0;
}
out.writeBits(len, 8);
}
} 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");
}
- }
- 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);
- }
+
+ // 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++;
}
- } catch (IOException e) {
- System.err.println("Erreur lors de l’écriture des bits dans le fichier PIF");
}
+
+ 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
- public void encodePixels(BitOutputStream out, RGBImage image, Map canonRED, Map canonGREEN, Map canonBLUE){
+ public void encodePixels(BitOutputStream out, RGBImage image,
+ Map canonRED,
+ Map canonGREEN,
+ Map canonBLUE) {
+
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));
-
- }
- }
-
- }
+ try {
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ // Récupérer le pixel une seule fois pour optimiser
+ Pixel pixel = image.getPixel(x, y);
+ int r = pixel.getR();
+ int g = pixel.getG();
+ int b = pixel.getB();
-
-}
+ // OPTIMISATION : Utiliser writeBitString() directement
+ out.writeBitString(canonRED.get(r));
+ out.writeBitString(canonGREEN.get(g));
+ out.writeBitString(canonBLUE.get(b));
+ }
+ }
+ } catch (IOException e) {
+ System.err.println("Erreur lors de l'écriture des pixels dans le fichier PIF");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/fr/iutfbleau/sae/util/BitOutputStream.java b/src/fr/iutfbleau/sae/util/BitOutputStream.java
index 1ebc34d..075b454 100644
--- a/src/fr/iutfbleau/sae/util/BitOutputStream.java
+++ b/src/fr/iutfbleau/sae/util/BitOutputStream.java
@@ -109,6 +109,30 @@ public class BitOutputStream {
this.fluxSortie.flush(); // Force l'écriture dans le flux sous-jacent dans le but de vider le buffer
}
+ /**
+ * Écrit une séquence de bits à partir d'une chaîne de '0' et '1'.
+ *
+ * @param codeBinaire chaîne contenant uniquement '0' et '1'
+ * @throws IOException si une erreur d'écriture survient
+ * @throws IllegalArgumentException si la chaîne contient autre chose que '0' ou '1'
+ */
+ public void writeBitString(String codeBinaire) throws IOException {
+ if (codeBinaire == null) {
+ throw new IllegalArgumentException("Le code binaire ne peut pas être null");
+ }
+
+ for (int i = 0; i < codeBinaire.length(); i++) {
+ char c = codeBinaire.charAt(i);
+ if (c == '0') {
+ writeBit(0);
+ } else if (c == '1') {
+ writeBit(1);
+ } else {
+ throw new IllegalArgumentException("Le code binaire ne doit contenir que '0' et '1'");
+ }
+ }
+ }
+
/**
* Vide les buffers internes et ferme le flux de sortie.
*