Package org.geotools.coverage.processing.operation

Source Code of org.geotools.coverage.processing.operation.IndexColorOperation

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2006-2008, 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.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.RenderedImage;

import javax.media.jai.ImageLayout;
import javax.media.jai.NullOpImage;
import javax.media.jai.OpImage;

import org.opengis.coverage.Coverage;
import org.opengis.coverage.SampleDimension;
import org.opengis.coverage.grid.GridCoverage;
import org.opengis.parameter.ParameterValueGroup;

import org.geotools.factory.GeoTools;
import org.geotools.factory.Hints;
import org.geotools.coverage.CoverageFactoryFinder;
import org.geotools.coverage.GridSampleDimension;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.ViewType;
import org.geotools.coverage.processing.Operation2D;
import org.geotools.parameter.DefaultParameterDescriptorGroup;
import org.geotools.resources.coverage.CoverageUtilities;
import org.geotools.resources.image.ColorUtilities;
import org.geotools.resources.Classes;
import org.geotools.resources.i18n.ErrorKeys;
import org.geotools.resources.i18n.Errors;


/**
* Operation applied only on image's colors. This operation work only for source
* image using an {@link IndexColorModel}.
*
* @source $URL$
* @version $Id$
* @author Martin Desruisseaux
*
* @todo Consider moving this class to the {@link org.geotools.coverage.processing} package.
*/
abstract class IndexColorOperation extends Operation2D {
    /**
     * Constructs an operation.
     */
    public IndexColorOperation(final DefaultParameterDescriptorGroup descriptor) {
        super(descriptor);
    }

    /**
     * Performs the color transformation. This method invokes the
     * {@link #transformColormap transformColormap(...)} method with current RGB
     * colormap, the source {@link SampleDimension} and the supplied parameters.
     *
     * @param parameters The parameters.
     * @param hints Rendering hints (ignored in this implementation).
     *
     * @throws IllegalArgumentException if the candidate image do not use an
     *         {@link IndexColorModel}.
     */
    public Coverage doOperation(final ParameterValueGroup parameters, final Hints hints) {
        final GridCoverage2D source = (GridCoverage2D) parameters.parameter("Source").getValue();
        final GridCoverage2D visual = source.view(ViewType.RENDERED);
        final RenderedImage  image  = visual.getRenderedImage();
        final GridSampleDimension[] bands = visual.getSampleDimensions();
        final int visibleBand = CoverageUtilities.getVisibleBand(image);
        ColorModel model = image.getColorModel();
        boolean colorChanged = false;
        for (int i=0; i<bands.length; i++) {
            /*
             * Extracts the ARGB codes from the IndexColorModel and invokes the
             * transformColormap(...) method, which needs to be defined by subclasses.
             */
            GridSampleDimension band = bands[i];
            final ColorModel candidate = (i == visibleBand) ? image.getColorModel() : band.getColorModel();
            if (!(candidate instanceof IndexColorModel)) {
                // Current implementation supports only sources that use an index color model.
                throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_CLASS_$2,
                        Classes.getClass(candidate), IndexColorModel.class));
            }
            final IndexColorModel colors = (IndexColorModel) candidate;
            final int mapSize = colors.getMapSize();
            final int[] ARGB = new int[mapSize];
            colors.getRGBs(ARGB);
            band = transformColormap(ARGB, i, band, parameters);
            /*
             * Checks if there is any change, either as a new GridSampleDimension instance or in
             * the ARGB array. Note that if the new GridSampleDimension is equals to the old one,
             * then the new one will be discarted since the old one is more likely to be a shared
             * instance.
             */
            if (!bands[i].equals(band)) {
                bands[i] = band;
                colorChanged = true;
            } else if (!colorChanged) {
                for (int j=0; j<mapSize; j++) {
                    if (ARGB[j] != colors.getRGB(j)) {
                        colorChanged = true;
                        break;
                    }
                }
            }
            /*
             * If we changed the color of the visible band, then create immediately a new
             * color model for this band. The new color model will be given later to the
             * image operator.
             */
            if (colorChanged && (i == visibleBand)) {
                model = ColorUtilities.getIndexColorModel(ARGB, bands.length, visibleBand);
            }
        }
        if (!colorChanged) {
            return source;
        }
        /*
         * Gives the color model to the image layout and creates a new image using the Null
         * operation, which merely propagates its first source along the operation chain
         * unmodified (except for the ColorModel given in the layout in this case).
         */
        final ImageLayout layout = new ImageLayout().setColorModel(model);
        final RenderedImage newImage = new NullOpImage(image, layout, null, OpImage.OP_COMPUTE_BOUND);
        final GridCoverage2D target = CoverageFactoryFinder.getGridCoverageFactory(GeoTools.getDefaultHints()).create(
                    visual.getName(), newImage,
                    visual.getCoordinateReferenceSystem2D(),
                    visual.getGridGeometry().getGridToCRS(),
                    bands, new GridCoverage[] { visual }, null);

        if (source != visual) {
            // TODO: needs to select the right type.
            return target.geophysics(true);
        }
        return target;
    }

    /**
     * Transforms the supplied RGB colors. This method is automatically invoked
     * by {@link #doOperation(ParameterList)} for each band in the source
     * {@link GridCoverage2D}. The {@code ARGB} array contains the ARGB values
     * from the current source and should be overridden with new ARGB values
     * for the destination image.
     *
     * @param ARGB
     *            Alpha, Red, Green and Blue components to transform.
     * @param band
     *            The band number, from 0 to the number of bands in the image -1.
     * @param sampleDimension
     *            The sample dimension of band {@code band}.
     * @param parameters
     *            The user-supplied parameters.
     * @return A sample dimension identical to {@code sampleDimension} except for the
     *         colors. Subclasses may conservatively returns {@code sampleDimension}.
     */
    protected abstract GridSampleDimension transformColormap(final int[] ARGB, final int band,
            final GridSampleDimension sampleDimension, final ParameterValueGroup parameters);
}
TOP

Related Classes of org.geotools.coverage.processing.operation.IndexColorOperation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.