package uk.co.mmscomputing.imageio.jpeg; import java.io.*; public class JPEGDCTOutputStream extends OutputStream implements JPEGConstants{ static private final int levelshift=128; protected int count; protected float[] buffer=new float[DCTBlockSize]; protected int[] qt; protected OutputStream dc; protected OutputStream ac; public JPEGDCTOutputStream(int[] qt)throws IOException{ this.qt=qt;this.dc=null;this.ac=null;count=0; } public void setHuffmanOutputStreams(JPEGHuffmanOutputStream dc,JPEGHuffmanOutputStream ac)throws IOException{ this.dc=new JPEGDCOutputStream(dc); this.ac=new JPEGACOutputStream(ac); } public void write(int b)throws IOException{ buffer[count++]=b-levelshift; if(count==DCTBlockSize){ forwardDCT(buffer); dc.write((int)Math.round(buffer[IZigZagTable[0]]/qt[0])); for(int i=1;i<DCTBlockSize;i++){ ac.write((int)Math.round(buffer[IZigZagTable[i]]/qt[i])); } count=0; } } /* protected void forwardDCT(int[] buffer)throws IOException{ // The text book DCT algorithm. int matr1[]=new int[DCTBlockSize]; // temp buffer double[] coeff={1.0/Math.sqrt(2.0),1,1,1,1,1,1,1}; double sum; for(int v=0;v<DCTSize;v++) { for(int u=0;u<DCTSize;u++) { sum = 0.0; for(int y=0;y<DCTSize;y++){ for(int x=0;x<DCTSize;x++){ sum+=buffer[y*DCTSize+x]*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*=(coeff[u]*coeff[v])/4.0; matr1[v*DCTSize+u]=((int)Math.round(sum)); } } System.arraycopy(matr1,0,buffer,0,DCTBlockSize); } */ // http://forum.java.sun.com/thread.jspa?forumID=426&start=15&threadID=482368 [last accessed 2005-12-14] // based on http://www.ijg.org/ 'Independent JPEG Group' [last accessed 2005-12-14] private static final float F0 = (float)(1.0 / Math.sqrt(2)); // 0.7071067811865475 private static final float F1 = (float)Math.cos(1 * Math.PI / 16) / 2; // 0.4903926402016152 private static final float F2 = (float)Math.cos(2 * Math.PI / 16) / 2; // 0.46193976625564337 private static final float F3 = (float)Math.cos(3 * Math.PI / 16) / 2; // 0.4157348061512726 private static final float F4 = (float)Math.cos(4 * Math.PI / 16) / 2; // 0.3535533905932738 private static final float F5 = (float)Math.cos(5 * Math.PI / 16) / 2; // 0.27778511650980114 private static final float F6 = (float)Math.cos(6 * Math.PI / 16) / 2; // 0.19134171618254492 private static final float F7 = (float)Math.cos(7 * Math.PI / 16) / 2; // 0.09754516100806417 private static final float D71 = F7 - F1; // -0.39284747919355106 private static final float D35 = F3 - F5; // 0.13794968964147147 private static final float D62 = F6 - F2; // -0.27059805007309845 private static final float S71 = F7 + F1; // 0.5879378012096794 private static final float S35 = F3 + F5; // 0.6935199226610738 private static final float S62 = F6 + F2; // 0.6532814824381883 protected void forwardDCT(float[] buffer)throws IOException{ float temp; float a0, a1, a2, a3, a4, a5, a6, a7; float b0, b1, b2, b3, b4, b5, b6, b7; for(int y=0;y<64;y+=8){ b0 = buffer[y+0] + buffer[y+7]; b7 = buffer[y+0] - buffer[y+7]; b1 = buffer[y+1] + buffer[y+6]; b6 = buffer[y+1] - buffer[y+6]; b2 = buffer[y+2] + buffer[y+5]; b5 = buffer[y+2] - buffer[y+5]; b3 = buffer[y+3] + buffer[y+4]; b4 = buffer[y+3] - buffer[y+4]; a0 = b0 + b3; a1 = b1 + b2; a2 = b1 - b2; a3 = b0 - b3; a4 = b4; a5 = (b6 - b5) * F0; a6 = (b6 + b5) * F0; a7 = b7; buffer[y+0] =((a0 + a1) * F4); buffer[y+4] =((a0 - a1) * F4); temp = (a3 + a2) * F6; buffer[y+2] =(temp - a3 * D62); buffer[y+6] =(temp - a2 * S62); b4 = a4 + a5; b7 = a7 + a6; b5 = a4 - a5; b6 = a7 - a6; temp = (b7 + b4) * F7; buffer[y+1] =(temp - b7 * D71); buffer[y+7] =(temp - b4 * S71); temp = (b6 + b5) * F3; buffer[y+5] =(temp - b6 * D35); buffer[y+3] =(temp - b5 * S35); } for(int x=0;x<8;x++){ b0 = buffer[ 0+x] + buffer[56+x]; b7 = buffer[ 0+x] - buffer[56+x]; b1 = buffer[ 8+x] + buffer[48+x]; b6 = buffer[ 8+x] - buffer[48+x]; b2 = buffer[16+x] + buffer[40+x]; b5 = buffer[16+x] - buffer[40+x]; b3 = buffer[24+x] + buffer[32+x]; b4 = buffer[24+x] - buffer[32+x]; a0 = b0 + b3; a1 = b1 + b2; a2 = b1 - b2; a3 = b0 - b3; a4 = b4; a5 = (b6 - b5) * F0; a6 = (b6 + b5) * F0; a7 = b7; buffer[ 0+x] =((a0 + a1) * F4); buffer[32+x] =((a0 - a1) * F4); temp = (a3 + a2) * F6; buffer[16+x] =(temp - a3 * D62); buffer[48+x] =(temp - a2 * S62); b4 = a4 + a5; b7 = a7 + a6; b5 = a4 - a5; b6 = a7 - a6; temp = (b7 + b4) * F7; buffer[ 8+x] =(temp - b7 * D71); buffer[56+x] =(temp - b4 * S71); temp = (b6 + b5) * F3; buffer[40+x] =(temp - b6 * D35); buffer[24+x] =(temp - b5 * S35); } } /* protected void forwardDCTi(int[] buffer)throws IOException{ double temp; double a0, a1, a2, a3, a4, a5, a6, a7; double b0, b1, b2, b3, b4, b5, b6, b7; for(int y=0;y<64;y+=8){ b0 = buffer[y+0] + buffer[y+7]; b7 = buffer[y+0] - buffer[y+7]; b1 = buffer[y+1] + buffer[y+6]; b6 = buffer[y+1] - buffer[y+6]; b2 = buffer[y+2] + buffer[y+5]; b5 = buffer[y+2] - buffer[y+5]; b3 = buffer[y+3] + buffer[y+4]; b4 = buffer[y+3] - buffer[y+4]; a0 = b0 + b3; a1 = b1 + b2; a2 = b1 - b2; a3 = b0 - b3; a4 = b4; a5 = (b6 - b5) * F0; a6 = (b6 + b5) * F0; a7 = b7; buffer[y+0] =(int)((a0 + a1) * F4); buffer[y+4] =(int)((a0 - a1) * F4); temp = (a3 + a2) * F6; buffer[y+2] =(int)(temp - a3 * D62); buffer[y+6] =(int)(temp - a2 * S62); b4 = a4 + a5; b7 = a7 + a6; b5 = a4 - a5; b6 = a7 - a6; temp = (b7 + b4) * F7; buffer[y+1] =(int)(temp - b7 * D71); buffer[y+7] =(int)(temp - b4 * S71); temp = (b6 + b5) * F3; buffer[y+5] =(int)(temp - b6 * D35); buffer[y+3] =(int)(temp - b5 * S35); } for(int x=0;x<8;x++){ b0 = buffer[ 0+x] + buffer[56+x]; b7 = buffer[ 0+x] - buffer[56+x]; b1 = buffer[ 8+x] + buffer[48+x]; b6 = buffer[ 8+x] - buffer[48+x]; b2 = buffer[16+x] + buffer[40+x]; b5 = buffer[16+x] - buffer[40+x]; b3 = buffer[24+x] + buffer[32+x]; b4 = buffer[24+x] - buffer[32+x]; a0 = b0 + b3; a1 = b1 + b2; a2 = b1 - b2; a3 = b0 - b3; a4 = b4; a5 = (b6 - b5) * F0; a6 = (b6 + b5) * F0; a7 = b7; buffer[ 0+x] =(int)((a0 + a1) * F4); buffer[32+x] =(int)((a0 - a1) * F4); temp = (a3 + a2) * F6; buffer[16+x] =(int)(temp - a3 * D62); buffer[48+x] =(int)(temp - a2 * S62); b4 = a4 + a5; b7 = a7 + a6; b5 = a4 - a5; b6 = a7 - a6; temp = (b7 + b4) * F7; buffer[ 8+x] =(int)(temp - b7 * D71); buffer[56+x] =(int)(temp - b4 * S71); temp = (b6 + b5) * F3; buffer[40+x] =(int)(temp - b6 * D35); buffer[24+x] =(int)(temp - b5 * S35); } } */ }