sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] branch geoapi-4.0 updated: Add tests for BandedSampleConverter.
Date Sat, 04 Jan 2020 10:59:00 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new ac2fc3e  Add tests for BandedSampleConverter.
ac2fc3e is described below

commit ac2fc3efa06a5964ec90db43eec479b016150aab
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Sat Jan 4 11:57:35 2020 +0100

    Add tests for BandedSampleConverter.
---
 .../java/org/apache/sis/image/PlanarImage.java     |   5 +-
 .../main/java/org/apache/sis/image/TileCache.java  |   2 +-
 .../coverage/j2d/BandedSampleConverter.java        |  44 +++++-
 .../sis/internal/coverage/j2d/ImageLayout.java     |   2 +-
 .../sis/internal/coverage/j2d/Transferer.java      |  24 +++-
 .../java/org/apache/sis/image/PlanarImageTest.java |  17 +--
 .../coverage/j2d/BandedSampleConverterTest.java    | 158 +++++++++++++++++++++
 .../java/org/apache/sis/test/FeatureAssert.java    |  45 +++++-
 .../apache/sis/test/suite/FeatureTestSuite.java    |   1 +
 9 files changed, 268 insertions(+), 30 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/PlanarImage.java b/core/sis-feature/src/main/java/org/apache/sis/image/PlanarImage.java
index e8e51dc..494009d 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/PlanarImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/PlanarImage.java
@@ -248,7 +248,10 @@ public abstract class PlanarImage implements RenderedImage {
      * This method does not verify argument validity.
      */
     private WritableRaster createWritableRaster(final Rectangle aoi) {
-        final SampleModel sm = getSampleModel().createCompatibleSampleModel(aoi.width, aoi.height);
+        SampleModel sm = getSampleModel();
+        if (sm.getWidth() != aoi.width || sm.getHeight() != aoi.height) {
+            sm = sm.createCompatibleSampleModel(aoi.width, aoi.height);
+        }
         return Raster.createWritableRaster(sm, aoi.getLocation());
     }
 
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/TileCache.java b/core/sis-feature/src/main/java/org/apache/sis/image/TileCache.java
index e024556..7562101 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/TileCache.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/TileCache.java
@@ -67,7 +67,7 @@ final class TileCache extends Cache<TileCache.Key, Raster> {
         } catch (IllegalArgumentException e) {
             numBits *= Integer.SIZE;                // Conservatively assume 32 bits values.
         }
-        return (int) Math.min(Integer.MIN_VALUE, numBits / Byte.SIZE);
+        return (int) Math.min(Integer.MAX_VALUE, numBits / Byte.SIZE);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/BandedSampleConverter.java
b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/BandedSampleConverter.java
index a94da76..e5c4a1d 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/BandedSampleConverter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/BandedSampleConverter.java
@@ -21,9 +21,11 @@ import java.awt.image.Raster;
 import java.awt.image.WritableRaster;
 import java.awt.image.RenderedImage;
 import java.awt.image.BandedSampleModel;
+import java.awt.image.ColorModel;
 import org.opengis.referencing.operation.MathTransform1D;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.image.ComputedImage;
+import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Workaround;
 
 
@@ -50,7 +52,7 @@ import org.apache.sis.util.Workaround;
  * @since   1.1
  * @module
  */
-public abstract class BandedSampleConverter extends ComputedImage {
+public final class BandedSampleConverter extends ComputedImage {
     /**
      * The transfer functions to apply on each band of the source image.
      */
@@ -58,6 +60,8 @@ public abstract class BandedSampleConverter extends ComputedImage {
 
     /**
      * Creates a new image of the given data type which will compute values using the given
converters.
+     * The number of bands is the length of the {@code converters} array, which must be greater
than 0
+     * and not greater than the number of bands in the source image.
      *
      * @param  source      the image for which to convert sample values.
      * @param  layout      object to use for computing tile size, or {@code null} for the
default.
@@ -79,6 +83,8 @@ public abstract class BandedSampleConverter extends ComputedImage {
     private static BandedSampleModel createSampleModel(final int targetType,
             final int numBands, ImageLayout layout, final RenderedImage source)
     {
+        ArgumentChecks.ensureNonNull("source", source);
+        ArgumentChecks.ensureSizeBetween("converters", 1, source.getSampleModel().getNumBands(),
numBands);
         if (layout == null) {
             layout = ImageLayout.DEFAULT;
         }
@@ -87,6 +93,38 @@ public abstract class BandedSampleConverter extends ComputedImage {
     }
 
     /**
+     * Returns the color model associated with all rasters of this image.
+     *
+     * @return the color model of this image, or {@code null} if none.
+     */
+    @Override
+    public ColorModel getColorModel() {
+        return null;
+    }
+
+    /**
+     * Returns the width (in pixels) of this image.
+     * This is the the same value than the source image (not necessarily zero).
+     *
+     * @return the width (number of columns) of this image.
+     */
+    @Override
+    public int getWidth() {
+        return getSource(0).getWidth();
+    }
+
+    /**
+     * Returns the height (in pixels) of this image.
+     * This is the the same value than the source image (not necessarily zero).
+     *
+     * @return the height (number of rows) of this image.
+     */
+    @Override
+    public int getHeight() {
+        return getSource(0).getHeight();
+    }
+
+    /**
      * Returns the minimum <var>x</var> coordinate (inclusive) of this image.
      * This is the the same value than the source image (not necessarily zero).
      *
@@ -140,10 +178,8 @@ public abstract class BandedSampleConverter extends ComputedImage {
      */
     @Override
     protected Raster computeTile(final int tileX, final int tileY) throws TransformException
{
-        final Raster         source = getSource(0).getTile(tileX, tileY);
         final WritableRaster target = createTile(tileX, tileY);
-        final Transferer   transfer = Transferer.suggest(source, target);
-        transfer.compute(converters);
+        Transferer.create(getSource(0), target).compute(converters);
         return target;
     }
 }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageLayout.java
b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageLayout.java
index e63d523..b50aa9a 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageLayout.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageLayout.java
@@ -186,7 +186,7 @@ public class ImageLayout {
         boolean pt = allowPartialTiles;
         if (pt) {
             final ColorModel cm = image.getColorModel();
-            if (cm != null) {
+            if (pt = (cm != null)) {
                 if (cm instanceof IndexColorModel) {
                     pt = ((IndexColorModel) cm).getTransparentPixel() == 0;
                 } else {
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/Transferer.java
b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/Transferer.java
index 8ccda79..26adda8 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/Transferer.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/Transferer.java
@@ -24,6 +24,7 @@ import java.awt.image.ComponentSampleModel;
 import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferFloat;
 import java.awt.image.DataBufferDouble;
+import java.awt.image.RenderedImage;
 import org.apache.sis.internal.util.Numerics;
 import org.opengis.referencing.operation.MathTransform1D;
 import org.opengis.referencing.operation.TransformException;
@@ -489,15 +490,32 @@ abstract class Transferer {
 
 
     /**
+     * Suggests a strategy for transferring data from the given source image to the given
target.
+     * This method assumes that the source image uses the same pixel coordinate system than
the
+     * target raster (i.e. that pixels at the same coordinates are at the same location on
Earth).
+     * It also assumes that the target tile is fully included in the bounds of a single source
tile.
+     * That later condition is met if the target grid tiles has been created by {@link ImageLayout}.
+     *
+     * @param  source  image from which to read sample values.
+     * @param  target  image tile where to write sample values after processing.
+     * @return object to use for applying the operation.
+     */
+    static Transferer create(final RenderedImage source, final WritableRaster target) {
+        int tileX = Math.floorDiv((target.getMinX() - source.getTileGridXOffset()), source.getTileWidth());
+        int tileY = Math.floorDiv((target.getMinY() - source.getTileGridYOffset()), source.getTileHeight());
+        return create(source.getTile(tileX, tileY), target);
+    }
+
+    /**
      * Suggests a strategy for transferring data from the given source to the given target.
-     * Some operation can be applied on sample values during the transfer for producing a
-     * computed image.
+     * The operation to apply on sample values during transfer is specified later, during
+     * the call to {@link #compute(MathTransform1D[])}.
      *
      * @param  source  image tile from which to read sample values.
      * @param  target  image tile where to write sample values after processing.
      * @return object to use for applying the operation.
      */
-    static Transferer suggest(final Raster source, final WritableRaster target) {
+    static Transferer create(final Raster source, final WritableRaster target) {
         switch (ImageUtilities.getDataType(target)) {
             case DataBuffer.TYPE_DOUBLE: {
                 if (isDirect(target)) {
diff --git a/core/sis-feature/src/test/java/org/apache/sis/image/PlanarImageTest.java b/core/sis-feature/src/test/java/org/apache/sis/image/PlanarImageTest.java
index 0ac4572..3f82965 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/image/PlanarImageTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/image/PlanarImageTest.java
@@ -43,21 +43,10 @@ public final strictfp class PlanarImageTest extends TestCase {
     private static final int TILE_WIDTH = 3, TILE_HEIGHT = 2;
 
     /**
-     * Random number generator for this test.
+     * Creates a rendered image with arbitrary tiles.
      */
-    private final Random random;
-
-    /**
-     * Creates a new test.
-     */
-    public PlanarImageTest() {
-        random = TestUtilities.createRandomNumberGenerator();
-    }
-
-    /**
-     * Creates a rendered image which arbitrary tiles.
-     */
-    private PlanarImage createImage() {
+    private static PlanarImage createImage() {
+        final Random random = TestUtilities.createRandomNumberGenerator();
         final TiledImageMock image = new TiledImageMock(
                 DataBuffer.TYPE_USHORT, 1,      // dataType and numBands
                 random.nextInt(20) - 10,        // minX
diff --git a/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/BandedSampleConverterTest.java
b/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/BandedSampleConverterTest.java
new file mode 100644
index 0000000..c2be7db
--- /dev/null
+++ b/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/BandedSampleConverterTest.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.coverage.j2d;
+
+import java.util.Random;
+import java.awt.image.DataBuffer;
+import org.opengis.referencing.operation.MathTransform1D;
+import org.apache.sis.referencing.operation.transform.MathTransforms;
+import org.apache.sis.image.TiledImageMock;
+import org.apache.sis.test.TestUtilities;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.apache.sis.test.FeatureAssert.assertValuesEqual;
+
+
+/**
+ * Tests {@link BandedSampleConverter}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.1
+ * @since   1.1
+ * @module
+ */
+public final strictfp class BandedSampleConverterTest extends TestCase {
+    /**
+     * Size of tiles in this test. The width should be different than the height
+     * for increasing the chances to detect errors in index calculations.
+     */
+    private static final int TILE_WIDTH = 4, TILE_HEIGHT = 3;
+
+    /**
+     * The image to test.
+     */
+    private BandedSampleConverter image;
+
+    /**
+     * Creates a converted image with arbitrary tiles.
+     * The created image is assigned to the {@link #image} field.
+     *
+     * @param  sourceType  source data type as one of the {@link DataBuffer} constants.
+     * @param  targetType  target data type as one of the {@link DataBuffer} constants.
+     * @param  scale       the scale factor of the conversion to apply.
+     */
+    private void createImage(final int sourceType, final int targetType, final double scale)
{
+        final Random random = TestUtilities.createRandomNumberGenerator();
+        final TiledImageMock source = new TiledImageMock(
+                sourceType, 1,
+                random.nextInt(20) - 10,        // minX
+                random.nextInt(20) - 10,        // minY
+                TILE_WIDTH  * 3,                // width
+                TILE_HEIGHT * 2,                // height
+                TILE_WIDTH,
+                TILE_HEIGHT,
+                random.nextInt(20) - 10,        // minTileX
+                random.nextInt(20) - 10);       // minTileY
+        source.validate();
+        source.initializeAllTiles(0);
+        image = new BandedSampleConverter(source, null, targetType,
+                (MathTransform1D) MathTransforms.linear(scale, 0));
+    }
+
+    /**
+     * Asserts that {@link #image} values are equal to the source values divided by 10.
+     */
+    private void assertValuesDivided() {
+        assertValuesEqual(image.getData(), 0, new float[][] {
+            { 10.0f,  10.1f,  10.2f,  10.3f  ,   20.0f,  20.1f,  20.2f,  20.3f  ,   30.0f,
 30.1f,  30.2f,  30.3f},
+            { 11.0f,  11.1f,  11.2f,  11.3f  ,   21.0f,  21.1f,  21.2f,  21.3f  ,   31.0f,
 31.1f,  31.2f,  31.3f},
+            { 12.0f,  12.1f,  12.2f,  12.3f  ,   22.0f,  22.1f,  22.2f,  22.3f  ,   32.0f,
 32.1f,  32.2f,  32.3f},
+            { 40.0f,  40.1f,  40.2f,  40.3f  ,   50.0f,  50.1f,  50.2f,  50.3f  ,   60.0f,
 60.1f,  60.2f,  60.3f},
+            { 41.0f,  41.1f,  41.2f,  41.3f  ,   51.0f,  51.1f,  51.2f,  51.3f  ,   61.0f,
 61.1f,  61.2f,  61.3f},
+            { 42.0f,  42.1f,  42.2f,  42.3f  ,   52.0f,  52.1f,  52.2f,  52.3f  ,   62.0f,
 62.1f,  62.2f,  62.3f}
+        });
+    }
+
+    /**
+     * Asserts that {@link #image} values are equal to the source values multiplied by 10.
+     */
+    private void assertValuesMultiplied() {
+        assertValuesEqual(image.getData(), 0, new int[][] {
+            { 1000,  1010,  1020,  1030  ,   2000,  2010,  2020,  2030  ,   3000,  3010,
 3020,  3030},
+            { 1100,  1110,  1120,  1130  ,   2100,  2110,  2120,  2130  ,   3100,  3110,
 3120,  3130},
+            { 1200,  1210,  1220,  1230  ,   2200,  2210,  2220,  2230  ,   3200,  3210,
 3220,  3230},
+            { 4000,  4010,  4020,  4030  ,   5000,  5010,  5020,  5030  ,   6000,  6010,
 6020,  6030},
+            { 4100,  4110,  4120,  4130  ,   5100,  5110,  5120,  5130  ,   6100,  6110,
 6120,  6130},
+            { 4200,  4210,  4220,  4230  ,   5200,  5210,  5220,  5230  ,   6200,  6210,
 6220,  6230}
+        });
+    }
+
+    /**
+     * Tests conversion from unsigned integers to floating point values.
+     */
+    @Test
+    public void testUShortToFloat() {
+        createImage(DataBuffer.TYPE_USHORT, DataBuffer.TYPE_FLOAT, 0.1);
+        assertValuesDivided();
+    }
+
+    /**
+     * Tests conversion from floating point values to unsigned integers.
+     */
+    @Test
+    public void testFloatToUShort() {
+        createImage(DataBuffer.TYPE_FLOAT, DataBuffer.TYPE_USHORT, 10);
+        assertValuesMultiplied();
+    }
+
+    /**
+     * Tests conversion from floating point values to other floating point values.
+     */
+    @Test
+    public void testFloatToFloat() {
+        createImage(DataBuffer.TYPE_FLOAT, DataBuffer.TYPE_FLOAT, 0.1);
+        assertValuesDivided();
+    }
+
+    /**
+     * Tests conversion from unsigned integer values to integers.
+     */
+    @Test
+    public void testUShortToUShort() {
+        createImage(DataBuffer.TYPE_USHORT, DataBuffer.TYPE_USHORT, 10);
+        assertValuesMultiplied();
+    }
+
+    /**
+     * Tests conversion from signed integer values to other integers.
+     */
+    @Test
+    public void testShortToInteger() {
+        createImage(DataBuffer.TYPE_SHORT, DataBuffer.TYPE_INT, 10);
+        assertValuesMultiplied();
+    }
+
+    /**
+     * Tests conversion from floating point values to signed integers.
+     */
+    @Test
+    public void testDoubleToInteger() {
+        createImage(DataBuffer.TYPE_DOUBLE, DataBuffer.TYPE_INT, 10);
+        assertValuesMultiplied();
+    }
+}
diff --git a/core/sis-feature/src/test/java/org/apache/sis/test/FeatureAssert.java b/core/sis-feature/src/test/java/org/apache/sis/test/FeatureAssert.java
index 3387d3a..c08b455 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/test/FeatureAssert.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/test/FeatureAssert.java
@@ -38,7 +38,7 @@ public strictfp class FeatureAssert extends ReferencingAssert {
     }
 
     /**
-     * Verifies that sample values in the given raster are equal to the expected values.
+     * Verifies that sample values in the given raster are equal to the expected integer
values.
      *
      * @param  raster    the raster to verify.
      * @param  band      the band to verify.
@@ -54,14 +54,47 @@ public strictfp class FeatureAssert extends ReferencingAssert {
             final int y = minY + j;
             for (int i=0; i<row.length; i++) {
                 final int x = minX + i;
-                final int actual = raster.getSample(x, y, band);
+                final int a = raster.getSample(x, y, band);
                 final int e = row[i];
-                if (actual != e) {
-                    fail("Mismatched sample value at image coordinates (" + x + ", " + y
+ ") "
-                            + "— matrix indices (" + i + ", " + j + ") band " + band
-                            + ": expected " + e + " but found " + actual);
+                if (a != e) {
+                    fail(mismatchedSampleValue(x, y, i, j, band, e, a));
                 }
             }
         }
     }
+
+    /**
+     * Verifies that sample values in the given raster are equal to the expected floating-point
values.
+     *
+     * @param  raster    the raster to verify.
+     * @param  band      the band to verify.
+     * @param  expected  the expected sample values.
+     */
+    public static void assertValuesEqual(final Raster raster, final int band, final float[][]
expected) {
+        final int minX = raster.getMinX();
+        final int minY = raster.getMinY();
+        assertEquals("Height", expected.length, raster.getHeight());
+        for (int j=0; j<expected.length; j++) {
+            final float[] row = expected[j];
+            assertEquals("Width", row.length, raster.getWidth());
+            final int y = minY + j;
+            for (int i=0; i<row.length; i++) {
+                final int   x = minX + i;
+                final float a = raster.getSampleFloat(x, y, band);
+                final float e = row[i];
+                if (Float.floatToRawIntBits(a) != Float.floatToRawIntBits(e)) {
+                    fail(mismatchedSampleValue(x, y, i, j, band, e, a));
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the error message for a test failure in an {@code assertValuesEqual(…)}
method.
+     */
+    private static String mismatchedSampleValue(int x, int y, int i, int j, int band, Number
expected, Number actual) {
+        return "Mismatched sample value at image coordinates (" + x + ", " + y + ") "
+                + "— matrix indices (" + i + ", " + j + ") band " + band
+                + ": expected " + expected + " but found " + actual;
+    }
 }
diff --git a/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
b/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
index d81d017..4e6ff8a 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
@@ -90,6 +90,7 @@ import org.junit.runners.Suite;
     org.apache.sis.coverage.grid.FractionalGridCoordinatesTest.class,
     org.apache.sis.coverage.grid.ReshapedImageTest.class,
     org.apache.sis.coverage.grid.GridCoverage2DTest.class,
+    org.apache.sis.internal.coverage.j2d.BandedSampleConverterTest.class,
     org.apache.sis.internal.coverage.j2d.BufferedGridCoverageTest.class
 })
 public final strictfp class FeatureTestSuite extends TestSuite {


Mime
View raw message