package uk.co.mmscomputing.imageio.jpeg; import java.io.*; public class JFIFInputStream extends JPEGInputStream{ protected int version; // 1.02 protected int units; // density unit = 0 => Only the aspect ratio is specified. // density unit = 1 => Density in pixels per inch. // density unit = 2 => Density in pixels per centimeter. protected int xDensity,yDensity; protected int xThumbnail,yThumbnail; public JFIFInputStream(InputStream in)throws IOException{ super(in); } public int getUnits(){return units;} public int getXDensity(){return xDensity;} public int getYDensity(){return yDensity;} public void app0(InputStream in)throws IOException{ // 0xE0 String id="";for(int i=0;i<5;i++){id+=(char)readIn(in);} // System.out.println("ID="+id); if(id.equals("JFIF\0")){ version =readIn(in)<<8|readIn(in); // System.out.println("Version="+Integer.toHexString(version)); units =readIn(in); // System.out.println("Units="+units); xDensity=readIn(in)<<8|readIn(in); // System.out.println("Xdensity="+xDensity); yDensity=readIn(in)<<8|readIn(in); // System.out.println("Ydensity="+yDensity); xThumbnail=readIn(in); // System.out.println("Xthumbnail="+xThumbnail); yThumbnail=readIn(in); // System.out.println("Ythumbnail="+yThumbnail); }else if(id.equals("JFXX\0")){ } } // The Gimp can put in Exif data. I.e.: // E x i f 0 0 Exif Header // M M 0 42 0 0 0 8 0 0 0 0 0 0 Empty TIFF Image. public void app1(InputStream in)throws IOException{ // 0xE1 String id="";for(int i=0;i<6;i++){id+=(char)readIn(in);} System.out.println("ID="+id); if(id.equals("Exif\0\0")){ // TIFF Header [2] // dump(in); } } // http://www.color.org/ICC1V42.pdf public void app2(InputStream in)throws IOException{ // 0xE1 String id="";byte b;int i=0; while((b=(byte)in.read())!=-1){ id+=(char)b; System.out.println("APP2["+i+"] 0x"+Integer.toHexString(b)+" "+(char)((b>=' ')?b:' ')+" "+b);i++; if(id.equals("ICC_PROFILE\0")){ break; } } } public void app13(InputStream in)throws IOException{ // 0xED String id="";byte b;int i=0; while((b=(byte)in.read())!=-1){ id+=(char)b; System.out.println("APP13["+i+"] 0x"+Integer.toHexString(b)+" "+(char)((b>=' ')?b:' ')+" "+b);i++; if(id.equals("Photoshop 3.0\0")){ break; } } } // http://partners.adobe.com/public/developer/en/ps/sdk/5116.DCT_Filter.pdf p.27 public void app14(InputStream in)throws IOException{ // 0xEE String id="";byte b;int i=0; while((b=(byte)in.read())!=-1){ id+=(char)b; System.out.println("APP14["+i+"] 0x"+Integer.toHexString(b)+" "+(char)((b>=' ')?b:' ')+" "+b);i++; if(id.equals("Adobe\0")){ /* int version=in.read()|(in.read()<<8); int flag0=in.read()|(in.read()<<8); // not essential int flag1=in.read()|(in.read()<<8); // essential int ctc=in.read(); System.out.println(id); System.out.println("Version=0x"+Integer.toHexString(version)); System.out.println("flag0=0x"+Integer.toHexString(flag0)); System.out.println("flag1=0x"+Integer.toHexString(flag1)); System.out.println("ctc=0x"+Integer.toHexString(ctc)); */ break; } } } public int read(int[] buf, int off, int len)throws IOException{ double Y,Cb,Cr; int YCbCr,R,G,B,RGB; len=super.read(buf,off,len); for(int i=0;i<len;i++){ YCbCr=buf[i]; Y =((YCbCr>>16)&0x000000FF); Cb=((YCbCr>> 8)&0x000000FF); Cr=((YCbCr )&0x000000FF); R =(int)(Y + 1.402 *(Cr-128.0)); if(R<0){R=0;}else if(R>255){R=255;} G =(int)(Y - 0.3441363*(Cb-128.0) - 0.71413636*(Cr-128.0)); if(G<0){G=0;}else if(G>255){G=255;} B =(int)(Y + 1.772 *(Cb-128.0)); if(B<0){B=0;}else if(B>255){B=255;} buf[i]=(R<<16)|(G<<8)|B; } return len; } } // [1] JPEG File Interchange Format (JFIF) // Version 1.02 [1992-09-01] // http://www.jpeg.org/public/jfif.pdf [last accessed 2005-11-28] // [2] http://www.media.mit.edu/pia/Research/deepview/exif.html [last accessed 2005-11-28]