Files
SAE32_2025/src/fr/iutfbleau/sae/util/BitinputStream.java
T

116 lines
3.2 KiB
Java

package fr.iutfbleau.sae.util;
import java.io.IOException;
import java.io.InputStream;
/**
* Décorateur de flux permettant la lecture binaire à granularité du bit.
* <p>
* Cette classe encapsule un {@link InputStream} existant et fournit
* des opérations de lecture bit par bit ou par groupes de bits.
* Elle ne gère ni l'ouverture ni la sélection du fichier source.
* </p>
*
* <p>
* Utilisée notamment pour le décodage des fichiers compressés
* (ex : format PIF utilisant des codes de Huffman).
* </p>
*
*
*
* @author Algassimou Pellel Diallo
* @version 1.0
* @since 2025-12-13
*/
public class BitinputStream {
/** Flux d'entrée sous-jacent */
private final InputStream fluxEntree;
/** Octet actuellement chargé depuis le flux */
private int octetCourant;
/** Position du bit courant dans l'octet (du bit 7 au bit 0) */
private int positionBit;
/** Indique si la fin du flux a été atteinte */
private boolean finDeFlux;
/**
* Construit un lecteur binaire à partir d'un flux existant.
*
* @param fluxEntree flux d'entrée à décorer
* @throws IllegalArgumentException si le flux est nul
*/
public BitinputStream(InputStream fluxEntree) {
if (fluxEntree == null) {
throw new IllegalArgumentException("Le flux d'entrée ne peut pas être nul");
}
this.fluxEntree = fluxEntree;
this.octetCourant = 0;
this.positionBit = -1; // force la lecture d'un nouvel octet
this.finDeFlux = false;
}
/**
* Lit un bit depuis le flux binaire.
*
* @return 0 ou 1 si un bit est lu, -1 si la fin du flux est atteinte
* @throws IOException si une erreur de lecture survient
*/
public int readBit() throws IOException {
if (finDeFlux) {
return -1;
}
if (this.positionBit < 0) {
int octetLu = this.fluxEntree.read();
if (octetLu == -1) {
this.finDeFlux = true;
} else {
this.octetCourant = octetLu;
this.positionBit = 7;
}
}
if (finDeFlux) {
return -1;
}
int bit = (this.octetCourant >> this.positionBit) & 1;
this.positionBit--;
return bit;
}
/**
* Lit une séquence de bits consécutifs et les assemble dans un entier.
*
* @param nombreBits nombre de bits à lire (strictement positif)
* @return valeur entière correspondant aux bits lus,
* ou -1 si la fin du flux est atteinte prématurément
* @throws IOException si une erreur de lecture survient
*/
public int readBits(int nombreBits) throws IOException {
int res=0;
for (int i = 0; i < nombreBits; i++) {
int bit = readBit();
if (bit == -1) {
return -1;
}
res = (res << 1) | bit;
}
return res;
}
/**
* Ferme le flux d'entrée sous-jacent.
*
* @throws IOException si une erreur survient lors de la fermeture
*/
public void closeFlux() throws IOException {
this.fluxEntree.close();
}
}