/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-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; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.RenderedImage; import java.util.Random; import javax.media.jai.PlanarImage; import javax.media.jai.RenderedImageAdapter; import javax.media.jai.RenderedOp; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.TransformException; import org.geotools.coverage.grid.ViewType; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridCoverageFactory; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.geotools.referencing.operation.transform.IdentityTransform; import org.junit.*; import static org.junit.Assert.*; /** * Tests the {@link SampleTranscoder} implementation. Image adapter depends * heavily on {@link CategoryList}, so this one should be tested first. * * * @source $URL$ * @version $Id$ * @author Martin Desruisseaux (IRD) */ public final class SampleTranscoderTest { /** * Small value for comparaisons. Remind: transformed values are stored in a new image * using the 'float' data type. So we can't expected as much precision than with a * 'double' data type. */ private static final double EPS = 1E-5; /** * Random number generator for this test. */ private static final Random random = new Random(6215962897884256696L); /** * A sample dimension for a band. */ private GridSampleDimension band1; /** * Sets up common objects used for all tests. */ @Before public void setUp() { band1 = new GridSampleDimension("Temperature", new Category[] { new Category("No data", null, 0), new Category("Land", null, 1), new Category("Clouds", null, 2), new Category("Temperature", null, 3, 100, 0.1, 5), new Category("Foo", null, 100, 160, -1, 3), new Category("Tarzan", null, 160) }, null); } /** * Tests the transformation using a random raster with only one band. * * @throws TransformException If an error occured while transforming a value. */ @Test public void testOneBand() throws TransformException { assertTrue(testOneBand(1, 0) instanceof RenderedImageAdapter); assertTrue(testOneBand(.8, 2) instanceof RenderedOp); assertTrue(testOneBand(band1) instanceof RenderedOp); } /** * Tests the transformation using a random raster with only one band. * A sample dimension with only one category will be used. * * @param scale The scale factor. * @param offset The offset value. * @return The transformed image. */ private RenderedImage testOneBand(final double scale, final double offset) throws TransformException { final Category category = new Category("Values", null, 0, 256, scale, offset); return testOneBand(new GridSampleDimension("Measure", new Category[] {category}, null)); } /** * Tests the transformation using a random raster with only one band. * * @param band The sample dimension for the only band. * @return The transformed image. */ private RenderedImage testOneBand(final GridSampleDimension band) throws TransformException { final int SIZE = 64; /* * Constructs a 64x64 image with random values. * Samples values are integer in the range 0..160 inclusive. */ final BufferedImage source = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_BYTE_INDEXED); final DataBufferByte buffer = (DataBufferByte) source.getRaster().getDataBuffer(); final byte[] array = buffer.getData(0); for (int i=0; i<array.length; i++) { array[i] = (byte) random.nextInt(161); } final MathTransform identity = IdentityTransform.create(2); final GridCoverageFactory factory = CoverageFactoryFinder.getGridCoverageFactory(null); GridCoverage2D coverage; coverage = factory.create("Test", source, DefaultGeographicCRS.WGS84, identity, new GridSampleDimension[] {band}, null, null); /* * Apply the operation. The SampleTranscoder class is suppose to transform our * integers into real-world values. Check if the result use floating-points. */ final RenderedImage target = coverage.view(ViewType.GEOPHYSICS).getRenderedImage(); assertSame(target, PlanarImage.wrapRenderedImage(target)); assertEquals(DataBuffer.TYPE_BYTE, source.getSampleModel().getDataType()); if (coverage.getRenderedImage() != target) { assertEquals(DataBuffer.TYPE_FLOAT, target.getSampleModel().getDataType()); } /* * Now, gets the data as an array and compare it with the expected values. */ double[] sourceData = source.getData().getSamples(0, 0, SIZE, SIZE, 0, (double[]) null); double[] targetData = target.getData().getSamples(0, 0, SIZE, SIZE, 0, (double[]) null); band.getSampleToGeophysics().transform(sourceData, 0, sourceData, 0, sourceData.length); CategoryListTest.compare(sourceData, targetData, EPS); /* * Construct a new image with the resulting data, and apply an inverse transformation. * Compare the resulting values with the original data. */ RenderedImage back = PlanarImage.wrapRenderedImage(target).getAsBufferedImage(); coverage = factory.create("Test", back, DefaultGeographicCRS.WGS84, identity, new GridSampleDimension[]{band.geophysics(true)}, null, null); back = coverage.view(ViewType.PACKED).getRenderedImage(); assertEquals(DataBuffer.TYPE_BYTE, back.getSampleModel().getDataType()); sourceData = source.getData().getSamples(0, 0, SIZE, SIZE, 0, (double[]) null); targetData = back.getData().getSamples(0, 0, SIZE, SIZE, 0, (double[]) null); CategoryListTest.compare(sourceData, targetData, 1.0 + EPS); /* * Returns the "geophysics view" of the image. */ return target; } }