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:37 UTC

[sis] 01/03: Share TiledImageMock implementation with other tests.

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 62cea41a9398021af28fb34fc685db816c9956ba
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Sun Dec 29 16:04:10 2019 +0100

    Share TiledImageMock implementation with other tests.
---
 .../org/apache/sis/image/DefaultIteratorTest.java  |   1 +
 .../java/org/apache/sis/image/TiledImageMock.java  | 150 ++++++++++++++-------
 .../sis/internal/coverage/j2d/PlanarImageTest.java | 118 +++-------------
 3 files changed, 118 insertions(+), 151 deletions(-)

diff --git a/core/sis-feature/src/test/java/org/apache/sis/image/DefaultIteratorTest.java b/core/sis-feature/src/test/java/org/apache/sis/image/DefaultIteratorTest.java
index 724defe..d0b6236 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/image/DefaultIteratorTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/image/DefaultIteratorTest.java
@@ -211,6 +211,7 @@ public strictfp class DefaultIteratorTest extends TestCase {
         }
         expected = new float[StrictMath.max(subMaxX - subMinX, 0) * StrictMath.max(subMaxY - subMinY, 0) * numBands];
         final TiledImageMock image = new TiledImageMock(dataType, numBands, xmin, ymin, width, height, tileWidth, tileHeight, minTileX, minTileY);
+        image.validate();
         /*
          * At this point, all data structures have been created an initialized to zero sample values.
          * Now fill the data structures with arbitrary values. We fill them tile-by-tile by default,
diff --git a/core/sis-feature/src/test/java/org/apache/sis/image/TiledImageMock.java b/core/sis-feature/src/test/java/org/apache/sis/image/TiledImageMock.java
index 93fe1a5..ac36645 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/image/TiledImageMock.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/image/TiledImageMock.java
@@ -16,18 +16,17 @@
  */
 package org.apache.sis.image;
 
-import java.awt.Image;
 import java.awt.Point;
-import java.awt.Rectangle;
 import java.awt.image.ColorModel;
 import java.awt.image.PixelInterleavedSampleModel;
 import java.awt.image.Raster;
-import java.awt.image.RenderedImage;
+import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.TileObserver;
 import java.awt.image.WritableRaster;
 import java.awt.image.WritableRenderedImage;
-import java.util.Vector;
+import org.apache.sis.internal.coverage.j2d.PlanarImage;
+import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.ArraysExt;
 
 import static org.junit.Assert.*;
@@ -35,18 +34,19 @@ import static org.junit.Assert.*;
 
 /**
  * A rendered image which can contain an arbitrary number of tiles. Tiles are stored in memory.
- * We use this class for testing purpose only because tiled images in production need a more
+ * We use this class for testing purpose only because tiled images in production use need a more
  * sophisticated implementation capable to store some tiles on disk (for memory consumption reasons).
  *
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.1
  * @since   0.8
  * @module
  */
-final class TiledImageMock implements WritableRenderedImage {
+public final strictfp class TiledImageMock extends PlanarImage implements WritableRenderedImage {
     /**
-     * The minimum X or Y coordinate (inclusive) of the rendered image.
+     * Location of the upper-left pixel of the image. Should be a non-trivial
+     * value for increasing the chances to detect error in index calculation.
      */
     private final int minX, minY;
 
@@ -67,7 +67,8 @@ final class TiledImageMock implements WritableRenderedImage {
     private final int numXTiles, numYTiles;
 
     /**
-     * The minimum tile index in the X or Y direction.
+     * Index of the first tile in the image. Should be a non-trivial value
+     * for increasing the chances to detect error in index calculation.
      */
     private final int minTileX, minTileY;
 
@@ -92,16 +93,24 @@ final class TiledImageMock implements WritableRenderedImage {
     private boolean isTileAcquired;
 
     /**
-     * Creates a new tiled image.
+     * Creates a new tiled image. Testers should invoke {@link #validate()} after construction.
      *
-     * @param dataType  sample data type as one of the {@link java.awt.image.DataBuffer} constants.
-     * @param numBands  number of bands in the sample model to create.
+     * @param dataType     sample data type as one of the {@link java.awt.image.DataBuffer} constants.
+     * @param numBands     number of bands in the sample model to create.
+     * @param minX         minimum X coordinate (inclusive) of the rendered image.
+     * @param minY         minimum Y coordinate (inclusive) of the rendered image.
+     * @param width        number of pixels along X axis in the whole rendered image.
+     * @param height       number of pixels along Y axis in the whole rendered image.
+     * @param tileWidth    number of pixels along X axis in a single tile of the image.
+     * @param tileHeight   number of pixels along Y axis in a single tile of the image.
+     * @param minTileX     minimum tile index in the X direction.
+     * @param minTileY     minimum tile index in the Y direction.
      */
-    TiledImageMock(final int dataType,  final int numBands,
-                   final int minX,      final int minY,
-                   final int width,     final int height,
-                   final int tileWidth, final int tileHeight,
-                   final int minTileX,  final int minTileY)
+    public TiledImageMock(final int dataType,  final int numBands,
+                          final int minX,      final int minY,
+                          final int width,     final int height,
+                          final int tileWidth, final int tileHeight,
+                          final int minTileX,  final int minTileY)
     {
         this.minX        = minX;
         this.minY        = minY;
@@ -111,37 +120,42 @@ final class TiledImageMock implements WritableRenderedImage {
         this.tileHeight  = tileHeight;
         this.minTileX    = minTileX;
         this.minTileY    = minTileY;
-        this.numXTiles   = (width  + tileWidth  - 1) / tileWidth;      // Round toward upper integer value.
-        this.numYTiles   = (height + tileHeight - 1) / tileHeight;
+        this.numXTiles   = Numerics.ceilDiv(width,  tileWidth);
+        this.numYTiles   = Numerics.ceilDiv(height, tileHeight);
         this.tiles       = new WritableRaster[numXTiles * numYTiles];
         this.sampleModel = new PixelInterleavedSampleModel(dataType, tileWidth, tileHeight,
                                 numBands, tileWidth * numBands, ArraysExt.range(0, numBands));
     }
 
-    /*
-     * No source, no property, no color model since this test images is not for rendering on screen.
+    /**
+     * No color model since this test images is not for rendering on screen.
      */
-    @Override public Vector<RenderedImage> getSources()             {return null;}
-    @Override public Object                getProperty(String name) {return Image.UndefinedProperty;}
-    @Override public String[]              getPropertyNames()       {return null;}
-    @Override public ColorModel            getColorModel()          {return null;}
-    @Override public SampleModel           getSampleModel()         {return sampleModel;}
+    @Override public ColorModel  getColorModel()  {return null;}
+    @Override public SampleModel getSampleModel() {return sampleModel;}
 
     /*
      * Information specified to the constructor.
      */
-    @Override public int getMinX()            {return minX;}
-    @Override public int getMinY()            {return minY;}
-    @Override public int getWidth()           {return width;}
-    @Override public int getHeight()          {return height;}
-    @Override public int getTileWidth()       {return tileWidth;}
-    @Override public int getTileHeight()      {return tileHeight;}
-    @Override public int getNumXTiles()       {return numXTiles;}
-    @Override public int getNumYTiles()       {return numYTiles;}
-    @Override public int getMinTileX()        {return minTileX;}
-    @Override public int getMinTileY()        {return minTileY;}
-    @Override public int getTileGridXOffset() {return minX - (minTileX * tileWidth);}
-    @Override public int getTileGridYOffset() {return minY - (minTileY * tileHeight);}
+    @Override public int getMinX()       {return minX;}
+    @Override public int getMinY()       {return minY;}
+    @Override public int getWidth()      {return width;}
+    @Override public int getHeight()     {return height;}
+    @Override public int getTileWidth()  {return tileWidth;}
+    @Override public int getTileHeight() {return tileHeight;}
+    @Override public int getNumXTiles()  {return numXTiles;}
+    @Override public int getNumYTiles()  {return numYTiles;}
+    @Override public int getMinTileX()   {return minTileX;}
+    @Override public int getMinTileY()   {return minTileY;}
+
+    /**
+     * Verifies that image and tile layouts are consistent.
+     * This method should be invoked after construction.
+     *
+     * @see #verify()
+     */
+    public void validate() {
+        assertNull(verify());
+    }
 
     /**
      * Sets a sample value at the given location in pixel coordinates.
@@ -154,8 +168,38 @@ final class TiledImageMock implements WritableRenderedImage {
         if (ox < 0 || ox >= width || oy < 0 || oy >= height) {
             throw new IndexOutOfBoundsException();
         }
-        tile(ox / tileWidth  + minTileX,
-             oy / tileHeight + minTileY).setSample(x, y, b, value);
+        tile(StrictMath.floorDiv(ox, tileWidth)  + minTileX,
+             StrictMath.floorDiv(oy, tileHeight) + minTileY, true).setSample(x, y, b, value);
+    }
+
+    /**
+     * Initializes the sample values of all tiles to testing values.
+     * The sample values will be 3 digits numbers of the form "TXY" where:
+     * <ul>
+     *   <li><var>T</var> is the tile index starting with 1 for the first tile and increasing in a row-major fashion.</li>
+     *   <li><var>X</var> is the <var>x</var> coordinate (column index) of the sample value relative to current tile.</li>
+     *   <li><var>Y</var> is the <var>y</var> coordinate (row index) of the sample value relative to current tile.</li>
+     * </ul>
+     *
+     * @param  band  band index where to set values. Other bands will be unmodified.
+     */
+    public void initializeAllTiles(final int band) {
+        int ti = 0;
+        for (int ty=0; ty<numYTiles; ty++) {
+            for (int tx=0; tx<numXTiles; tx++) {
+                final int value = (ti + 1) * 100;
+                final int x = tx * tileWidth  + minX;
+                final int y = ty * tileHeight + minY;
+                final WritableRaster raster = Raster.createWritableRaster(sampleModel, new Point(x, y));
+                for (int j=0; j<tileHeight; j++) {
+                    for (int i=0; i<tileWidth; i++) {
+                        raster.setSample(x+i, y+j, band, value + 10*j + i);
+                    }
+                }
+                tiles[ti++] = raster;
+            }
+        }
+        assertEquals(tiles.length, ti);
     }
 
     /**
@@ -169,7 +213,7 @@ final class TiledImageMock implements WritableRenderedImage {
     @Override
     public Raster getTile(final int tileX, final int tileY) {
         assertFalse("isTileAcquired", isTileAcquired);              // See javadoc.
-        return tile(tileX, tileY);
+        return tile(tileX, tileY, false);
     }
 
     /**
@@ -178,17 +222,18 @@ final class TiledImageMock implements WritableRenderedImage {
     @Override
     public WritableRaster getWritableTile(final int tileX, final int tileY) {
         assertFalse("isTileAcquired", isTileAcquired);
+        final WritableRaster raster = tile(tileX, tileY, true);
         isTileAcquired = true;
         acquiredTileX  = tileX;
         acquiredTileY  = tileY;
-        return tile(tileX, tileY);
+        return raster;
     }
 
     /**
      * Returns the tile at the given index without any verification. It is caller responsibility to verify if this
      * method is invoked in a consistent context (for example after a writable raster has been properly acquired).
      */
-    private WritableRaster tile(int tileX, int tileY) {
+    private WritableRaster tile(int tileX, int tileY, final boolean allowCreate) {
         if ((tileX -= minTileX) < 0 || tileX >= numXTiles ||
             (tileY -= minTileY) < 0 || tileY >= numYTiles)
         {
@@ -197,9 +242,12 @@ final class TiledImageMock implements WritableRenderedImage {
         final int i = tileY * numXTiles + tileX;
         WritableRaster raster = tiles[i];
         if (raster == null) {
-            tiles[i] = raster = Raster.createWritableRaster(sampleModel,
-                    new Point(tileX * tileWidth  + minX,
-                              tileY * tileHeight + minY));
+            if (!allowCreate) {
+                throw new RasterFormatException("Requested tile has not yet been defined.");
+            }
+            final int x = tileX * tileWidth  + minX;
+            final int y = tileY * tileHeight + minY;
+            tiles[i] = raster = Raster.createWritableRaster(sampleModel, new Point(x, y));
         }
         return raster;
     }
@@ -255,11 +303,11 @@ final class TiledImageMock implements WritableRenderedImage {
     public void removeTileObserver(TileObserver to) {
     }
 
-    /*
+    /**
      * Not needed for the tests.
      */
-    @Override public Raster         getData()                       {throw new UnsupportedOperationException();}
-    @Override public Raster         getData(Rectangle rect)         {throw new UnsupportedOperationException();}
-    @Override public void           setData(Raster r)               {throw new UnsupportedOperationException();}
-    @Override public WritableRaster copyData(WritableRaster raster) {throw new UnsupportedOperationException();}
+    @Override
+    public void setData(Raster r) {
+        throw new UnsupportedOperationException();
+    }
 }
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 b5d8c89..e25f534 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
@@ -17,18 +17,13 @@
 package org.apache.sis.internal.coverage.j2d;
 
 import java.util.Random;
-import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.image.ColorModel;
 import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-import java.awt.image.SampleModel;
-import java.awt.image.WritableRaster;
+import org.apache.sis.image.TiledImageMock;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.test.TestUtilities;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
 import static org.apache.sis.test.FeatureAssert.assertValuesEqual;
 
 
@@ -48,12 +43,6 @@ public final strictfp class PlanarImageTest extends TestCase {
     private static final int TILE_WIDTH = 3, TILE_HEIGHT = 2;
 
     /**
-     * Image size. Shall be multiple of tile width and height.
-     */
-    private static final int WIDTH  = TILE_WIDTH  * 4,
-                             HEIGHT = TILE_HEIGHT * 3;
-
-    /**
      * Random number generator for this test.
      */
     private final Random random;
@@ -66,93 +55,22 @@ public final strictfp class PlanarImageTest extends TestCase {
     }
 
     /**
-     * A rendered image which can contain an arbitrary number of tiles. Tiles are stored in memory.
-     * We use this class for testing purpose only because tiled images in production need a more
-     * sophisticated implementation capable to store some tiles on disk (for memory consumption reasons).
+     * Creates a rendered image which arbitrary tiles.
      */
-    private static final class TiledImage extends PlanarImage {
-        /**
-         * Index of the first tile in the image. Should be a non-trivial value
-         * for increasing the chances to detect error in index calculation.
-         */
-        private final int minTileX, minTileY;
-
-        /**
-         * Location of the upper-left pixel of the image. Should be a non-trivial
-         * value for increasing the chances to detect error in index calculation.
-         */
-        private final int minX, minY;
-
-        /**
-         * The tiles.
-         */
-        private final Raster[] tiles;
-
-        /**
-         * Creates a new tiled image.
-         */
-        TiledImage(final Random random) {
-            minTileX = random.nextInt(20) - 10;
-            minTileY = random.nextInt(20) - 10;
-            minX     = random.nextInt(20) - 10;
-            minY     = random.nextInt(20) - 10;
-            final int numXTiles = getNumXTiles();
-            final int numYTiles = getNumYTiles();
-            tiles = new WritableRaster[numXTiles * numYTiles];
-            int i = 0;
-            for (int ty = 0; ty < numYTiles; ty++) {
-                for (int tx = 0; tx < numXTiles; tx++) {
-                    tiles[i] = createTile(tx * TILE_WIDTH  + minX,
-                                          ty * TILE_HEIGHT + minY,
-                                          ++i * 100);
-                }
-            }
-            assertEquals(tiles.length, i);
-            assertNull(verify());
-        }
-
-        /**
-         * Creates a tile at the given location and with values starting at the given value.
-         *
-         * @param  x      column index of the upper-left pixel.
-         * @param  y      row index of the upper-left pixel.
-         * @param  value  value of the upper-left pixel.
-         */
-        private static WritableRaster createTile(final int x, final int y, final int value) {
-            final WritableRaster raster = Raster.createBandedRaster(DataBuffer.TYPE_USHORT, TILE_WIDTH, TILE_HEIGHT, 1, new Point(x,y));
-            for (int j=0; j<TILE_HEIGHT; j++) {
-                for (int i=0; i<TILE_WIDTH; i++) {
-                    raster.setSample(x+i, y+j, 0, value + 10*j + i);
-                }
-            }
-            return raster;
-        }
-
-        /*
-         * Size and tiling information.
-         */
-        @Override public int         getMinX()        {return minX;}
-        @Override public int         getMinY()        {return minY;}
-        @Override public int         getWidth()       {return WIDTH;}
-        @Override public int         getHeight()      {return HEIGHT;}
-        @Override public int         getTileWidth()   {return TILE_WIDTH;}
-        @Override public int         getTileHeight()  {return TILE_HEIGHT;}
-        @Override public int         getMinTileX()    {return minTileX;}
-        @Override public int         getMinTileY()    {return minTileY;}
-        @Override public ColorModel  getColorModel()  {return null;}
-        @Override public SampleModel getSampleModel() {return tiles[0].getSampleModel();}
-
-        /**
-         * Returns the tile at the given location in tile coordinates.
-         */
-        @Override
-        public Raster getTile(int tileX, int tileY) {
-            final int numXTiles = getNumXTiles();
-            final int numYTiles = getNumYTiles();
-            assertTrue((tileX -= minTileX) >= 0 && tileX < numXTiles);
-            assertTrue((tileY -= minTileY) >= 0 && tileY < numYTiles);
-            return tiles[tileY * numXTiles + tileX];
-        }
+    private PlanarImage createImage() {
+        final TiledImageMock image = new TiledImageMock(
+                DataBuffer.TYPE_USHORT, 1,      // dataType and numBands
+                random.nextInt(20) - 10,        // minX
+                random.nextInt(20) - 10,        // minY
+                TILE_WIDTH  * 4,                // width
+                TILE_HEIGHT * 3,                // height
+                TILE_WIDTH,
+                TILE_HEIGHT,
+                random.nextInt(20) - 10,        // minTileX,
+                random.nextInt(20) - 10);       // minTileY
+        image.validate();
+        image.initializeAllTiles(0);
+        return image;
     }
 
     /**
@@ -160,7 +78,7 @@ public final strictfp class PlanarImageTest extends TestCase {
      */
     @Test
     public void testGetData() {
-        final PlanarImage image = new TiledImage(random);
+        final PlanarImage image = createImage();
         assertValuesEqual(image.getData(), 0, new int[][] {
             { 100,  101,  102  ,   200,  201,  202  ,   300,  301,  302  ,   400,  401,  402},
             { 110,  111,  112  ,   210,  211,  212  ,   310,  311,  312  ,   410,  411,  412},
@@ -176,7 +94,7 @@ public final strictfp class PlanarImageTest extends TestCase {
      */
     @Test
     public void testGetDataRegion() {
-        final PlanarImage image = new TiledImage(random);
+        final PlanarImage image = createImage();
         final Rectangle region = ImageUtilities.getBounds(image);
         region.x      += 4;     // Exclude 4 columns on left side.
         region.width  -= 6;     // Exclude 2 columns on right side.