117 lines
3.2 KiB
Java
117 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();
|
|
}
|
|
|
|
|
|
|
|
}
|