package uk.co.mmscomputing.imageio.jpeg; import java.io.*; public class JPEGDCTInputStream extends JPEGACInputStream{ protected JPEGDCInputStream dc; protected int levelshift,negclamp,posclamp; public JPEGDCTInputStream(JPEGHuffmanInputStream dc,JPEGHuffmanInputStream ac,int[] qt,int bps){ super(ac,qt); this.dc=new JPEGDCInputStream(dc); levelshift=1<<(bps-1);negclamp=-levelshift;posclamp= levelshift-1; } public void restart()throws IOException{ // Call at beginning of restart interval dc.restart(); super.restart(); } public int[] getBuffer(){return buffer;} protected void levelShift(){ int col; for(int i=0;i<DCTBlockSize;i++){ col=buffer[i]; if(col<negclamp){ col=negclamp; // clamp to -128 .. 127 or -2048 .. 2047 }else if(col>posclamp){ col=posclamp; } col+=levelshift; // level shift;[1] A.3.1; F.1.1.3 p.87 buffer[i]=col; } } public void fillBuffer()throws IOException{ buffer[0]=qt[0]*dc.read(); super.fillBuffer(); inverseDCT(buffer); levelShift(); count=0; } public int read()throws IOException{ if(count==DCTBlockSize){ fillBuffer(); } return buffer[count++]; } protected int matr1[]=new int[DCTBlockSize]; // temp buffer; used in JPEGFastDCTInputStream as well public void inverseDCT(int[] buffer)throws IOException{ // The text book DCT algorithm. double[] coeff={1.0/Math.sqrt(2.0),1,1,1,1,1,1,1}; double sum; for(int y=0;y<DCTSize;y++){ for(int x=0;x<DCTSize;x++){ sum = 0.0; for(int v=0;v<DCTSize;v++) { for(int u=0;u<DCTSize;u++) { sum+=coeff[u]*coeff[v]*buffer[v*DCTSize+u]*Math.cos(((2.0*x+1.0)/16.0)*u*Math.PI)*Math.cos(((2.0*y+1.0)/16.0)*v*Math.PI); } } sum/=4.0; matr1[y*DCTSize+x]=((int)Math.round(sum)); } } System.arraycopy(matr1,0,buffer,0,DCTBlockSize); } } // [1]'JPEG' : ISO/IEC IS 10918-1 // ITU-T Recommendation T.81 // http://www.w3.org/Graphics/JPEG/itu-t81.pdf