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