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 84c4925e23f9eea038dc2bf52899c394d336059c
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Tue Nov 9 14:21:46 2021 +0100

    Edit the tests (formatting, constants, some simplifications).
    There is no change in test data.
---
 .../java/org/apache/sis/image/MaskedImageTest.java | 281 +++++++++++++--------
 1 file changed, 179 insertions(+), 102 deletions(-)

diff --git 
a/core/sis-feature/src/test/java/org/apache/sis/image/MaskedImageTest.java 
b/core/sis-feature/src/test/java/org/apache/sis/image/MaskedImageTest.java
index 441574c..7be55e7 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/image/MaskedImageTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/image/MaskedImageTest.java
@@ -16,99 +16,147 @@
  */
 package org.apache.sis.image;
 
+import java.util.Arrays;
 import java.awt.Color;
-import java.awt.Graphics;
+import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.Polygon;
 import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
 import java.awt.image.BufferedImage;
 import java.awt.image.DataBuffer;
 import java.awt.image.IndexColorModel;
 import java.awt.image.Raster;
 import java.awt.image.RenderedImage;
 import java.awt.image.WritableRaster;
-import org.apache.sis.internal.coverage.j2d.WritableTiledImage;
-import org.apache.sis.test.FeatureAssert;
-import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.internal.coverage.j2d.TiledImage;
 import org.apache.sis.test.TestCase;
+import org.apache.sis.util.Debug;
 import org.junit.Test;
 
+import static org.apache.sis.test.FeatureAssert.*;
+
+
 /**
- * TODO: test with big images
- * TODO: when upgrading to Junit 5 use parameterized tests to avoid 
duplication of test methods
+ * Tests {@link MaskedImage}.
+ *
+ * @author  Alexis Manin (Geomatys)
+ * @version 1.2
+ * @since   1.2
+ * @module
  */
 public final strictfp class MaskedImageTest extends TestCase {
+    /**
+     * The image width and height in pixels.
+     */
+    private static final int WIDTH = 8, HEIGHT = 8;
 
-    private static final Polygon CONVEX_POLYGON = new Polygon(
-            new int[] {3, 8, 8, 3, 3},
-            new int[] {3, 3, 6, 6, 3},
-            5);
+    /**
+     * The tile width and height in pixels. Note that the number of tiles
+     * is hard-coded to 2 in methods such as {@link #multiTile()}.
+     */
+    private static final int TILE_WIDTH = WIDTH/2, TILE_HEIGHT = HEIGHT/2;
+
+    /**
+     * Returns a rectangular shape to use as a mask.
+     */
+    private static Rectangle rectangularMask() {
+        return new Rectangle(3, 3, 5, 3);
+    }
 
-    private static final Polygon CONCAVE_POLYGON = new Polygon(
+    /**
+     * Returns a non-rectangular polygon to use as a mask.
+     */
+    private static Polygon concavePolygon() {
+        return new Polygon(
             new int[] { 1, 1, 7, 7, 5, 5, 2, 2 },
             new int[] { 1, 6, 6, 3, 3, 4, 4, 1 },
             8);
+    }
 
-    private static final int[] BASE_CANVAS = {
-            0, 0, 0, 0, 1, 1, 1, 1,
-            0, 0, 0, 0, 1, 1, 1, 1,
-            0, 0, 0, 0, 1, 1, 1, 1,
-            0, 0, 0, 0, 1, 1, 1, 1,
-            3, 3, 3, 3, 2, 2, 2, 2,
-            3, 3, 3, 3, 2, 2, 2, 2,
-            3, 3, 3, 3, 2, 2, 2, 2,
-            3, 3, 3, 3, 2, 2, 2, 2
-    };
-
+    /**
+     * Tests an empty mask. The result should be identical to source image.
+     * Actually, {@link MaskedImage} is expected to optimize by reusing the 
same raster.
+     */
     @Test
     public void noErrorOnEmptyMasks() {
         final BufferedImage source = monoTile();
-        final RenderedImage masked = new MaskedImage(source, new Polygon(), 
true, new Number[]{ 127 });
-        FeatureAssert.assertPixelsEqual(source, null, masked, null);
+        final RenderedImage masked = new MaskedImage(source, new Polygon(), 
true, new Number[] {127});
+        assertPixelsEqual(source, null, masked, null);
+        assertSame(source.getRaster(), masked.getTile(0,0));    // 
Optimization applied by MaskedImage.
     }
 
+    /**
+     * Tests masking pixels inside a rectangle on a image having a single tile.
+     */
     @Test
     public void fill_MONO_tile_INside_conVEX_polygon() {
-        maskInsideConvexPolygon(monoTile());
+        maskInsideRectangle(monoTile());
     }
 
+    /**
+     * Tests masking pixels outside a rectangle on a image having a single 
tile.
+     */
     @Test
     public void fill_MONO_tile_OUTside_conVEX_polygon() {
         maskOutsideConvexPolygon(monoTile());
     }
 
+    /**
+     * Tests masking pixels inside a rectangle on a image having many tiles.
+     */
     @Test
     public void fill_MULTI_tile_INside_conVEX_polygon() {
-        maskInsideConvexPolygon(multiTile());
+        maskInsideRectangle(multiTile());
     }
 
+    /**
+     * Tests masking pixels outside a rectangle on a image having many tiles.
+     */
     @Test
     public void fill_MULTI_tile_OUTside_conVEX_polygon() {
         maskOutsideConvexPolygon(multiTile());
     }
 
+    /**
+     * Tests masking pixels inside a non-rectangular polygon on a image having 
a single tile.
+     */
     @Test
     public void fill_MONO_tile_INside_conCAVE_polygon() {
         fillInsideConcavePolygon(monoTile());
     }
 
+    /**
+     * Tests masking pixels outside a non-rectangular polygon on a image 
having a single tile.
+     */
     @Test
     public void fill_MONO_tile_OUTside_conCAVE_polygon() {
         fillOutsideConcavePolygon(monoTile());
     }
 
+    /**
+     * Tests masking pixels inside a non-rectangular polygon on a image having 
many tiles.
+     */
     @Test
     public void fill_MULTI_tile_INside_conCAVE_polygon() {
         fillInsideConcavePolygon(multiTile());
     }
 
+    /**
+     * Tests masking pixels outside a non-rectangular polygon on a image 
having many tiles.
+     */
     @Test
     public void fill_MULTI_tile_OUTside_conCAVE_polygon() {
         fillOutsideConcavePolygon(multiTile());
     }
 
-    private void maskInsideConvexPolygon(RenderedImage source) {
-        final RenderedImage masked = new MaskedImage(source, CONVEX_POLYGON, 
true, new Number[]{ 4 });
+    /**
+     * Tests masking pixels inside a rectangle on the given image.
+     * This method is invoked twice, for untiled image and for tiled image.
+     */
+    private static void maskInsideRectangle(final RenderedImage source) {
+        final RenderedImage masked = new MaskedImage(source, 
rectangularMask(), true, new Number[]{ 4 });
         final RenderedImage expected = monoTile(new int[] {
                 0, 0, 0, 0, 1, 1, 1, 1,
                 0, 0, 0, 0, 1, 1, 1, 1,
@@ -119,11 +167,15 @@ public final strictfp class MaskedImageTest extends 
TestCase {
                 3, 3, 3, 3, 2, 2, 2, 2,
                 3, 3, 3, 3, 2, 2, 2, 2
         });
-        FeatureAssert.assertPixelsEqual(expected, null, masked, null);
+        assertPixelsEqual(expected, null, masked, null);
     }
 
-    private void maskOutsideConvexPolygon(final RenderedImage source) {
-        final RenderedImage masked = new MaskedImage(source, CONVEX_POLYGON, 
false, new Number[]{ 4 });
+    /**
+     * Tests masking pixels outside a rectangle on the given image.
+     * This method is invoked twice, for untiled image and for tiled image.
+     */
+    private static void maskOutsideConvexPolygon(final RenderedImage source) {
+        final RenderedImage masked = new MaskedImage(source, 
rectangularMask(), false, new Number[]{ 4 });
         final RenderedImage expected = monoTile(new int[] {
                 4, 4, 4, 4, 4, 4, 4, 4,
                 4, 4, 4, 4, 4, 4, 4, 4,
@@ -134,11 +186,15 @@ public final strictfp class MaskedImageTest extends 
TestCase {
                 4, 4, 4, 4, 4, 4, 4, 4,
                 4, 4, 4, 4, 4, 4, 4, 4
         });
-        FeatureAssert.assertPixelsEqual(expected, null, masked, null);
+        assertPixelsEqual(expected, null, masked, null);
     }
 
-    private void fillInsideConcavePolygon(final RenderedImage source) {
-        final RenderedImage masked = new MaskedImage(source, CONCAVE_POLYGON, 
true, new Number[]{ 4 });
+    /**
+     * Tests masking pixels inside a non-rectangular polygon on the given 
image.
+     * This method is invoked twice, for untiled image and for tiled image.
+     */
+    private static void fillInsideConcavePolygon(final RenderedImage source) {
+        final RenderedImage masked = new MaskedImage(source, concavePolygon(), 
true, new Number[]{ 4 });
         final RenderedImage expected = monoTile(new int[] {
                 0, 0, 0, 0, 1, 1, 1, 1,
                 0, 4, 0, 0, 1, 1, 1, 1,
@@ -149,11 +205,15 @@ public final strictfp class MaskedImageTest extends 
TestCase {
                 3, 3, 3, 3, 2, 2, 2, 2,
                 3, 3, 3, 3, 2, 2, 2, 2
         });
-        FeatureAssert.assertPixelsEqual(expected, null, masked, null);
+        assertPixelsEqual(expected, null, masked, null);
     }
 
-    private void fillOutsideConcavePolygon(final RenderedImage source) {
-        final RenderedImage masked = new MaskedImage(source, CONCAVE_POLYGON, 
false, new Number[]{ 4 });
+    /**
+     * Tests masking pixels outside a non-rectangular polygon on the given 
image.
+     * This method is invoked twice, for untiled image and for tiled image.
+     */
+    private static void fillOutsideConcavePolygon(final RenderedImage source) {
+        final RenderedImage masked = new MaskedImage(source, concavePolygon(), 
false, new Number[]{ 4 });
         final RenderedImage expected = monoTile(new int[] {
                 4, 4, 4, 4, 4, 4, 4, 4,
                 4, 0, 4, 4, 4, 4, 4, 4,
@@ -164,24 +224,72 @@ public final strictfp class MaskedImageTest extends 
TestCase {
                 4, 4, 4, 4, 4, 4, 4, 4,
                 4, 4, 4, 4, 4, 4, 4, 4
         });
-        FeatureAssert.assertPixelsEqual(expected, null, masked, null);
+        assertPixelsEqual(expected, null, masked, null);
+    }
+
+    /**
+     * Creates the base test image with a single tile.
+     * Sample values are between 0 and 3 inclusive and
+     * the image uses an {@linkplain #colorPalette() indexed color model}.
+     */
+    private static BufferedImage monoTile() {
+        return monoTile(new int[] {
+                0, 0, 0, 0, 1, 1, 1, 1,
+                0, 0, 0, 0, 1, 1, 1, 1,
+                0, 0, 0, 0, 1, 1, 1, 1,
+                0, 0, 0, 0, 1, 1, 1, 1,
+                3, 3, 3, 3, 2, 2, 2, 2,
+                3, 3, 3, 3, 2, 2, 2, 2,
+                3, 3, 3, 3, 2, 2, 2, 2,
+                3, 3, 3, 3, 2, 2, 2, 2
+        });
     }
 
-    private RenderedImage multiTile() {
-        return new WritableTiledImage(null, colorPalette(), 8, 8, 0, 0,
-                tile(0, 0), tile(1, 1), tile(2, 3), tile(3, 2));
+    /**
+     * Creates an image with a single tile and the given number of values.
+     * Image size is {@value #WIDTH}×{@value #HEIGHT} pixels.
+     */
+    private static BufferedImage monoTile(final int[] pixels) {
+        assertEquals("Input raster must be " + WIDTH + "×" + HEIGHT, 
WIDTH*HEIGHT, pixels.length);
+        final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, 
BufferedImage.TYPE_BYTE_INDEXED, colorPalette());
+        final WritableRaster raster = image.getRaster();
+        raster.setPixels(0, 0, WIDTH, HEIGHT, pixels);
+        return image;
     }
 
-    private static WritableRaster tile(final int n, final int fillValue) {
-        final WritableRaster tile = 
Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, 4, 4, 1, new Point((n % 
2)*4, (n / 2)*4));
-        final WritablePixelIterator it = new 
PixelIterator.Builder().createWritable(tile);
-        while (it.next()) it.setSample(0, fillValue);
+    /**
+     * Creates an image with a 4 tiles and the given number of values.
+     * Image size is {@value #WIDTH}×{@value #HEIGHT} pixels.
+     */
+    private static RenderedImage multiTile() {
+        final TiledImage image = new TiledImage(null, colorPalette(), WIDTH, 
HEIGHT, 0, 0,
+                tile(         0,           0, 0),
+                tile(TILE_WIDTH,           0, 1),
+                tile(         0, TILE_HEIGHT, 3),
+                tile(TILE_WIDTH, TILE_HEIGHT, 2));
+        assertNull(image.verify());
+        return image;
+    }
+
+    /**
+     * Creates a tile filled with the given value.
+     *
+     * @param  x  <var>x</var> coordinate of upper-left corner.
+     * @param  y  <var>y</var> coordinate of upper-left corner.
+     * @param  fillValue  the value to use for filling the raster.
+     * @return a tile filled with the given value.
+     */
+    private static WritableRaster tile(final int x, final int y, final int 
fillValue) {
+        final WritableRaster tile = Raster.createInterleavedRaster(
+                DataBuffer.TYPE_BYTE, TILE_WIDTH, TILE_HEIGHT, 1, new Point(x, 
y));
+        final int[] pixels = new int[TILE_WIDTH * TILE_HEIGHT];
+        Arrays.fill(pixels, fillValue);
+        tile.setPixels(x, y, TILE_WIDTH, TILE_HEIGHT, pixels);
         return tile;
     }
 
     /**
      * Base colors are shades of blue. The last (fifth) color used for masks 
is green.
-     * @return
      */
     private static IndexColorModel colorPalette() {
         byte[] reds   = { 0,  0,  0,   0,   0 };
@@ -191,65 +299,34 @@ public final strictfp class MaskedImageTest extends 
TestCase {
     }
 
     /**
+     * Draws the given polygon into the given image, in order to display 
expected result in debugger.
+     * If the given image is {@code null}, the {@linkplain #monoTile() untiled 
source image} is used.
      *
-     * @return Base test image, based on {@link #colorPalette() indexed color 
model}.
-     */
-    private static BufferedImage monoTile() {
-        return monoTile(BASE_CANVAS);
-    }
-
-    private static BufferedImage monoTile(int[] pixels) {
-        ArgumentChecks.ensureDimensionMatches("Input raster must be 8x8", 64, 
pixels);
-        final BufferedImage image = new BufferedImage(8, 8, 
BufferedImage.TYPE_BYTE_INDEXED, colorPalette());
-        final WritableRaster raster = image.getRaster();
-        raster.setPixels(0, 0, 8, 8, pixels);
-        return image;
-    }
-
-    /**
-     * Draw given polygon into source image, to display expected result in 
debugger.
+     * <p>Tip for IntelliJ users:</p> this method allows to display input 
image in debugger
+     * by adding a new watch calling this method on the wanted image.
+     *
+     * @param  source    the image to display, or {@code null} for {@link 
#monoTile()}.
+     * @param  geometry  the geometry to show on top of the image, or {@code 
null} if none.
+     * @return the image directly displayable through debugger.
      */
-    private static BufferedImage debugGeometryImage(final Polygon geometry) {
-        final BufferedImage source = monoTile();
-        final BufferedImage debugImg = new BufferedImage(source.getWidth(), 
source.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
-        final Graphics painter = debugImg.getGraphics();
-        painter.drawImage(source, 0, 0, null);
-
-        final Rectangle bounds = geometry.getBounds();
-        final Rectangle enlargedBounds = new Rectangle(bounds.x - 1, bounds.y 
- 1, bounds.width + 2, bounds.height + 2);
-        final Rectangle intersection = 
enlargedBounds.intersection(debugImg.getRaster().getBounds());
-        painter.setColor(Color.RED);
-        painter.fillRect(intersection.x, intersection.y, intersection.width, 
intersection.height);
-        painter.setColor(Color.GREEN);
-        painter.fillPolygon(geometry);
+    @Debug
+    private static BufferedImage debugGeometryImage(RenderedImage source, 
final Shape geometry) {
+        if (source == null) {
+            source = monoTile();
+        }
+        final BufferedImage debugImg = new BufferedImage(source.getWidth(), 
source.getHeight(), BufferedImage.TYPE_INT_RGB);
+        final Graphics2D painter = debugImg.createGraphics();
+        painter.drawRenderedImage(source, new AffineTransform());
+        if (geometry != null) {
+            final Rectangle bounds = geometry.getBounds();
+            final Rectangle enlargedBounds = new Rectangle(bounds.x - 1, 
bounds.y - 1, bounds.width + 2, bounds.height + 2);
+            final Rectangle intersection = 
enlargedBounds.intersection(debugImg.getRaster().getBounds());
+            painter.setColor(Color.RED);
+            painter.fill(intersection);
+            painter.setColor(Color.GREEN);
+            painter.fill(geometry);
+        }
         painter.dispose();
-
         return debugImg;
     }
-
-
-    /**
-     * Useful in IntelliJ: allow to display input image in debugger: Add a new 
watch calling this method on wanted image.
-     * <em>WARNINGS:</em> works only for current test case:
-     * <ul>
-     *     <li> it assume input image is compatible with test {@link 
#colorPalette() color palette}.</li>
-     *     <li>Work only on single tile images.</li>
-     * </ul>
-     *
-     * @param source The image to display.
-     * @return The image directly displayable through debugger.
-     */
-    private static BufferedImage debug(final RenderedImage source) {
-        Raster tile = source.getTile(source.getMinTileX(), 
source.getMinTileY());
-        final int width, height;
-
-        tile = tile.createTranslatedChild(0, 0);
-        width = tile.getWidth();
-        height = tile.getHeight();
-
-        final BufferedImage view = new BufferedImage(width, height, 
BufferedImage.TYPE_BYTE_INDEXED, colorPalette());
-        view.getRaster().setRect(tile);
-
-        return view;
-    }
 }

Reply via email to