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 <[email protected]>
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 {