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 bfedee8a7b Delegate to `WritablePixelIterator` the work of setting 
sample values from `IntBinaryOperator`.
bfedee8a7b is described below

commit bfedee8a7bb0306d464b8c563964e76609976f04
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat Feb 21 13:02:11 2026 +0100

    Delegate to `WritablePixelIterator` the work of setting sample values from 
`IntBinaryOperator`.
---
 .../sis/coverage/grid/GridCoverageBuilder.java     | 44 +++++--------------
 .../main/org/apache/sis/image/BandedIterator.java  | 23 ++++++++++
 .../apache/sis/image/WritablePixelIterator.java    | 50 +++++++++++++++++++++-
 .../main/org/apache/sis/image/package-info.java    |  2 +-
 4 files changed, 82 insertions(+), 37 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverageBuilder.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverageBuilder.java
index d1ccc8dd0d..8c08c74153 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverageBuilder.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverageBuilder.java
@@ -37,11 +37,12 @@ import org.opengis.geometry.Envelope;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.image.DataType;
 import org.apache.sis.image.PlanarImage;
-import org.apache.sis.coverage.SampleDimension;
+import org.apache.sis.image.WritablePixelIterator;
 import org.apache.sis.image.internal.shared.ColorScaleBuilder;
 import org.apache.sis.image.internal.shared.ObservableImage;
 import org.apache.sis.image.internal.shared.TiledImage;
 import org.apache.sis.image.internal.shared.WritableTiledImage;
+import org.apache.sis.coverage.SampleDimension;
 import org.apache.sis.feature.internal.Resources;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
@@ -393,7 +394,7 @@ public class GridCoverageBuilder {
      * The number of bands is the number of functions and the color model 
defaults to gray scale.
      * The tiling is unspecified and may change in future versions of Apache 
<abbr>SIS</abbr>.
      *
-     * <p>Each functions will receive pixel coordinates (<var>x</var>, 
<var>y</var>)
+     * <p>Each function will receive pixel coordinates (<var>x</var>, 
<var>y</var>)
      * and shall return the sample value to store in one band of the image at 
that pixel position.
      * The <var>x</var> values will be between 0 inclusive and {@link 
Dimension#width} exclusive.
      * The <var>y</var> values will be between 0 inclusive and {@link 
Dimension#height} exclusive.
@@ -405,40 +406,15 @@ public class GridCoverageBuilder {
      * @return {@code this} for method invocation chaining.
      * @throws IllegalArgumentException if {@code width} or {@code height} is 
negative or equals to zero.
      *
+     * @see WritablePixelIterator#setRemainingPixels(IntBinaryOperator...)
+     *
      * @since 1.7
      */
-    public GridCoverageBuilder setValues(final DataType type, final Dimension 
size, IntBinaryOperator... bands) {
-        final int width, height;
-        ArgumentChecks.ensureStrictlyPositive("width",  width  = size.width);
-        ArgumentChecks.ensureStrictlyPositive("height", height = size.height);
-        ArgumentChecks.ensureNonEmpty("bands", bands);
-        bands = bands.clone();
-        for (int b=0; b<bands.length; b++) {
-            ArgumentChecks.ensureNonNullElement("bands", b, bands[b]);
-        }
-        final WritableRaster data = 
Raster.createBandedRaster(type.toDataBufferType(), width, height, bands.length, 
null);
-        if (bands.length == 1) {
-            /*
-             * This block is not strictly necessary, as the following block is 
general.
-             * But it is a slight optimization for a common case.
-             */
-            final IntBinaryOperator band = bands[0];
-            for (int y=0; y<height; y++) {
-                for (int x=0; x<width; x++) {
-                    data.setSample(x, y, 0, band.applyAsInt(x, y));
-                }
-            }
-        } else {
-            final int[] samples = new int[bands.length];
-            for (int y=0; y<height; y++) {
-                for (int x=0; x<width; x++) {
-                    for (int b=0; b<bands.length; b++) {
-                        samples[b] = bands[b].applyAsInt(x, y);
-                    }
-                    data.setPixel(x, y, samples);
-                }
-            }
-        }
+    public GridCoverageBuilder setValues(final DataType type, final Dimension 
size, final IntBinaryOperator... bands) {
+        // Number of bands, width and height are verified by 
`Raster.createBandedRaster(…)`
+        final WritableRaster data = 
Raster.createBandedRaster(type.toDataBufferType(), size.width, size.height, 
bands.length, null);
+        final WritablePixelIterator i = new 
WritablePixelIterator.Builder().createWritable(data);
+        i.setRemainingPixels(bands);
         return setValues(data);
     }
 
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandedIterator.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandedIterator.java
index 7946d0c533..71af21c212 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandedIterator.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandedIterator.java
@@ -28,6 +28,7 @@ import java.awt.image.Raster;
 import java.awt.image.RenderedImage;
 import java.awt.image.WritableRaster;
 import java.awt.image.WritableRenderedImage;
+import java.util.function.IntBinaryOperator;
 
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
 import org.opengis.coverage.grid.SequenceType;
@@ -297,6 +298,28 @@ final class BandedIterator extends WritablePixelIterator {
         }
     }
 
+    /**
+     * Sets all remaining pixels to sample values computed by the given 
functions.
+     * If the iterator is not in a valid position, then this method behavior 
is undetermined.
+     */
+    @Override
+    public void setRemainingPixels(IntBinaryOperator... bands) {
+        bands = validate(bands);
+        if (bands.length == 1) {    // Slight optimization for a common case.
+            final IntBinaryOperator band = bands[0];
+            while (next()) {
+                destBuffer.setElem(x + xToBuffer, band.applyAsInt(x, y));
+            }
+        } else {
+            while (next()) {
+                final int index = x + xToBuffer;
+                for (int i=0; i<bands.length; i++) {
+                    destBuffer.setElem(i, index, bands[i].applyAsInt(x, y));
+                }
+            }
+        }
+    }
+
     /**
      * Creates a window for floating point values using the given arrays.
      */
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/WritablePixelIterator.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/WritablePixelIterator.java
index 3c15235136..eccbade41e 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/WritablePixelIterator.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/WritablePixelIterator.java
@@ -23,7 +23,9 @@ import java.awt.image.Raster;
 import java.awt.image.RenderedImage;
 import java.awt.image.WritableRaster;
 import java.awt.image.WritableRenderedImage;
+import java.util.function.IntBinaryOperator;
 import org.apache.sis.feature.internal.Resources;
+import org.apache.sis.util.ArgumentChecks;
 
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
 import org.opengis.coverage.grid.SequenceType;
@@ -54,7 +56,7 @@ import org.opengis.coverage.grid.SequenceType;
  *
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.7
  * @since   1.0
  */
 public class WritablePixelIterator extends PixelIterator implements Closeable {
@@ -113,7 +115,6 @@ public class WritablePixelIterator extends PixelIterator 
implements Closeable {
                           final Rectangle subArea, final Dimension window, 
final SequenceType order)
     {
         super(input, subArea, window, order);
-        destRaster  = null;
         destination = output;
         if (output != null) {
             if (!input.getSampleModel().equals(output.getSampleModel())) {
@@ -252,6 +253,51 @@ public class WritablePixelIterator extends PixelIterator 
implements Closeable {
         destRaster.setPixel(x, y, values);
     }
 
+    /**
+     * Returns a clone of the given array where all elements are guaranteed 
non-null.
+     */
+    final IntBinaryOperator[] validate(IntBinaryOperator[] bands) {
+        if (bands.length != numBands) {
+            throw new 
IllegalArgumentException(Resources.format(Resources.Keys.UnexpectedNumberOfBands_2,
 numBands, bands.length));
+        }
+        bands = bands.clone();
+        for (int i=0; i<bands.length; i++) {
+            ArgumentChecks.ensureNonNullElement("bands", i, bands[i]);
+        }
+        return bands;
+    }
+
+    /**
+     * Sets all remaining pixels to sample values computed by the given 
functions.
+     * Each function will receive pixel coordinates (<var>x</var>, 
<var>y</var>)
+     * and shall return the sample value to store in one band of the image at 
that pixel position.
+     * The functions shall be given in the same order as the bands.
+     * Therefore, the function at index <var>i</var> computes the sample 
values of band <var>i</var>.
+     *
+     * @param  bands  functions providing sample values in each band, in order.
+     * @throws IllegalArgumentException if the number of functions is not equal
+     *         to the {@linkplain #getNumBands() number of bands}.
+     *
+     * @since 1.7
+     */
+    public void setRemainingPixels(IntBinaryOperator... bands) {
+        bands = validate(bands);
+        if (bands.length == 1) {    // Slight optimization for a common case.
+            final IntBinaryOperator band = bands[0];
+            while (next()) {
+                destRaster.setSample(x, y, 0, band.applyAsInt(x, y));
+            }
+        } else {
+            final int[] samples = new int[bands.length];
+            while (next()) {
+                for (int i=0; i<bands.length; i++) {
+                    samples[i] = bands[i].applyAsInt(x, y);
+                }
+                destRaster.setPixel(x, y, samples);
+            }
+        }
+    }
+
     /**
      * Sets the data elements (not necessarily band values) of current pixel.
      * The {@code Object} argument is a relatively opaque format (it may be 
{@code int[]}, {@code byte[]}, <i>etc.</i>).
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/package-info.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/package-info.java
index f865d60a57..527d1ee8cc 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/package-info.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/package-info.java
@@ -42,7 +42,7 @@
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.6
+ * @version 1.7
  * @since   1.0
  */
 package org.apache.sis.image;

Reply via email to