/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2006-2015, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotools.coverage.processing.operation; import java.awt.RenderingHints; import java.awt.image.DataBuffer; import java.awt.image.RenderedImage; import java.util.HashMap; import java.util.Map; import javax.media.jai.Interpolation; import javax.media.jai.InterpolationNearest; import javax.media.jai.JAI; import javax.media.jai.ParameterBlockJAI; import javax.media.jai.PlanarImage; import javax.media.jai.PropertyGenerator; import javax.media.jai.ROI; import javax.media.jai.RenderedOp; import javax.media.jai.registry.RenderedRegistryMode; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.processing.BaseScaleOperationJAI; import org.geotools.coverage.processing.OperationJAI; import org.geotools.image.jai.Registry; import org.geotools.resources.coverage.CoverageUtilities; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.util.InternationalString; /** * This operation is simply a wrapper for the JAI scale operation which allows * me to arbitrarily scale and translate a rendered image. * * @source $URL$ * @version $Id$ * @author Simone Giannecchini * @since 2.3 * * @see javax.media.jai.operator.ScaleDescriptor */ public class Scale extends BaseScaleOperationJAI { /** * Serial number for cross-version compatibility. */ private static final long serialVersionUID = -3212656385631097713L; /** Lock for unsetting native acceleration. */ private final static int[] lock = new int[1]; /** * Default constructor. */ public Scale() { super("Scale"); } @Override protected RenderedImage createRenderedImage(ParameterBlockJAI parameters, RenderingHints hints) { final RenderedImage source = (RenderedImage) parameters.getSource(0); final Interpolation interpolation; if(parameters.getObjectParameter("interpolation")!=null) interpolation=(Interpolation) parameters.getObjectParameter("interpolation"); else if(hints.get(JAI.KEY_INTERPOLATION)!=null) interpolation=(Interpolation) hints.get(JAI.KEY_INTERPOLATION); else { //I am pretty sure this should not happen. However I am not sure we should throw an error interpolation=null; } final int transferType = source.getSampleModel().getDataType(); final JAI processor = OperationJAI.getJAI(hints); PlanarImage image; if (interpolation!=null&&!(interpolation instanceof InterpolationNearest) && (transferType == DataBuffer.TYPE_FLOAT || transferType == DataBuffer.TYPE_DOUBLE)) { synchronized (lock) { /** * Disables the native acceleration for the "Scale" operation. * In JAI 1.1.2, the "Scale" operation on TYPE_FLOAT datatype * with INTERP_BILINEAR interpolation cause an exception in the * native code of medialib, which halt the Java Virtual Machine. * Using the pure Java implementation instead resolve the * problem. * * @todo Remove this hack when Sun will fix the medialib bug. * See * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4906854 */ Registry.setNativeAccelerationAllowed(getName(), false); image = processor.createNS(getName(), parameters, hints).getRendering(); /** * see above */ Registry.setNativeAccelerationAllowed(getName(), true); } } else image = processor.createNS(getName(), parameters, hints); return image; } protected void handleJAIEXTParams(ParameterBlockJAI parameters, ParameterValueGroup parameters2) { GridCoverage2D source = (GridCoverage2D) parameters2.parameter("source0").getValue(); handleROINoDataInternal(parameters, source, SCALE, 5, 7); } protected Map<String, ?> getProperties(RenderedImage data, CoordinateReferenceSystem crs, InternationalString name, MathTransform gridToCRS, GridCoverage2D[] sources, Parameters parameters) { Map props = sources[PRIMARY_SOURCE_INDEX].getProperties(); Map properties = new HashMap<>(); if (props != null) { properties.putAll(props); } if (parameters.parameters.getNumParameters() > 5 && parameters.parameters.getObjectParameter(8) != null) { // Setting NoData property if needed Object bkgProp = parameters.parameters.getObjectParameter(8); if (bkgProp != null && bkgProp instanceof double[]) { double[] background = (double[]) bkgProp; CoverageUtilities.setNoDataProperty(properties, background); } } // Setting ROI if present if (data instanceof RenderedOp) { String operationName = ((RenderedOp) data).getOperationName(); PropertyGenerator propertyGenerator = null; if (operationName.equalsIgnoreCase(SCALE) || operationName.equalsIgnoreCase(TRANSLATE)) { propertyGenerator = getOperationDescriptor(operationName).getPropertyGenerators(RenderedRegistryMode.MODE_NAME)[0]; } if (propertyGenerator != null) { Object roiProp = propertyGenerator.getProperty(ROI, data); if (roiProp != null && roiProp instanceof ROI) { CoverageUtilities.setROIProperty(properties, (ROI) roiProp); } } } return properties; } }