/* JAI-Ext - OpenSource Java Advanced Image Extensions Library * http://www.geo-solutions.it/ * Copyright 2014 GeoSolutions * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package it.geosolutions.jaiext.nullop; import java.awt.Rectangle; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.util.Hashtable; import java.util.Map; import javax.media.jai.ImageLayout; import javax.media.jai.OpImage; import javax.media.jai.PlanarImage; import javax.media.jai.PointOpImage; import com.sun.media.jai.util.JDKWorkarounds; /** * An<code>OpImage</code> subclass that simply transmits its * source unchanged. This may be useful when an interface requires an * <code>OpImage</code> but another sort of <code>RenderedImage</code> * (such as a <code>BufferedImage</code> or <code>TiledImage</code>) * is available. Additionally, <code>NullOpImage</code> is able to * make use of JAI's tile caching mechanisms. * * <p> Methods that get or set properties are implemented to forward * the requests to the source image; no independent property information * is stored in the <code>NullOpImage</code> itself. * * @see PointOpImage */ public class NullOpImage extends OpImage { /** * Create a new ImageLayout from the source image optionally overriding a ColorModel supplied via the layout. */ private static ImageLayout layoutHelper(RenderedImage source, ImageLayout layout) { // Create basic layout from the source. ImageLayout il = new ImageLayout(source); // If a layout containing a valid ColorModel field is supplied then // reset the ColorModel if it is compatible with the SampleModel. if(layout != null && layout.isValid(ImageLayout.COLOR_MODEL_MASK)) { ColorModel colorModel = layout.getColorModel(null); if(JDKWorkarounds.areCompatibleDataModels(source.getSampleModel(), colorModel)) { il.setColorModel(colorModel); } } return il; } /** * Constructs a <code>NullOpImage</code>. The superclass * constructor will be passed a new <code>ImageLayout</code> * object with all of its fields filled in. * * @param layout An <code>ImageLayout</code> optionally specifying * the image <code>ColorModel</code>; all other fields are * ignored. This parameter may be <code>null</code>. * @param source A <code>RenderedImage</code>; must not be * <code>null</code> or a <code>IllegalArgumentException</code> * will be thrown. * @param configuration Configurable attributes of the image including * configuration variables indexed by * <code>RenderingHints.Key</code>s and image properties indexed * by <code>String</code>s or <code>CaselessStringKey</code>s. * This is simply forwarded to the superclass constructor. * * @throws <code>IllegalArgumentException</code> if <code>source</code> * is <code>null</code>. * @throws <code>IllegalArgumentException</code> if <code>computeType</code> * is not one of the known <code>OP_*_BOUND</code> values. * */ public NullOpImage(RenderedImage source, ImageLayout layout, Map configuration) { super(vectorize(source),layoutHelper(source, layout),configuration,true); } /** * Returns a tile for reading. * * @param tileX The X index of the tile. * @param tileY The Y index of the tile. * @return The tile as a <code>Raster</code>. */ public Raster computeTile(int tileX, int tileY) { return getSourceImage(0).getTile(tileX, tileY); } /** * Returns false as NullOpImage can return via computeTile() * tiles that are internally cached. */ public boolean computesUniqueTiles() { return false; } /** * Returns the properties from the source image. */ protected synchronized Hashtable getProperties() { // Selection of all the image properties String[] propertyNames = getPropertyNames(); // Selection of the source image RenderedImage sourceImage = getSourceImage(0); // Creation of a Map containing all the source image properties Hashtable<String, Object> properties = new Hashtable<String, Object>(); // Cycle on all the properties if(propertyNames != null){ for(String property : propertyNames){ // Addition of the selected property properties.put(property, sourceImage.getProperty(property)); } return properties; }else{ return null; } } /** * Set the properties <code>Hashtable</code> of the source image * to the supplied <code>Hashtable</code>. */ protected synchronized void setProperties(Hashtable properties) { // Selection of the source image PlanarImage sourceImage = getSourceImage(0); Hashtable<String, Object> propertyTable = properties; if(propertyTable != null){ // Cycle on all the properties for(String property : propertyTable.keySet()){ // Setting of the selected property sourceImage.setProperty(property, propertyTable.get(property)); } } } /** * Returns the property names from the source image or <code>null</code> * if no property names are recognized. */ public String[] getPropertyNames() { return getSourceImage(0).getPropertyNames(); } /** * Returns the property names with the supplied prefix from * the source image or <code>null</code> if no property names * are recognized. */ public String[] getPropertyNames(String prefix) { return getSourceImage(0).getPropertyNames(prefix); } /** * Returns the class of the specified property from the source image. */ public Class getPropertyClass(String name) { return getSourceImage(0).getPropertyClass(name); } /** * Retrieves a property from the source image by name or * <code>java.awt.Image.UndefinedProperty</code> if the property * with the specified name is not defined. */ public Object getProperty(String name) { return getSourceImage(0).getProperty(name); } /** * Sets a property on the source image by name. */ public void setProperty(String name, Object value) { getSourceImage(0).setProperty(name, value); } /** * Removes a property from the source image by name. */ public void removeProperty(String name) { getSourceImage(0).removeProperty(name); } @Override public Rectangle mapDestRect(Rectangle destRect, int sourceIndex) { return destRect; } @Override public Rectangle mapSourceRect(Rectangle sourceRect, int sourceIndex) { return sourceRect; } }