You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2019/12/29 22:40:38 UTC
[sis] 02/03: Add more tests for ReshapedImage and fix a few bugs in
this process.
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
commit a32a606dbf8f96f54f619a0abeae43c0b946d789
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Sun Dec 29 22:55:45 2019 +0100
Add more tests for ReshapedImage and fix a few bugs in this process.
---
.../apache/sis/coverage/grid/ReshapedImage.java | 31 +++-
.../sis/coverage/grid/ReshapedImageTest.java | 171 +++++++++++++++++++--
.../sis/internal/coverage/j2d/PlanarImageTest.java | 2 +-
.../apache/sis/test/suite/FeatureTestSuite.java | 6 +-
4 files changed, 183 insertions(+), 27 deletions(-)
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ReshapedImage.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ReshapedImage.java
index 7fd6ab3..bb4fe6c 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ReshapedImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ReshapedImage.java
@@ -24,6 +24,7 @@ import java.awt.image.SampleModel;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import org.apache.sis.internal.coverage.j2d.PlanarImage;
+import org.apache.sis.util.ArgumentChecks;
import static java.lang.Math.min;
import static java.lang.Math.max;
@@ -131,8 +132,8 @@ final class ReshapedImage extends PlanarImage {
minY = toIntExact(y);
width = toIntExact(min(upperX, (maxTX + 1) * tw + xo) - sx);
height = toIntExact(min(upperY, (maxTY + 1) * th + yo) - sy);
- offsetX = toIntExact(x - lowerX);
- offsetY = toIntExact(y - lowerY);
+ offsetX = toIntExact(x - sx);
+ offsetY = toIntExact(y - sy);
minTileX = toIntExact(minTX);
minTileY = toIntExact(minTY);
}
@@ -224,7 +225,15 @@ final class ReshapedImage extends PlanarImage {
*/
@Override
public Raster getData() {
- return offset(image.getData());
+ /*
+ * If this image contains all data, delegate to RenderedImage.getData()
+ * in case some implementations provide an optimized method. Otherwise
+ * ask only the sub-region covered by this image.
+ */
+ if (width >= image.getWidth() && height >= image.getHeight()) {
+ return offset(image.getData());
+ }
+ return copyData(new Rectangle(minX, minY, width, height));
}
/**
@@ -235,8 +244,16 @@ final class ReshapedImage extends PlanarImage {
* @return a copy of this image in the given area of interest.
*/
@Override
- public Raster getData(Rectangle aoi) {
- aoi = new Rectangle(aoi);
+ public Raster getData(final Rectangle aoi) {
+ ArgumentChecks.ensureNonNull("aoi", aoi);
+ return copyData(new Rectangle(aoi));
+ }
+
+ /**
+ * Implementation of {@link #getData(Rectangle)}. This implementation will modify the given {@code aoi}
+ * argument. If that argument was supplied by user, then it should first be copied by the caller.
+ */
+ private Raster copyData(final Rectangle aoi) {
aoi.x = subtractExact(aoi.x, offsetX); // Convert coordinate from this image to wrapped image.
aoi.y = subtractExact(aoi.y, offsetY);
final Raster data = image.getData(aoi);
@@ -276,8 +293,8 @@ final class ReshapedImage extends PlanarImage {
public String verify() {
final String error = super.verify();
if (error == null) {
- if (getMinX() != image.getMinX() + offsetX) return "minX";
- if (getMinY() != image.getMinY() + offsetY) return "minY";
+ if (getMinX() != image.getMinX() + (minTileX - image.getMinTileX()) * getTileWidth() + offsetX) return "minX";
+ if (getMinY() != image.getMinY() + (minTileY - image.getMinTileY()) * getTileHeight() + offsetY) return "minY";
if (getTileGridXOffset() != super.getTileGridXOffset()) return "tileGridXOffset";
if (getTileGridYOffset() != super.getTileGridYOffset()) return "tileGridYOffset";
}
diff --git a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/ReshapedImageTest.java b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/ReshapedImageTest.java
index de15b71..6155bf9 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/ReshapedImageTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/ReshapedImageTest.java
@@ -16,8 +16,12 @@
*/
package org.apache.sis.coverage.grid;
+import java.util.Random;
+import java.awt.image.DataBuffer;
import java.awt.image.BufferedImage;
-import java.awt.image.WritableRaster;
+import org.apache.sis.image.TiledImageMock;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestUtilities;
import org.apache.sis.test.TestCase;
import org.junit.Test;
@@ -34,25 +38,160 @@ import static org.apache.sis.test.FeatureAssert.assertValuesEqual;
* @since 1.1
* @module
*/
+@DependsOn(org.apache.sis.internal.coverage.j2d.PlanarImageTest.class)
public final strictfp class ReshapedImageTest extends TestCase {
/**
- * Tests with a request starting on the left and on top of data.
+ * Size of tiles used in this test.
+ */
+ private static final int TILE_WIDTH = 3, TILE_HEIGHT = 2;
+
+ /**
+ * Expected coordinates of image upper-left corner. Default value is (0,0).
+ */
+ private int minX, minY;
+
+ /**
+ * Expected index of first tile. Default value is (0,0).
+ */
+ private int minTileX, minTileY;
+
+ /**
+ * Expected number of tiles. Shall be initialized by test method
+ * before to invoke {@link #verifyLayout(ReshapedImage)}.
+ */
+ private int numXTiles, numYTiles;
+
+ /**
+ * Expected values of image size. Shall be initialized by test
+ * method before to invoke {@link #verifyLayout(ReshapedImage)}.
+ */
+ private int width, height;
+
+ /**
+ * Expected values of tile grid offset. Shall be initialized by test
+ * method before to invoke {@link #verifyLayout(ReshapedImage)}.
+ */
+ private int tileXOffset, tileYOffset;
+
+ /**
+ * Tests wrapping a {@link BufferedImage}. This single case has only one tile
+ * with pixel coordinates starting at (0,0).
*/
@Test
- public void testRequestBefore() {
- final BufferedImage image = new BufferedImage(2, 2, BufferedImage.TYPE_BYTE_GRAY);
- final WritableRaster raster = image.getRaster();
- raster.setSample(0, 0, 0, 1);
- raster.setSample(1, 0, 0, 2);
- raster.setSample(0, 1, 0, 3);
- raster.setSample(1, 1, 0, 4);
-
- final ReshapedImage trs = new ReshapedImage(image, -1, -2, 4, 4);
- assertEquals(1, trs.getMinX());
- assertEquals(2, trs.getMinY());
- assertValuesEqual(trs.getData(), 0, new int[][] {
- {1, 2},
- {3, 4}
+ public void testSingleTile() {
+ numXTiles = 1;
+ numYTiles = 1;
+ width = TILE_WIDTH;
+ height = TILE_HEIGHT;
+ final BufferedImage data = new BufferedImage(TILE_WIDTH, TILE_HEIGHT, BufferedImage.TYPE_BYTE_GRAY);
+ data.getRaster().setSamples(0, 0, TILE_WIDTH, TILE_HEIGHT, 0, new int[] {
+ 1, 2, 3,
+ 4, 7, 6
+ });
+ /*
+ * Tests with a request starting on the left and on top of data.
+ * The requested size is larger than image size; constructor shall clamp.
+ */
+ tileXOffset = minX = 1;
+ tileYOffset = minY = 2;
+ verifySingleTile(new ReshapedImage(data, -1, -2, 4, 4));
+ /*
+ * Tests with a request inside the image. Constructor should expand to
+ * an integer number of tiles, which is the whole image for this test.
+ */
+ tileXOffset = minX = -2;
+ tileYOffset = minY = -1;
+ verifySingleTile(new ReshapedImage(data, 2, 1, 1, 1));
+ }
+
+ /**
+ * Verify an image created by {@link #testSingleTile()}.
+ *
+ * @param image the reshaped image.
+ */
+ private void verifySingleTile(final ReshapedImage image) {
+ verifyLayout(image);
+ assertValuesEqual(image.getData(), 0, new int[][] {
+ {1, 2, 3},
+ {4, 7, 6}
+ });
+ }
+
+ /**
+ * Verifies the image properties (size, number of tiles).
+ *
+ * @param image the image to verify.
+ */
+ private void verifyLayout(final ReshapedImage image) {
+ assertNull( image.verify());
+ assertEquals(minX, image.getMinX());
+ assertEquals(minY, image.getMinY());
+ assertEquals(width, image.getWidth());
+ assertEquals(height, image.getHeight());
+ assertEquals(TILE_WIDTH, image.getTileWidth());
+ assertEquals(TILE_HEIGHT, image.getTileHeight());
+ assertEquals(minTileX, image.getMinTileX());
+ assertEquals(minTileY, image.getMinTileY());
+ assertEquals(numXTiles, image.getNumXTiles());
+ assertEquals(numYTiles, image.getNumYTiles());
+ assertEquals(tileXOffset, image.getTileGridXOffset());
+ assertEquals(tileYOffset, image.getTileGridYOffset());
+ }
+
+ /**
+ * Tests wrapping a {@link TiledImageMock}.
+ */
+ @Test
+ public void testMultiTiles() {
+ final Random random = TestUtilities.createRandomNumberGenerator(219970242558564L);
+ final int dataMinX, dataMinY;
+ dataMinX = random.nextInt(20) - 10;
+ dataMinY = random.nextInt(20) - 10;
+ minTileX = random.nextInt(20) - 10;
+ minTileY = random.nextInt(20) - 10;
+ numXTiles = 5;
+ numYTiles = 4;
+ width = numXTiles * TILE_WIDTH;
+ height = numYTiles * TILE_HEIGHT;
+ final TiledImageMock data = new TiledImageMock(DataBuffer.TYPE_USHORT, 1, dataMinX, dataMinY,
+ width, height, TILE_WIDTH, TILE_HEIGHT, minTileX, minTileY);
+ data.validate();
+ data.initializeAllTiles(0);
+ /*
+ * Apply only a translation, keep all tiles.
+ */
+ tileXOffset = (minX = 7) - minTileX * TILE_WIDTH;
+ tileYOffset = (minY = 13) - minTileY * TILE_HEIGHT;
+ ReshapedImage image = new ReshapedImage(data, dataMinX - 7, dataMinY - 13, 100, 100);
+ verifyLayout(image);
+ assertValuesEqual(image.getData(), 0, new int[][] {
+ { 100, 101, 102 , 200, 201, 202 , 300, 301, 302 , 400, 401, 402 , 500, 501, 502},
+ { 110, 111, 112 , 210, 211, 212 , 310, 311, 312 , 410, 411, 412 , 510, 511, 512},
+ { 600, 601, 602 , 700, 701, 702 , 800, 801, 802 , 900, 901, 902 , 1000, 1001, 1002},
+ { 610, 611, 612 , 710, 711, 712 , 810, 811, 812 , 910, 911, 912 , 1010, 1011, 1012},
+ {1100, 1101, 1102 , 1200, 1201, 1202 , 1300, 1301, 1302 , 1400, 1401, 1402 , 1500, 1501, 1502},
+ {1110, 1111, 1112 , 1210, 1211, 1212 , 1310, 1311, 1312 , 1410, 1411, 1412 , 1510, 1511, 1512},
+ {1600, 1601, 1602 , 1700, 1701, 1702 , 1800, 1801, 1802 , 1900, 1901, 1902 , 2000, 2001, 2002},
+ {1610, 1611, 1612 , 1710, 1711, 1712 , 1810, 1811, 1812 , 1910, 1911, 1912 , 2010, 2011, 2012}
+ });
+ /*
+ * Ask for a subregion of the image. The subregion starts at (5,3) and ends at (9,5) inclusive.
+ * ReshapedImageTest shall expand to an integer number of tiles, which result in (3,2) - (11,5).
+ * This is 3×2 tiles.
+ */
+ minTileX++; // Skip one tile on the left.
+ minTileY++; // Skip one tile on the bottom.
+ width = (numXTiles = 3) * TILE_WIDTH;
+ height = (numYTiles = 2) * TILE_HEIGHT;
+ tileXOffset = (minX = -2) - minTileX * TILE_WIDTH;
+ tileYOffset = (minY = -1) - minTileY * TILE_HEIGHT;
+ image = new ReshapedImage(data, dataMinX + 5, dataMinY + 3, dataMinX + 9, dataMinY + 5);
+ verifyLayout(image);
+ assertValuesEqual(image.getData(), 0, new int[][] {
+ { 700, 701, 702 , 800, 801, 802 , 900, 901, 902},
+ { 710, 711, 712 , 810, 811, 812 , 910, 911, 912},
+ {1200, 1201, 1202 , 1300, 1301, 1302 , 1400, 1401, 1402},
+ {1210, 1211, 1212 , 1310, 1311, 1312 , 1410, 1411, 1412}
});
}
}
diff --git a/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/PlanarImageTest.java b/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/PlanarImageTest.java
index e25f534..c983c3e 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/PlanarImageTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/PlanarImageTest.java
@@ -66,7 +66,7 @@ public final strictfp class PlanarImageTest extends TestCase {
TILE_HEIGHT * 3, // height
TILE_WIDTH,
TILE_HEIGHT,
- random.nextInt(20) - 10, // minTileX,
+ random.nextInt(20) - 10, // minTileX
random.nextInt(20) - 10); // minTileY
image.validate();
image.initializeAllTiles(0);
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 e9a6f4c..73940c8 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
@@ -74,6 +74,9 @@ import org.junit.runners.Suite;
org.apache.sis.feature.builder.FeatureTypeBuilderTest.class,
// Rasters
+ org.apache.sis.internal.coverage.j2d.ImageUtilitiesTest.class,
+ org.apache.sis.internal.coverage.j2d.ScaledColorSpaceTest.class,
+ org.apache.sis.internal.coverage.j2d.PlanarImageTest.class,
org.apache.sis.image.DefaultIteratorTest.class,
org.apache.sis.image.LinearIteratorTest.class,
org.apache.sis.coverage.CategoryTest.class,
@@ -87,9 +90,6 @@ 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.ImageUtilitiesTest.class,
- org.apache.sis.internal.coverage.j2d.ScaledColorSpaceTest.class,
- org.apache.sis.internal.coverage.j2d.PlanarImageTest.class,
org.apache.sis.internal.coverage.j2d.BufferedGridCoverageTest.class
})
public final strictfp class FeatureTestSuite extends TestSuite {