package com.sun.imageio.plugins.tiff;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.plugins.tiff.TIFFImageReadParam;
import javax.imageio.plugins.tiff.TIFFTagSet;
public class TIFFRenderedImage implements RenderedImage {
private TIFFImageReader reader;
private int imageIndex;
private ImageReadParam tileParam;
private int subsampleX;
private int subsampleY;
private boolean isSubsampling;
private int width;
private int height;
private int tileWidth;
private int tileHeight;
private ImageTypeSpecifier its;
public TIFFRenderedImage(TIFFImageReader reader,
int imageIndex,
ImageReadParam readParam,
int width, int height) throws IOException {
this.reader = reader;
this.imageIndex = imageIndex;
this.tileParam = cloneImageReadParam(readParam, false);
this.subsampleX = tileParam.getSourceXSubsampling();
this.subsampleY = tileParam.getSourceYSubsampling();
this.isSubsampling = this.subsampleX != 1 || this.subsampleY != 1;
this.width = width/subsampleX;
this.height = height/subsampleY;
this.tileWidth = reader.getTileWidth(imageIndex)/subsampleX;
this.tileHeight = reader.getTileHeight(imageIndex)/subsampleY;
Iterator<ImageTypeSpecifier> iter = reader.getImageTypes(imageIndex);
this.its = iter.next();
tileParam.setDestinationType(its);
}
private ImageReadParam cloneImageReadParam(ImageReadParam param,
boolean copyTagSets) {
TIFFImageReadParam newParam = new TIFFImageReadParam();
newParam.setSourceSubsampling(param.getSourceXSubsampling(),
param.getSourceYSubsampling(),
param.getSubsamplingXOffset(),
param.getSubsamplingYOffset());
newParam.setSourceBands(param.getSourceBands());
newParam.setDestinationBands(param.getDestinationBands());
newParam.setDestinationOffset(param.getDestinationOffset());
if (param instanceof TIFFImageReadParam && copyTagSets) {
TIFFImageReadParam tparam = (TIFFImageReadParam) param;
List<TIFFTagSet> tagSets = tparam.getAllowedTagSets();
if (tagSets != null) {
Iterator<TIFFTagSet> tagSetIter = tagSets.iterator();
if (tagSetIter != null) {
while (tagSetIter.hasNext()) {
TIFFTagSet tagSet = tagSetIter.next();
newParam.addAllowedTagSet(tagSet);
}
}
}
}
return newParam;
}
public Vector<RenderedImage> getSources() {
return null;
}
public Object getProperty(String name) {
return java.awt.Image.UndefinedProperty;
}
public String[] getPropertyNames() {
return null;
}
public ColorModel getColorModel() {
return its.getColorModel();
}
public SampleModel getSampleModel() {
return its.getSampleModel();
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public int getMinX() {
return 0;
}
public int getMinY() {
return 0;
}
public int getNumXTiles() {
return (width + tileWidth - 1)/tileWidth;
}
public int getNumYTiles() {
return (height + tileHeight - 1)/tileHeight;
}
public int getMinTileX() {
return 0;
}
public int getMinTileY() {
return 0;
}
public int getTileWidth() {
return tileWidth;
}
public int getTileHeight() {
return tileHeight;
}
public int getTileGridXOffset() {
return 0;
}
public int getTileGridYOffset() {
return 0;
}
public Raster getTile(int tileX, int tileY) {
Rectangle tileRect = new Rectangle(tileX*tileWidth,
tileY*tileHeight,
tileWidth,
tileHeight);
return getData(tileRect);
}
public Raster getData() {
return read(new Rectangle(0, 0, getWidth(), getHeight()));
}
public Raster getData(Rectangle rect) {
return read(rect);
}
public synchronized WritableRaster read(Rectangle rect) {
tileParam.setSourceRegion(isSubsampling ?
new Rectangle(subsampleX*rect.x,
subsampleY*rect.y,
subsampleX*rect.width,
subsampleY*rect.height) :
rect);
try {
BufferedImage bi = reader.read(imageIndex, tileParam);
WritableRaster ras = bi.getRaster();
return ras.createWritableChild(0, 0,
ras.getWidth(), ras.getHeight(),
rect.x, rect.y,
null);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public WritableRaster copyData(WritableRaster raster) {
if (raster == null) {
return read(new Rectangle(0, 0, getWidth(), getHeight()));
} else {
Raster src = read(raster.getBounds());
raster.setRect(src);
return raster;
}
}
}