package uk.co.mmscomputing.imageio.tiff;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.nio.ByteOrder;
import javax.imageio.*;
import javax.imageio.spi.*;
import javax.imageio.stream.*;
import javax.imageio.metadata.*;
public class TIFFImageReader extends ImageReader implements TIFFConstants{
private Vector ifds=null;
protected TIFFImageReader(ImageReaderSpi originatingProvider){
super(originatingProvider);
}
public BufferedImage read(int imageIndex, ImageReadParam param)throws IOException{
readIFDs();
checkIndex(imageIndex);
return readImage(((IFD)ifds.elementAt(imageIndex)));
}
public int getHeight(int imageIndex)throws IOException{
readIFDs();
checkIndex(imageIndex);
return ((IFD)ifds.elementAt(imageIndex)).getHeight();
}
public int getWidth(int imageIndex)throws IOException{
readIFDs();
checkIndex(imageIndex);
return ((IFD)ifds.elementAt(imageIndex)).getWidth();
}
public Iterator getImageTypes(int imageIndex)throws IOException{
readIFDs();
checkIndex(imageIndex);
ImageTypeSpecifier imageType = null;
java.util.List l = new ArrayList();
imageType=ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
l.add(imageType);
return l.iterator();
}
public int getNumImages(boolean allowSearch)throws IOException{
readIFDs();
return ifds.size();
}
public IIOMetadata getImageMetadata(int imageIndex)throws IOException{
readIFDs();
checkIndex(imageIndex);
return null;
}
public IIOMetadata getStreamMetadata() throws IOException{
return null;
}
private void checkIndex(int imageIndex) {
if (imageIndex > ifds.size()) {
throw new IndexOutOfBoundsException("\n"+getClass().getName()+".checkIndex:\n Bad index in image reader");
}
}
private long readImageFileHeader(ImageInputStream in)throws IOException{
// System.err.println("getUseCache = "+ImageIO.getUseCache());
int bo=in.readUnsignedShort();
if(bo==0x00004D4D){ // MM
in.setByteOrder(ByteOrder.BIG_ENDIAN);
// System.out.println("3\bbig endian");
}else if(bo==0x00004949){ // II
in.setByteOrder(ByteOrder.LITTLE_ENDIAN);
}else{
throw new IOException("\n"+getClass().getName()+".readImageFileHeader\n\tInvalid tiff document : MM or II missing.");
}
int version=in.readUnsignedShort();
if(version!=42){
throw new IOException("\n"+getClass().getName()+".readImageFileHeader\n\tInvalid tiff document : Unsupported Version: "+version+".");
}
return in.readUnsignedInt();
}
private void readIFDs()throws IOException{ // read image file directories
if(ifds==null){
ifds=new Vector();
ImageInputStream in=(ImageInputStream)getInput();
long pos=readImageFileHeader(in);
while(pos!=0){
IFD ifd=new IFD();
pos=ifd.read(in,pos);
ifds.add(ifd);
}
}
}
private BufferedImage readImage(IFD ifd)throws IOException{
int cmp=ifd.getCompression();
if((cmp==CCITTFAXT4)||(cmp==CCITTFAXT6)){ // Profile F Facsimile
return TIFFClassFFactory.readImage((ImageInputStream)getInput(),ifd);
}
if(cmp==JPEGDeprecated){
System.out.println("9\b"+getClass().getName()+".readImage:\n\tDo not support old style JPEG compression.");
return null;
}
return TIFFBaselineFactory.readImage((ImageInputStream)getInput(),ifd);
}
}
/*
[1] Adobe TIFF6.pdf
[2] RFC 2306 http://www.faqs.org/rfcs/rfc2306.html [last accessed: 2005-10-14]
*/