001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, Geotools Project Managment Committee (PMC)
005: * (C) 2003, Institut de Recherche pour le Développement
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.image.jai;
018:
019: // J2SE dependencies
020: import java.awt.image.RenderedImage;
021: import java.awt.image.renderable.ParameterBlock;
022:
023: // JAI dependencies
024: import javax.media.jai.OperationDescriptorImpl;
025: import javax.media.jai.registry.RenderedRegistryMode;
026:
027: // Geotools dependencies
028: import org.geotools.resources.Utilities;
029: import org.geotools.resources.i18n.Errors;
030: import org.geotools.resources.i18n.ErrorKeys;
031:
032: /**
033: * The operation descriptor for the {@link Combine} operation. While this descriptor declares
034: * to support 0 {@link RenderedImage} sources, an arbitrary amount of sources can really be
035: * specified. The "0" should be understood as the <em>minimal</em> number of sources required.
036: *
037: * @since 2.1
038: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/coverage/src/main/java/org/geotools/image/jai/CombineDescriptor.java $
039: * @version $Id: CombineDescriptor.java 20970 2006-08-11 07:53:22Z jgarnett $
040: * @author Remi Eve
041: * @author Martin Desruisseaux
042: */
043: public class CombineDescriptor extends OperationDescriptorImpl {
044: /**
045: * The operation name, which is {@value}.
046: */
047: public static final String OPERATION_NAME = "org.geotools.Combine";
048:
049: /**
050: * Constructs the descriptor.
051: */
052: public CombineDescriptor() {
053: super (
054: new String[][] {
055: { "GlobalName", OPERATION_NAME },
056: { "LocalName", OPERATION_NAME },
057: { "Vendor", "org.geotools" },
058: { "Description",
059: "Combine rendered images using a linear relation." },
060: { "DocURL", "http://www.geotools.org/" }, // TODO: provides more accurate URL
061: { "Version", "1.0" },
062: { "arg0Desc",
063: "The coefficients for linear combinaison as a matrix." },
064: {
065: "arg1Desc",
066: "An optional transform to apply on sample values "
067: + "before the linear combinaison." } },
068: new String[] { RenderedRegistryMode.MODE_NAME },
069: 0, // Supported modes
070: new String[] { "matrix", "transform" }, // Parameter names
071: new Class[] { double[][].class, CombineTransform.class }, // Parameter classes
072: new Object[] { NO_PARAMETER_DEFAULT, null }, // Default value
073: null // Valid parameter values
074: );
075: }
076:
077: /**
078: * Returns {@code true} if this operation supports the specified mode, and
079: * is capable of handling the given input source(s) for the specified mode.
080: *
081: * @param modeName The mode name (usually "Rendered").
082: * @param param The parameter block for the operation to performs.
083: * @param message A buffer for formatting an error message if any.
084: */
085: protected boolean validateSources(final String modeName,
086: final ParameterBlock param, final StringBuffer message) {
087: if (super .validateSources(modeName, param, message)) {
088: for (int i = param.getNumSources(); --i >= 0;) {
089: final Object source = param.getSource(i);
090: if (!(source instanceof RenderedImage)) {
091: message.append(Errors.format(
092: ErrorKeys.BAD_PARAMETER_TYPE_$2, "source"
093: + i, Utilities
094: .getShortClassName(source)));
095: return false;
096: }
097: }
098: return true;
099: }
100: return false;
101: }
102:
103: /**
104: * Returns {@code true} if the parameters are valids. This implementation check
105: * that the number of bands in the source src1 is equals to the number of bands of
106: * source src2.
107: *
108: * @param modeName The mode name (usually "Rendered").
109: * @param param The parameter block for the operation to performs.
110: * @param message A buffer for formatting an error message if any.
111: */
112: protected boolean validateParameters(final String modeName,
113: final ParameterBlock param, final StringBuffer message) {
114: if (!super .validateParameters(modeName, param, message)) {
115: return false;
116: }
117: final double[][] matrix = (double[][]) param
118: .getObjectParameter(0);
119: int numSamples = 1; // Begin at '1' for the offset value.
120: for (int i = param.getNumSources(); --i >= 0;) {
121: numSamples += ((RenderedImage) param.getSource(i))
122: .getSampleModel().getNumBands();
123: }
124: for (int i = 0; i < matrix.length; i++) {
125: if (matrix[i].length != numSamples) {
126: message.append(Errors.format(
127: ErrorKeys.UNEXPECTED_ROW_LENGTH_$3,
128: new Integer(i), new Integer(matrix[i].length),
129: new Integer(numSamples)));
130: return false;
131: }
132: }
133: return true;
134: }
135: }
|