001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2007, GeoTools Project Managment Committee (PMC)
005: * (C) 2007, Geomatys
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;
010: * version 2.1 of the License.
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.io;
018:
019: import java.awt.Transparency;
020: import java.awt.image.DataBuffer;
021: import java.awt.color.ColorSpace;
022: import java.awt.image.ColorModel;
023: import java.awt.image.ComponentSampleModel;
024: import javax.media.jai.ComponentSampleModelJAI;
025: import javax.imageio.ImageTypeSpecifier;
026: import java.io.IOException;
027:
028: import org.geotools.resources.image.ComponentColorModelJAI;
029:
030: /**
031: * A factory for building {@linkplain ColorModel color model} suitable for
032: * {@link DataBuffer#TYPE_FLOAT}.
033: *
034: * @since 2.4
035: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/coverageio/src/main/java/org/geotools/image/io/ContinuousPalette.java $
036: * @version $Id: ContinuousPalette.java 26708 2007-08-27 19:42:59Z desruisseaux $
037: * @author Martin Desruisseaux
038: */
039: final class ContinuousPalette extends Palette {
040: /**
041: * Tells if we should use {@link ComponentSampleModelJAI} instead of the more standard
042: * {@link ComponentSampleModel}. There is two problems with models provided with J2SE 1.4:
043: * <p>
044: * <ul>
045: * <li>As of J2SE 1.4.0, {@link ImageTypeSpecifier#createBanded} doesn't accept
046: * {@link DataBuffer#TYPE_FLOAT} and {@link DataBuffer#TYPE_DOUBLE} argument.</li>
047: * <li>As of JAI 1.1, operators don't accept Java2D's {@link java.awt.image.DataBufferFloat}
048: * and {@link java.awt.image.DataBufferDouble}. They require JAI's DataBuffer instead.</li>
049: * </ul>
050: * <p>
051: * This flag is set to {@code true} for J2SE 1.4. It may be
052: * changed to {@code false} with future J2SE and JAI versions.
053: */
054: static final boolean USE_JAI_MODEL = true;
055:
056: /**
057: * The minimal value, inclusive.
058: */
059: protected final float minimum;
060:
061: /**
062: * The maximal value, inclusive.
063: */
064: protected final float maximum;
065:
066: /**
067: * The data type, as a {@link DataBuffer#TYPE_FLOAT} or {@link DataBuffer#TYPE_DOUBLE}
068: * constant.
069: */
070: private final int dataType;
071:
072: /**
073: * Creates a palette with the specified name.
074: *
075: * @param factory The originating factory.
076: * @param name The palette name.
077: * @param minimum The minimal sample value expected.
078: * @param maximum The maximal sample value expected.
079: * @param dataType The data type as a {@link DataBuffer#TYPE_FLOAT}
080: * or {@link DataBuffer#TYPE_DOUBLE} constant.
081: * @param numBands The number of bands (usually 1).
082: * @param visibleBand The band to use for color computations (usually 0).
083: */
084: protected ContinuousPalette(final PaletteFactory factory,
085: final String name, final float minimum,
086: final float maximum, final int dataType,
087: final int numBands, final int visibleBand) {
088: super (factory, name, numBands, visibleBand);
089: this .minimum = minimum;
090: this .maximum = maximum;
091: this .dataType = dataType;
092: }
093:
094: /**
095: * Returns the scale from <cite>normalized values</cite> (values in the range [0..1])
096: * to values in the range of this palette.
097: */
098: //@Override
099: double getScale() {
100: return maximum - minimum;
101: }
102:
103: /**
104: * Returns the offset from <cite>normalized values</cite> (values in the range [0..1])
105: * to values in the range of this palette.
106: */
107: //@Override
108: double getOffset() {
109: return minimum;
110: }
111:
112: /**
113: * Creates a grayscale image type for this palette.
114: * The image type is suitable for floating point values.
115: *
116: * @return A default color space scaled to fit data.
117: * @throws IOException If an I/O operation was needed and failed.
118: */
119: public synchronized ImageTypeSpecifier getImageTypeSpecifier()
120: throws IOException {
121: ImageTypeSpecifier its = queryCache();
122: if (its != null) {
123: return its;
124: }
125: final ColorSpace colorSpace;
126: if (minimum < maximum && !Float.isInfinite(minimum)
127: && !Float.isInfinite(maximum)) {
128: colorSpace = new ScaledColorSpace(numBands, visibleBand,
129: minimum, maximum);
130: } else {
131: colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
132: }
133: final int[] bankIndices = new int[numBands];
134: final int[] bandOffsets = new int[numBands];
135: for (int i = numBands; --i >= 0;) {
136: bankIndices[i] = i;
137: }
138: if (USE_JAI_MODEL) {
139: final ColorModel cm = new ComponentColorModelJAI(
140: colorSpace, null, false, false,
141: Transparency.OPAQUE, dataType);
142: its = new ImageTypeSpecifier(cm,
143: new ComponentSampleModelJAI(dataType, 1, 1, 1, 1,
144: bankIndices, bandOffsets));
145: } else {
146: its = ImageTypeSpecifier.createBanded(colorSpace,
147: bankIndices, bandOffsets, dataType, false, false);
148: }
149: cache(its);
150: return its;
151: }
152:
153: /**
154: * Returns a hash value for this palette.
155: */
156: //@Override
157: public int hashCode() {
158: return 37
159: * (37 * (37 * super .hashCode() + Float
160: .floatToIntBits(minimum)) + Float
161: .floatToIntBits(maximum)) + dataType;
162: }
163:
164: /**
165: * Compares this palette with the specified object for equality.
166: */
167: //@Override
168: public boolean equals(final Object object) {
169: if (object == this ) {
170: return true;
171: }
172: if (super .equals(object)) {
173: final ContinuousPalette that = (ContinuousPalette) object;
174: return Float.floatToIntBits(this .minimum) == Float
175: .floatToIntBits(that.minimum)
176: && Float.floatToIntBits(this .maximum) == Float
177: .floatToIntBits(that.maximum)
178: && this .dataType == that.dataType;
179: }
180: return false;
181: }
182:
183: /**
184: * Returns a string representation of this palette. Used for debugging purpose only.
185: */
186: //@Override
187: public String toString() {
188: return name + " [" + minimum + " ... " + maximum + ']';
189: }
190: }
|