/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2003-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2009-2012, Geomatys * * 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.geotoolkit.internal.image.jai; import java.util.List; import java.util.Vector; import javax.media.jai.CRIFImpl; import java.awt.image.RenderedImage; import java.awt.image.renderable.ParameterBlock; import java.awt.RenderingHints; import org.geotoolkit.resources.Errors; import org.geotoolkit.image.jai.Combine; import static org.geotoolkit.image.jai.Combine.Transform; /** * The image factory for the {@link Combine} operation. * * @author RĂ©mi Eve (IRD) * @author Martin Desruisseaux (IRD) * @version 3.00 * * @since 2.1 * @module */ public final class CombineCRIF extends CRIFImpl { /** * Constructs a default factory. */ public CombineCRIF() { } /** * Creates a {@link RenderedImage} representing the results of an imaging * operation for a given {@link ParameterBlock} and {@link RenderingHints}. * * @param param The parameter to be given to the image operation. * @param hints An optional set of hints, or {@code null}. */ @Override public RenderedImage create(final ParameterBlock param, final RenderingHints hints) { final Vector<RenderedImage> sources = cast(param.getSources()); final double[][] matrix = (double[][]) param.getObjectParameter(0); final Transform transform = (Transform) param.getObjectParameter(1); return transform == null && isDyadic(sources, matrix) ? new Combine.Dyadic(sources, matrix, hints) : new Combine (sources, matrix, transform, hints); } /** * Returns {@code true} if the combine operation could be done through * the optimized {@code Combine.Dyadic} class. */ private static boolean isDyadic(final List<?> sources, final double[][] matrix) { if (sources.size() != 2) { return false; } final RenderedImage src0 = (RenderedImage) sources.get(0); final RenderedImage src1 = (RenderedImage) sources.get(1); final int numBands0 = src0.getSampleModel().getNumBands(); final int numBands1 = src1.getSampleModel().getNumBands(); final int numBands = matrix.length; if (numBands!=numBands0 || numBands!=numBands1) { return false; } for (int i=0; i<numBands; i++) { final double[] row = matrix[i]; for (int j=numBands0+numBands1; --j>=0;) { if (j!=i && j!=i+numBands0 && row[j]!=0) { return false; } } } return true; } /** * Casts the given vector of object to a vector of rendered image. This method is not public * because while the vector is correct right after this method, there is nothing preventing * the callers to add invalid objects in the original vector after the call. */ @SuppressWarnings("unchecked") static Vector<RenderedImage> cast(final Vector<?> sources) { for (final Object element : sources) { if (!(element instanceof RenderedImage)) { throw new ClassCastException(Errors.format(Errors.Keys.IllegalClass_2, element.getClass(), RenderedImage.class)); } } return (Vector<RenderedImage>) sources; } }