/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2001-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.image.color; import java.awt.color.ColorSpace; import org.apache.sis.util.Classes; /** * Color space for images storing pixels as real numbers. The color model can have an * arbitrary number of bands, but in current implementation only one band is used. * * @author Martin Desruisseaux (IRD) * @version 3.00 * * @since 1.2 * @module */ public final class ScaledColorSpace extends ColorSpace { /** * For cross-version compatibility. */ private static final long serialVersionUID = 438226855772441165L; /** * Minimal normalized RGB value. */ private static final float MIN_VALUE = 0f; /** * Maximal normalized RGB value. */ private static final float MAX_VALUE = 1f; /** * The scaling factor for pixel values. */ private final float scale; /** * The offset to apply after the {@linkplain #scale} on pixel values. */ private final float offset; /** * Index of the band to display. */ private final int visibleBand; /** * Creates a color model. * * @param numComponents The number of components. * @param visibleBand The band to use for computing colors. * @param minimum The minimal sample value expected. * @param maximum The maximal sample value expected. */ public ScaledColorSpace(final int numComponents, final int visibleBand, final float minimum, final float maximum) { super(TYPE_GRAY, numComponents); this.visibleBand = visibleBand; scale = (maximum - minimum) / (MAX_VALUE - MIN_VALUE); offset = minimum - MIN_VALUE*scale; } /** * Creates a color model. * * @param numComponents The number of components. * @param visibleBand The band to use for computing colors. * @param minimum The minimal sample value expected. * @param maximum The maximal sample value expected. */ public ScaledColorSpace(final int numComponents, final int visibleBand, final double minimum, final double maximum) { super(TYPE_GRAY, numComponents); this.visibleBand = visibleBand; final double scale = (maximum - minimum) / (MAX_VALUE - MIN_VALUE); this.scale = (float) scale; this.offset = (float) (minimum - MIN_VALUE*scale); } /** * Returns a RGB color for a gray scale value. * * @param values The gray scale values. */ @Override public float[] toRGB(final float[] values) { float value = (values[visibleBand] - offset) / scale; //-- logic operation >, < ,= return false when at least one argument is Double.NAN //-- to avoid bad NAN value condition is coded as follow : if (!(value >= MIN_VALUE)) { value = MIN_VALUE; } else if (value > MAX_VALUE) { value = MAX_VALUE; } return new float[] {value, value, value}; } /** * Returns a real value for the specified RGB color. * The RGB color is assumed to be a gray scale value. * * @param RGB The RGB values. */ @Override public float[] fromRGB(final float[] RGB) { final float[] values = new float[getNumComponents()]; values[visibleBand] = (RGB[0] + RGB[1] + RGB[2]) / 3 * scale + offset; return values; } /** * Converts a color to the CIEXYZ color space. * * @param values The color values. */ @Override public float[] toCIEXYZ(final float[] values) { float value = (values[visibleBand] - offset) / scale; //-- logic operation >, < ,= return false when at least one argument is Double.NAN //-- to avoid bad NAN value condition is coded as follow : if (!(value >= MIN_VALUE)) { value = MIN_VALUE; } else if (value > MAX_VALUE) { value = MAX_VALUE; } return new float[] { value * 0.9642f, value * 1.0000f, value * 0.8249f }; } /** * Converts a color from the CIEXYZ color space. * * @param RGB The RGB values. */ @Override public float[] fromCIEXYZ(final float[] RGB) { final float[] values = new float[getNumComponents()]; values[visibleBand] = (RGB[0] / 0.9642f + RGB[1] + RGB[2] / 0.8249f) / 3 * scale + offset; return values; } /** * Returns the minimum value for the specified RGB component. */ @Override public float getMinValue(final int component) { return MIN_VALUE * scale + offset; } /** * Returns the maximum value for the specified RGB component. */ @Override public float getMaxValue(final int component) { return MAX_VALUE * scale + offset; } /** * Returns a string representation of this color model. */ @Override public String toString() { return Classes.getShortClassName(this) + '[' + getMinValue(visibleBand) + ", " + getMaxValue(visibleBand) + ']'; } }