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 49945796f423aaf5127a35568bf8b80473448fd0
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Mon Dec 23 16:16:15 2024 +0100

    Retrofit the `minTile` property of two `ImageLayout` subclasses into 
`ImageLayout` directly.
---
 .../org/apache/sis/image/BandAggregateImage.java   |   2 +-
 .../org/apache/sis/image/BandAggregateLayout.java  |  37 ++----
 .../main/org/apache/sis/image/ImageLayout.java     | 131 +++++++++++++--------
 .../main/org/apache/sis/image/ImageProcessor.java  |   2 +-
 .../main/org/apache/sis/image/Visualization.java   |   4 +-
 5 files changed, 92 insertions(+), 84 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateImage.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateImage.java
index 94cba95aa4..a1c7da14f7 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateImage.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateImage.java
@@ -173,7 +173,7 @@ class BandAggregateImage extends MultiSourceImage {
     private BandAggregateImage(final BandAggregateLayout layout, final 
Colorizer colorizer,
                                final boolean allowSharing, final boolean 
parallel)
     {
-        super(layout.filteredSources, layout.domain, layout.getMinTile(),
+        super(layout.filteredSources, layout.domain, 
layout.getPreferredMinTile(),
               layout.sampleModel, layout.createColorModel(colorizer), 
parallel);
         this.allowSharing = allowSharing;
     }
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateLayout.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateLayout.java
index a1e9a8513b..9ddb2f6ecd 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateLayout.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateLayout.java
@@ -93,15 +93,6 @@ final class BandAggregateLayout extends ImageLayout {
      */
     final Rectangle domain;
 
-    /**
-     * Index of the first tile. Other tile matrix properties such as the 
number of tiles and the grid offsets
-     * are derived from those values together with the {@linkplain #domain}. 
Contrarily to pixel coordinates,
-     * the tile coordinate space does not need to be the same for all images.
-     *
-     * @see #getMinTile()
-     */
-    private final int minTileX, minTileY;
-
     /**
      * Computes the layout of an image combining the bands of all the 
specified source images.
      * The optional {@code bandsPerSource} argument specifies the bands to 
select in each source images.
@@ -202,10 +193,12 @@ final class BandAggregateLayout extends ImageLayout {
         final var preferredTileSize = new Dimension((int) cx, (int) cy);
         final boolean exactTileSize = ((cx | cy) >>> Integer.SIZE) == 0;
         allowSharing &= exactTileSize;
+
+        final var minTile = new Point(chooseMinTile(tileGridXOffset, domain.x, 
preferredTileSize.width),
+                                      chooseMinTile(tileGridYOffset, domain.y, 
preferredTileSize.height));
+
         return new BandAggregateLayout(sources, bandsPerSource, bandSelect, 
domain, preferredTileSize, exactTileSize,
-                chooseMinTile(tileGridXOffset, domain.x, 
preferredTileSize.width),
-                chooseMinTile(tileGridYOffset, domain.y, 
preferredTileSize.height),
-                commonDataType, aggregate.numBands(), allowSharing ? 
scanlineStride : 0);
+                    minTile, commonDataType, aggregate.numBands(), 
allowSharing ? scanlineStride : 0);
     }
 
     /**
@@ -228,16 +221,13 @@ final class BandAggregateLayout extends ImageLayout {
      */
     private BandAggregateLayout(final RenderedImage[] sources, final int[][] 
bandsPerSource, final int[] bandSelect,
             final Rectangle domain, final Dimension preferredTileSize, final 
boolean exactTileSize,
-            final int minTileX, final int minTileY, final int commonDataType, 
final int numBands,
-            final int scanlineStride)
+            final Point minTile, final int commonDataType, final int numBands, 
final int scanlineStride)
     {
-        super(preferredTileSize, !exactTileSize, false, false);
+        super(preferredTileSize, !exactTileSize, false, false, minTile);
         this.bandsPerSource = bandsPerSource;
         this.bandSelect     = bandSelect;
         this.sources        = sources;
         this.domain         = domain;
-        this.minTileX       = minTileX;
-        this.minTileY       = minTileY;
         this.sampleModel    = createBandedSampleModel(commonDataType, 
numBands, null, domain, scanlineStride);
         /*
          * Note: above call to `createBandedSampleModel(…)` must be last,
@@ -310,19 +300,6 @@ final class BandAggregateLayout extends ImageLayout {
         return 0;
     }
 
-    /**
-     * Returns indices of the first tile ({@code minTileX}, {@code minTileY}).
-     * Other tile matrix properties such as the number of tiles and the grid 
offsets will be derived
-     * from those values together with the {@linkplain #domain}. Contrarily to 
pixel coordinates,
-     * the tile coordinate space does not need to be the same for all images.
-     *
-     * @return indices of the first tile ({@code minTileX}, {@code minTileY}).
-     */
-    @Override
-    public Point getMinTile() {
-        return new Point(minTileX, minTileY);
-    }
-
     /**
      * Returns {@code true} if all filtered sources are writable.
      *
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageLayout.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageLayout.java
index 179f3e426b..47500f5e33 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageLayout.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageLayout.java
@@ -73,14 +73,16 @@ public class ImageLayout {
      * Image sizes are preserved but the tile sizes are flexible. The last row 
and last column of tiles
      * in an image are allowed to be only partially filled.
      */
-    public static final ImageLayout DEFAULT = new ImageLayout(null, true, 
false, true);
+    public static final ImageLayout DEFAULT = new ImageLayout(null, true, 
false, true, null);
 
     /**
      * Preferred size (in pixels) for tiles.
+     * The actual tile size will also depend on the size of the image to tile.
      * The {@linkplain #DEFAULT default} value is {@value #DEFAULT_TILE_SIZE}.
      *
      * @see #DEFAULT_TILE_SIZE
      * @see #getPreferredTileSize()
+     * @see #suggestTileSize(int, int)
      */
     protected final int preferredTileWidth, preferredTileHeight;
 
@@ -120,6 +122,16 @@ public class ImageLayout {
      */
     public final boolean isPartialTilesAllowed;
 
+    /**
+     * Preferred tile index where images start their tile matrix.
+     * This property usually has no incidence on the appearance or performance
+     * of an image and may be ignored by image operations.
+     * The {@linkplain #DEFAULT default} value is 0.
+     *
+     * @see #getPreferredMinTile()
+     */
+    protected final int preferredMinTileX, preferredMinTileY;
+
     /**
      * Creates a new image layout.
      *
@@ -127,11 +139,13 @@ public class ImageLayout {
      * @param  isTileSizeAdjustmentAllowed     whether tile size can be 
modified if needed.
      * @param  isImageBoundsAdjustmentAllowed  whether image size can be 
modified if needed.
      * @param  isPartialTilesAllowed           whether to allow tiles that are 
only partially filled.
+     * @param  preferredMinTile                preferred tile index where 
image start their tile matrix, or {@code null} for (0,0).
      */
-    public ImageLayout(final Dimension preferredTileSize,
-                       final boolean isTileSizeAdjustmentAllowed,
-                       final boolean isImageBoundsAdjustmentAllowed,
-                       final boolean isPartialTilesAllowed)
+    protected ImageLayout(final Dimension preferredTileSize,
+                          final boolean isTileSizeAdjustmentAllowed,
+                          final boolean isImageBoundsAdjustmentAllowed,
+                          final boolean isPartialTilesAllowed,
+                          final Point   preferredMinTile)
     {
         if (preferredTileSize != null) {
             preferredTileWidth  = Math.max(1, preferredTileSize.width);
@@ -143,16 +157,13 @@ public class ImageLayout {
         this.isTileSizeAdjustmentAllowed    = isTileSizeAdjustmentAllowed;
         this.isImageBoundsAdjustmentAllowed = isImageBoundsAdjustmentAllowed;
         this.isPartialTilesAllowed          = isPartialTilesAllowed;
-    }
-
-    /**
-     * Creates a new layout with exactly the tile size of the given image.
-     *
-     * @param  source  image from which to take tile size and tile indices.
-     * @return layout giving exactly the tile size and indices of given image.
-     */
-    static ImageLayout forTileSize(final RenderedImage source) {
-        return new FixedSize(source, source.getMinTileX(), 
source.getMinTileY());
+        if (preferredMinTile != null) {
+            preferredMinTileX = preferredMinTile.x;
+            preferredMinTileY = preferredMinTile.y;
+        } else {
+            preferredMinTileX = 0;
+            preferredMinTileY = 0;
+        }
     }
 
     /**
@@ -167,36 +178,17 @@ public class ImageLayout {
         return new FixedDestination(source, minTileX, minTileY);
     }
 
-    /**
-     * Override preferred tile size with a fixed size.
-     */
-    private static class FixedSize extends ImageLayout {
-        /** Indices of the first tile. */
-        private final int minTileX, minTileY;
-
-        /** Creates a new layout with exactly the tile size of given image. */
-        FixedSize(final RenderedImage source, final int minTileX, final int 
minTileY) {
-            super(new Dimension(source.getTileWidth(), 
source.getTileHeight()), false, false, true);
-            this.minTileX = minTileX;
-            this.minTileY = minTileY;
-        }
-
-        /** Returns indices of the first tile. */
-        @Override public Point getMinTile() {
-            return new Point(minTileX, minTileY);
-        }
-    }
-
     /**
      * Override sample model with the one of the destination.
      */
-    private static final class FixedDestination extends FixedSize {
+    private static final class FixedDestination extends ImageLayout {
         /** The destination image. */
         private final WritableRenderedImage destination;
 
         /** Creates a new layout with exactly the tile size of given image. */
         FixedDestination(final WritableRenderedImage destination, final int 
minTileX, final int minTileY) {
-            super(destination, minTileX, minTileY);
+            super(new Dimension(destination.getTileWidth(), 
destination.getTileHeight()),
+                                false, false, true, new Point(minTileX, 
minTileY));
             this.destination = destination;
         }
 
@@ -222,7 +214,8 @@ public class ImageLayout {
      */
     public ImageLayout allowTileSizeAdjustments(boolean allowed) {
         if (isTileSizeAdjustmentAllowed == allowed) return this;
-        return new ImageLayout(getPreferredTileSize(), allowed, 
isImageBoundsAdjustmentAllowed, isPartialTilesAllowed);
+        return new ImageLayout(getPreferredTileSize(), allowed, 
isImageBoundsAdjustmentAllowed, isPartialTilesAllowed,
+                               getPreferredMinTile());
     }
 
     /**
@@ -236,7 +229,8 @@ public class ImageLayout {
      */
     public ImageLayout allowImageBoundsAdjustments(boolean allowed) {
         if (isImageBoundsAdjustmentAllowed == allowed) return this;
-        return new ImageLayout(getPreferredTileSize(), 
isTileSizeAdjustmentAllowed, allowed, isPartialTilesAllowed);
+        return new ImageLayout(getPreferredTileSize(), 
isTileSizeAdjustmentAllowed, allowed, isPartialTilesAllowed,
+                               getPreferredMinTile());
     }
 
     /**
@@ -250,7 +244,33 @@ public class ImageLayout {
      */
     public ImageLayout allowPartialTiles(boolean allowed) {
         if (isPartialTilesAllowed == allowed) return this;
-        return new ImageLayout(getPreferredTileSize(), 
isTileSizeAdjustmentAllowed, isImageBoundsAdjustmentAllowed, allowed);
+        return new ImageLayout(getPreferredTileSize(), 
isTileSizeAdjustmentAllowed, isImageBoundsAdjustmentAllowed, allowed,
+                               getPreferredMinTile());
+    }
+
+    /**
+     * Creates a new layout with the tile size and tile indices of the given 
image.
+     * Other properties (all Boolean flags) are copied unchanged.
+     * If the given argument value results in no change, returns {@code this}.
+     *
+     * @param  source  image from which to take tile size and tile indices.
+     * @return layout giving exactly the tile size and indices of given image.
+     *
+     * @see #getPreferredTileSize()
+     * @see #getPreferredMinTile()
+     */
+    public ImageLayout withTileMatrix(final RenderedImage source) {
+        final var preferredTileSize = new Dimension(source.getTileWidth(), 
source.getTileHeight());
+        final var preferredMinTile  = new Point(source.getMinTileX(), 
source.getMinTileY());
+        if (preferredTileSize.width  == preferredTileWidth  &&
+            preferredTileSize.height == preferredTileHeight &&
+            preferredMinTile .x      == preferredMinTileX   &&
+            preferredMinTile .y      == preferredMinTileY)
+        {
+            return this;
+        }
+        return new ImageLayout(preferredTileSize, isTileSizeAdjustmentAllowed,
+                isImageBoundsAdjustmentAllowed, isPartialTilesAllowed, 
preferredMinTile);
     }
 
     /**
@@ -266,7 +286,8 @@ public class ImageLayout {
         if (size.width == preferredTileWidth && size.height == 
preferredTileHeight) {
             return this;
         }
-        return new ImageLayout(size, isTileSizeAdjustmentAllowed, 
isImageBoundsAdjustmentAllowed, isPartialTilesAllowed);
+        return new ImageLayout(size, isTileSizeAdjustmentAllowed, 
isImageBoundsAdjustmentAllowed,
+                isPartialTilesAllowed, getPreferredMinTile());
     }
 
     /**
@@ -506,16 +527,19 @@ public class ImageLayout {
     }
 
     /**
-     * Returns indices of the first tile ({@code minTileX}, {@code minTileY}), 
or {@code null} for (0,0).
-     * The default implementation returns {@code null}.
+     * Returns the preferred indices of the upper-left tile in an image tile 
matrix.
+     * This property usually has no incidence on the appearance or performance 
of an image.
+     * It usually doesn't change neither the calculations that depend on 
georeferencing,
+     * because these calculations depend on pixel coordinates rather than tile 
coordinates.
+     * Therefore, this property is only a hint and may be ignored by image 
operations.
      *
-     * <p>This method is not yet in public API because it is currently set 
only by {@link Visualization}.
-     * Only the image operations needed by {@code Visualization} take this 
information in account.</p>
+     * @return preferred tile indices of the upper-left tile.
      *
-     * @return indices of the first tile ({@code minTileX}, {@code minTileY}), 
or {@code null} for (0,0).
+     * @see RenderedImage#getMinTileX()
+     * @see RenderedImage#getMinTileY()
      */
-    Point getMinTile() {
-        return null;
+    public final Point getPreferredMinTile() {
+        return new Point(preferredMinTileX, preferredMinTileY);
     }
 
     /**
@@ -537,8 +561,15 @@ public class ImageLayout {
      */
     @Override
     public String toString() {
+        var sb = new StringBuilder();
+        var preferredTileSize = 
sb.append(preferredTileWidth).append('×').append(preferredTileHeight).toString();
+        sb.setLength(0);
+        var preferredMinTile = 
sb.append('(').append(preferredMinTileX).append(", 
").append(preferredMinTileY).append(')').toString();
         return Strings.toString(getClass(),
-                "preferredTileSize", new 
StringBuilder().append(preferredTileWidth).append('×').append(preferredTileHeight),
-                "isImageBoundsAdjustmentAllowed", 
isImageBoundsAdjustmentAllowed);
+                "preferredTileSize",              preferredTileSize,
+                "isTileSizeAdjustmentAllowed",    isTileSizeAdjustmentAllowed,
+                "isImageBoundsAdjustmentAllowed", 
isImageBoundsAdjustmentAllowed,
+                "isPartialTilesAllowed",          isPartialTilesAllowed,
+                "preferredMinTile",               preferredMinTile);
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageProcessor.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageProcessor.java
index bd3e637c58..1dcb702295 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageProcessor.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageProcessor.java
@@ -1246,7 +1246,7 @@ public class ImageProcessor implements Cloneable {
             }
             final WritableRenderedImage destination = layout.getDestination();
             final SampleModel rsm = layout.createCompatibleSampleModel(source, 
bounds);
-            final var image = new ResampledImage(source, rsm, 
layout.getMinTile(), bounds, toSource,
+            final var image = new ResampledImage(source, rsm, 
layout.getPreferredMinTile(), bounds, toSource,
                                                  interpolation, fillValues, 
positionalAccuracyHints);
             image.setDestination(destination);
             resampled = unique(image);
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Visualization.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Visualization.java
index 375f3477ed..260c5edf15 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Visualization.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Visualization.java
@@ -260,7 +260,7 @@ final class Visualization extends ResampledImage {
              */
             final boolean shortcut = toSource.isIdentity() && (bounds == null 
|| ImageUtilities.getBounds(source).contains(bounds));
             if (shortcut) {
-                layout = ImageLayout.forTileSize(source);
+                layout = 
ImageLayout.DEFAULT.withTileMatrix(source).allowTileSizeAdjustments(false);
             }
             /*
              * Sample values will be unconditionally converted to integers in 
the [0 … 255] range.
@@ -479,7 +479,7 @@ final class Visualization extends ResampledImage {
     private Visualization(final Builder builder) {
         super(builder.source,
               builder.sampleModel,
-              builder.layout.getMinTile(),
+              builder.layout.getPreferredMinTile(),
               builder.bounds,
               builder.toSource,
               builder.interpolation,

Reply via email to