/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2010-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2010-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.coverage.io; import java.util.Objects; import java.io.IOException; import java.awt.image.ColorModel; import java.io.File; import java.nio.charset.Charset; import java.util.Locale; import javax.imageio.ImageTypeSpecifier; import org.geotoolkit.coverage.GridSampleDimension; import static org.apache.sis.util.collection.Containers.isNullOrEmpty; import org.geotoolkit.image.palette.Palette; import org.geotoolkit.image.palette.PaletteFactory; /** * A palette which build its {@link IndexColorModel} from a {@link GridSampleDimension}. * Instances of this class are created only by the {@link #FACTORY} singleton. The factory * needs a {@link GridSampleDimension} argument, which is passed in the {@link #BANDS} * static variable. This is ugly, but there is no API in the current {@link PaletteFactory} * class for building a palette from a sample dimension. * * {@note The raison why <code>PaletteFactory</code> has no API for sample dimensions is that * <code>PaletteFactory</code> is all about creating palettes from files of RGB codes, * and intentionally avoid the coverage API since its package is about image I/O. On * the contrary, this <code>SampleDimensionPalette</code> does not read any file, so * it is a bit a departure compared to the usual factory. In addition, creating the * required <code>GridSampleDimension</code> objects require a bit of non-trivial code * (provided in <code>ImageCoverageReader</code>) which is out of scope of Image I/O.} * * @author Martin Desruisseaux (Geomatys) * @version 3.19 * * @since 3.11 * @module */ final class SampleDimensionPalette extends Palette { /** * The singleton factory. We override only the method which is known to be invoked by * {@link org.geotoolkit.image.io.SpatialImageReader#getImageType}. However before to * invoke any factory method, the {@link #BANDS} field must be set. */ static final PaletteFactory FACTORY = new PaletteFactory(null, PaletteFactory.class, new File("colors"), ".pal", Charset.forName("ISO-8859-1"), Locale.US) { @Override public Palette getPalette(final String name, final int lower, final int upper, final int size, final int numBands, final int visibleBand) { final GridSampleDimension[] bands = BANDS.get(); final GridSampleDimension band = bands[Math.min(visibleBand, bands.length-1)]; if (isNullOrEmpty(band.getCategories())) { return super.getPalette(name, lower, upper, size, numBands, visibleBand); } Palette palette = new SampleDimensionPalette(this, name, band, numBands, visibleBand); palette = palettes.unique(palette); return palette; } }; /** * Workaround for passing the bands argument to {@code FACTORY.getPalette(...)}. */ static final ThreadLocal<GridSampleDimension[]> BANDS = new ThreadLocal<>(); /** * The sample dimension to use for creating the color model. */ private final GridSampleDimension band; /** * Creates a new palette for the given band. * * @param factory The originating factory. * @param name The palette name (actually ignored). */ private SampleDimensionPalette(final PaletteFactory factory, final String name, final GridSampleDimension band, final int numBands, final int visibleBand) { super(factory, name, numBands, visibleBand); this.band = band; } /** * Creates a new image type specifier with a color model inferred from the sample * dimension given to the constructor. */ @Override protected ImageTypeSpecifier createImageTypeSpecifier() throws IOException { final ColorModel cm = band.getColorModel(visibleBand, numBands); // 'cm' should not be null because the above factory checked // that the GridSampleDimension has at least one category. return new ImageTypeSpecifier(cm, cm.createCompatibleSampleModel(1, 1)); } /** * Returns a hash value for this palette. */ @Override public int hashCode() { return super.hashCode() + 31*band.hashCode(); } /** * Compares this palette with the specified object for equality. */ @Override public boolean equals(final Object object) { if (object == this) { return true; } if (super.equals(object)) { final SampleDimensionPalette that = (SampleDimensionPalette) object; return Objects.equals(band, that.band); } return false; } /** * Returns a string representation of this palette. Used for debugging purpose only. */ @Override public String toString() { return "Palette[" + band.getDescription() + ']'; } }