/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 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.io.impl.range; import java.awt.color.ColorSpace; import java.awt.image.ColorModel; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.measure.quantity.Dimensionless; import javax.measure.unit.Unit; import javax.media.jai.IHSColorSpace; import org.geotools.coverage.TypeMap; import org.geotools.coverage.io.range.Axis; import org.geotools.feature.NameImpl; import org.geotools.util.SimpleInternationalString; import org.opengis.coverage.ColorInterpretation; import org.opengis.coverage.SampleDimension; import org.opengis.feature.type.Name; import org.opengis.referencing.crs.SingleCRS; import org.opengis.util.InternationalString; /** * Implementation of {@link Axis} for multibands images. * * <p> * This implementation of Axis can be seen as a stub implementation since in * this case we do not really have an {@link Axis} for this kind of data, or * rather we have an axis that just represents an ordinal or a certain set of . * * @author Simone Giannecchini, GeoSolutions * @todo add convenience constructor based on {@link SampleDimension} and or * {@link SampleModel} * * * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/unsupported/coverage-experiment/coverage-api/src/main/java/org/geotools/coverage/io/impl/range/DimensionlessAxis.java $ */ @SuppressWarnings("deprecation") public class DimensionlessAxis implements Axis<String,Dimensionless> { /** * Textual representation for the various bands in this {@link Axis}. */ private String[] bandsKeys = null; private Name name = null; private InternationalString description; /** * Helper classes for creating {@link DimensionlessAxis} for the most common color models' bands. * * <p> * Suypported colorspaces incluse RGBA, GRAY, GRAYA, HSV,HLS, LAB, LUV, IHS, CI_XYZ, CMY(K). * Notice that RGB is not handled here but through a wavelength axis. * * <p> * This method returns null if an unsupported {@link ColorModel} is provided. * * @param raster a {@link RenderedImage} implementation from which to extract needed info, usually {@link ColorModel} and {@link SampleModel}. * @return a {@link DimensionlessAxis} or null if an unsupported {@link ColorModel} is provided. */ public static DimensionlessAxis createFromRenderedImage(final RenderedImage raster){ if(raster==null) throw new IllegalArgumentException("Provided null input image"); final ColorModel cm= raster.getColorModel(); if(cm==null) throw new IllegalArgumentException("Provided input image with null color model"); final SampleModel sm= raster.getSampleModel(); if(sm==null) throw new IllegalArgumentException("Provided input image with null SampleModel"); //get the color interpretation for the three bands final ColorInterpretation firstBandCI = TypeMap.getColorInterpretation(cm, 0); // CMY - CMYK if(firstBandCI==ColorInterpretation.CYAN_BAND) { if(sm.getNumBands()==3) return new DimensionlessAxis( Arrays.asList("CYAN","MAGENTA","YELLOW"), new NameImpl("CMY-AXIS"), new SimpleInternationalString("Axis for CMY bands")); else return new DimensionlessAxis( Arrays.asList("CYAN","MAGENTA","YELLOW","BLACK"), new NameImpl("CMYK-AXIS"), new SimpleInternationalString("Axis for CMYK bands")); } // HSV if(firstBandCI==ColorInterpretation.HUE_BAND) { return new DimensionlessAxis( Arrays.asList("HUE","SATURATION","VALUE"), new NameImpl("HSV-AXIS"), new SimpleInternationalString("Axis for HSV bands")); } //RGBA if(firstBandCI==ColorInterpretation.RED_BAND) { return new DimensionlessAxis( Arrays.asList("RED","GREEN","BLUE","ALPHA"), new NameImpl("RGBA-AXIS"), new SimpleInternationalString("Axis for RGBA bands")); } //PALETTE if(firstBandCI==ColorInterpretation.PALETTE_INDEX) return new DimensionlessAxis( Arrays.asList("PALETTE_INDEX"), new NameImpl("PALETTE_INDEX-AXIS"), new SimpleInternationalString("Axis for PALETTE INDEX bands")); // GRAY, GRAY+ALPHA if(firstBandCI==ColorInterpretation.GRAY_INDEX) { if(sm.getNumBands()==2) return new DimensionlessAxis( Arrays.asList("GRAY","ALPHA"), new NameImpl("GA-AXIS"), new SimpleInternationalString("Axis for GRAY-ALPHA bands")); else return new DimensionlessAxis( Arrays.asList("GRAY"), new NameImpl("GRAY-AXIS"), new SimpleInternationalString("Axis for GRAY bands")); } final ColorSpace cs = cm.getColorSpace(); //IHS if(cs instanceof IHSColorSpace) return new DimensionlessAxis( Arrays.asList("INTENSITY","HUE","SATURATION"), new NameImpl("IHS-AXIS"), new SimpleInternationalString("Axis for IHS bands")); //YCbCr, LUV, LAB, HLS, IEXYZ switch(cs.getType()){ case ColorSpace.TYPE_YCbCr: return new DimensionlessAxis( Arrays.asList("LUMA","CHROMA-A","CHROMA-B"), new NameImpl("YCbCr-AXIS"), new SimpleInternationalString("Axis for YCbCr bands")); case ColorSpace.TYPE_Luv: return new DimensionlessAxis( Arrays.asList("LIGHTNESS","U","V"), new NameImpl("LUV-AXIS"), new SimpleInternationalString("Axis for LUV bands")); case ColorSpace.TYPE_Lab: return new DimensionlessAxis( Arrays.asList("LIGHTNESS","A","B"), new NameImpl("LAB-AXIS"), new SimpleInternationalString("Axis for LAB bands")); case ColorSpace.TYPE_HLS: return new DimensionlessAxis( Arrays.asList("HUE","LIGHTNESS","SATURATION"), new NameImpl("HLS-AXIS"), new SimpleInternationalString("Axis for HLS bands")); case ColorSpace.CS_CIEXYZ: return new DimensionlessAxis( Arrays.asList("X","Y","Z"), new NameImpl("XYZ-AXIS"), new SimpleInternationalString("Axis for XYZ bands")); default: return null; } } /** * */ public DimensionlessAxis(final int bandsNumber, final Name name, final InternationalString description) { String[] bandsKeys = new String[bandsNumber]; for (int i = 0; i < bandsNumber; i++) bandsKeys[i] = Integer.toString(i); init(bandsKeys, name, description); } /** * */ public DimensionlessAxis(final String[] bands, final Name name, final InternationalString description) { init(bands, name, description); } /** * */ public DimensionlessAxis(final List<String> bandsKeys, final Name name, final InternationalString description) { if (bandsKeys==null || bandsKeys.isEmpty()) throw new IllegalArgumentException("Specified band keys list is invalid"); init((String[])bandsKeys.toArray(new String[bandsKeys.size()]), name, description); } private void init(String[] bandsKeys, final Name name, final InternationalString description) { this.name = name; this.description = description; this.bandsKeys = bandsKeys; } /** * @see org.geotools.coverage.io.range.Axis#getCoordinateReferenceSystem() */ public SingleCRS getCoordinateReferenceSystem() { return null; } /** * @see org.geotools.coverage.io.range.Axis#getDescription() */ public InternationalString getDescription() { return this.description; } /** * @see org.geotools.coverage.io.range.Axis#getKey(int) */ public BandIndexMeasure getKey(int keyIndex) { return new BandIndexMeasure(keyIndex, this.bandsKeys[keyIndex]); } /** * @see org.geotools.coverage.io.range.Axis#getKeys() */ public List<BandIndexMeasure> getKeys() { List<BandIndexMeasure> list = new ArrayList<BandIndexMeasure>( this.bandsKeys.length); int i = 0; for (String band : this.bandsKeys) list.add(new BandIndexMeasure(i++, band)); return list; } /** * @see org.geotools.coverage.io.range.Axis#getName() */ public Name getName() { return this.name; } /** * @see org.geotools.coverage.io.range.Axis#getNumKeys() */ public int getNumKeys() { return bandsKeys.length; } /** * @see org.geotools.coverage.io.range.Axis#getUnitOfMeasure() */ public Unit<Dimensionless> getUnitOfMeasure() { return Unit.ONE; } }