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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 67491ac139 Make possible to write a raster with a `BandedSampleModel` 
where the data are stored in a single bank.
67491ac139 is described below

commit 67491ac1393f1a5f8e1e2c4fa0a7fb14bb5f9d14
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Mon Jul 28 17:49:29 2025 +0200

    Make possible to write a raster with a `BandedSampleModel` where the data 
are stored in a single bank.
---
 .../apache/sis/io/stream/HyperRectangleWriter.java | 39 +++++++++++++++++++---
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/HyperRectangleWriter.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/HyperRectangleWriter.java
index 61aa85eeb3..30f001d47d 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/HyperRectangleWriter.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/HyperRectangleWriter.java
@@ -23,8 +23,10 @@ import java.awt.Rectangle;
 import java.awt.image.Raster;
 import java.awt.image.DataBuffer;
 import java.awt.image.SampleModel;
+import java.awt.image.BandedSampleModel;
 import java.awt.image.ComponentSampleModel;
 import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.PixelInterleavedSampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
 import java.awt.image.RasterFormatException;
 import org.apache.sis.util.ArraysExt;
@@ -265,7 +267,18 @@ public class HyperRectangleWriter {
         /**
          * Creates a new writer for raster data described by the given sample 
model.
          * The returned writer will need to be applied repetitively for each 
bank
-         * if {@link #bankIndices()} returns an array with a length greater 
than one.
+         * if {@link #numBanks()} returns a value greater than one.
+         *
+         * <h4>Banded versus interleaved</h4>
+         * If the given sample model is an instance of {@link 
BandedSampleModel},
+         * then this method will unconditionally handle each band as if it was 
stored in a separated bank,
+         * even if it would be more efficient to handle the data as a {@link 
PixelInterleavedSampleModel}.
+         * For example, the GeoTIFF writer does its own analysis of the sample 
model for deciding whether
+         * to declare in <abbr>TIFF</abbr> tags that the data are in  "planar" 
or "chunky" configuration.
+         * The {@code HyperRectangleWriter} must follow that configuration.
+         *
+         * <p>If the given sample model is the generic {@link 
ComponentSampleModel}, then this method decides
+         * automatically whether the banded or pixel interleaved sample model 
is the best match for the data.</p>
          *
          * @param  sm  the sample model of the rasters to write.
          * @return writer for rasters using the specified sample model (never 
{@code null}).
@@ -276,7 +289,23 @@ public class HyperRectangleWriter {
             scanlineStride = sm.getScanlineStride();
             bankIndices    = sm.getBankIndices();
             bandOffsets    = sm.getBandOffsets();
-            if (ArraysExt.allEquals(bankIndices, bankIndices[0])) {
+            boolean isInterleaved = (sm instanceof 
PixelInterleavedSampleModel);
+            if (!(isInterleaved  ||  sm instanceof BandedSampleModel)) {
+                /*
+                 * Generic `ComponentSampleModel`. Detect whether it can be 
handled as interleaved.
+                 * The sample model shall use only one bank (actually, that 
condition is true even
+                 * for `PixelInterleavedSampleModel`). Furthermore, the index 
of each sample value
+                 * (relative to the base index) should be inside a pixel 
stride.
+                 */
+                int min = Integer.MAX_VALUE;
+                int max = Integer.MIN_VALUE;    // (max - min) defaut to 1 if 
`bandOffsets` is empty.
+                for (int b : bandOffsets) {
+                    if (b < min) min = b;
+                    if (b > max) max = b;
+                }
+                isInterleaved = (max - min) < pixelStride;
+            }
+            if (isInterleaved && ArraysExt.allEquals(bankIndices, 
bankIndices[0])) {
                 /*
                  * PixelInterleavedSampleModel (at least conceptually, no 
matter the actual type).
                  * The returned `HyperRectangleWriter` instance may write all 
sample values in a
@@ -430,7 +459,7 @@ public class HyperRectangleWriter {
         /**
          * Creates a new writer for raster data described by the given sample 
model.
          * The returned writer will need to be applied repetitively for each 
bank
-         * if {@link #bankIndices()} returns an array with a length greater 
than one.
+         * if {@link #numBanks()} returns a value greater than one.
          *
          * @param  sm  the sample model of the rasters to write.
          * @return writer for rasters using the specified sample model (never 
{@code null}).
@@ -448,7 +477,7 @@ public class HyperRectangleWriter {
         /**
          * Creates a new writer for data of the specified raster.
          * The returned writer will need to be applied repetitively for each 
bank
-         * if {@link #bankIndices()} returns an array with a length greater 
than one.
+         * if {@link #numBanks()} returns a value greater than one.
          *
          * <h4>Tile size</h4>
          * Many formats such as GeoTIFF require that all tiles have the same 
size,
@@ -520,7 +549,7 @@ public class HyperRectangleWriter {
          * Returns the offset to add to a bank to write with {@code 
HyperRectangleWriter}.
          * This is in addition of offsets declared in {@link 
DataBuffer#getOffsets()}.
          *
-         * @param  i  index from 0 inclusive to {@link #numBanks()} exclusive.
+         * @param  i             index from 0 inclusive to {@link #numBanks()} 
exclusive.
          * @param  bufferOffset  the value of <code>{@link 
DataBuffer#getOffsets()}[bankIndex(i)]</code>.
          * @return offset of a banks to write with {@code 
HyperRectangleWriter}.
          */

Reply via email to