blob: 77e0c9a109cbc776cb86510a8eee39bc4b323de1 [file] [log] [blame]
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
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;
// If subsampling is being used, we may not match the
// true tile grid exactly, but everything should still work
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);
}
/**
* Creates a copy of {@code param}. The source subsampling and
* and bands settings and the destination bands and offset settings
* are copied. If {@code param} is a {@code TIFFImageReadParam}
* then the {@code TIFFDecompressor} and
* {@code TIFFColorConverter} settings are also copied; otherwise
* they are explicitly set to {@code null}.
*
* @param param the parameters to be copied.
* @param copyTagSets whether the {@code TIFFTagSet} settings
* should be copied if set.
* @return copied parameters.
*/
private ImageReadParam cloneImageReadParam(ImageReadParam param,
boolean copyTagSets) {
// Create a new TIFFImageReadParam.
TIFFImageReadParam newParam = new TIFFImageReadParam();
// Copy the basic settings.
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) {
// Copy the settings from the input parameter.
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);
}
// This method needs to be synchronized as it updates the instance
// variable 'tileParam'.
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;
}
}
}