US-D1 et US-D2
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
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>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user