package uk.co.mmscomputing.imageio.gif;
import java.io.*;
public class GIFBitInputStream extends InputStream{
private int buf;
private int bitsAvail;
protected boolean eof=false;
protected int count,max;
protected byte[] data=new byte[255];
protected InputStream in;
public GIFBitInputStream(InputStream in){
this.in=in;
}
public int read()throws IOException{
if(count==max){
max=in.read(); // read length of chunk
if(max==0){return -1;} // empty chunk, no data anymore
if((max<0)||(255<max)){throw new IOException(getClass().getName()+".read:\n\tGIF data chunk length out of bounds ["+max+"]");}
int len=in.read(data,0,max); // read chunk max 255 bytes
if(len!=max){throw new IOException(getClass().getName()+".read:\n\tGIF data chunk missing.");}
count=0;
}
return data[count++]&0x00FF;
}
public int readBits(int bitcount)throws IOException{ // read "count" bit
if(eof && (bitsAvail==0)){return -1;}
needBits(bitcount);
int bits=getBits(bitcount);
clrBits(bitcount);
return bits;
}
protected void needBits(int bitcount)throws IOException{
// Assert(bitcount<32);
while((eof==false)&&(bitsAvail < bitcount)){
int b=this.read();
if(b==-1){eof=true; break;}
buf |= (b<<bitsAvail);
bitsAvail += 8;
}
}
protected void clrBits(int bitcount){
bitsAvail -= bitcount;
buf >>= bitcount;
}
protected int getBits(int bitcount){
return ((int)buf & ((1<<bitcount)-1)); // mask lower x bits out
}
}