package uk.co.mmscomputing.io; import java.io.*; public class RLEInputStream extends FilterInputStream{ private int rlen; // the run length private int ccwi; // the current code word private int[] c=new int[2]; // code words private int bpcw; // bytes per code word private int cwi; // code word index private byte[][] ccw=new byte[2][4]; // code word buffer public RLEInputStream(InputStream in)throws IOException{ this(in,1); } public RLEInputStream(InputStream in, int bytesPerCodeWord){ super(in); setCodeWords(0x00FFFFFF,0x00000000); // white and black bpcw=bytesPerCodeWord; resetToStartCodeWord(); } public void setCodeWords(int c1,int c2){ // Assume c1 and c2 are not -1 if(c1==-1){c1--;} // need -1 for eos signal if(c2==-1){c2--;} // need -1 for eos signal c[0]=c1; ccw[0][0]=(byte)( c1 &0x000000FF); ccw[0][1]=(byte)((c1>> 8)&0x000000FF); ccw[0][2]=(byte)((c1>>16)&0x000000FF); ccw[0][3]=(byte)((c1>>24)&0x000000FF); c[1]=c2; ccw[1][0]=(byte)( c2 &0x000000FF); ccw[1][1]=(byte)((c2>> 8)&0x000000FF); ccw[1][2]=(byte)((c2>>16)&0x000000FF); ccw[1][3]=(byte)((c2>>24)&0x000000FF); } public void resetToStartCodeWord(){ccwi=-1;cwi=0;rlen=0;} public int read()throws IOException{ while(rlen==0){ rlen=in.read(); // can be 32 bit number if(rlen==-1){return -1;} // end of stream ccwi=(ccwi+1)&0x01; // change current code word } rlen--; return c[ccwi]; } private int pread()throws IOException{ while(rlen==0){ rlen=in.read(); // can be 32 bit number if(rlen==-1){return -1;} // end of stream ccwi=(ccwi+1)&0x01; // change current code word } int b=ccw[ccwi][cwi]; cwi++;if(cwi==bpcw){cwi=0;rlen--;} return b&0x00FF; } public int read(byte[] b,int off,int len)throws IOException{ if(b==null){ throw new NullPointerException(getClass().getName()+".read(byte[] b, int off, int len): b is null"); } if((off<0)||(len<0)||(b.length<(off+len))){ throw new IndexOutOfBoundsException(getClass().getName()+".read(byte[] b, int off, int len): index off or len out of bounds."); } int i=0; while(i<len){ int v=pread(); if(v==-1){return (i==0)?-1:i;} b[off+i]=(byte)v; i++; } return len; } public static void main(String[] argv){ try{ byte[] buf={2,4,9}; ByteArrayInputStream bais=new ByteArrayInputStream(buf); RLEInputStream rlis=new RLEInputStream(bais,3); rlis.setCodeWords(0x00CCBBAA,0x00332211); /* int b,i=0; while((b=rlis.read())!=-1){ System.out.println("["+i+"]="+Integer.toHexString(b));i++; } */ buf=new byte[50]; int len=rlis.read(buf); for(int i=0;i<len;i++){ System.out.println("["+i+"]="+Integer.toHexString(buf[i])); } }catch(Exception e){ e.printStackTrace(); } } }