| /* |
| * 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; |
| } |
| } |
| } |