This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit b4604cdd7df5c2f0bd88bddeaba476c63c108d9e
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat Jun 13 13:18:46 2026 +0200

    Anticipate for the reuse of `ImageModel` in a future version.
---
 .../sis/storage/geoheif/CoverageBuilder.java       | 32 +++++++++++-----
 .../main/org/apache/sis/storage/geoheif/Image.java |  2 +-
 .../org/apache/sis/storage/geoheif/ImageModel.java | 44 ++++++++++++++--------
 .../apache/sis/storage/geoheif/ImageResource.java  |  6 +--
 .../sis/storage/geoheif/ResourceBuilder.java       |  4 +-
 5 files changed, 57 insertions(+), 31 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/CoverageBuilder.java
 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/CoverageBuilder.java
index 4f2c8033e6..1cbabfe5f5 100644
--- 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/CoverageBuilder.java
+++ 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/CoverageBuilder.java
@@ -69,9 +69,13 @@ import org.apache.sis.pending.jdk.JDK18;
  */
 final class CoverageBuilder implements Emptiable {
     /**
-     * The data store which is creating a grid coverage.
+     * The resource which is creating a grid coverage.
+     *
+     * @todo A future version could store a map of {@link ImageModel} in the 
resource builder
+     *       for the case where an image is tiled and each tile has the same 
image description.
+     *       It would avoid recreating the same color model and sample model 
many times.
      */
-    final GeoHeifStore store;
+    private final ResourceBuilder owner;
 
     /**
      * An index of the image to build, for information purpose only.
@@ -180,17 +184,17 @@ final class CoverageBuilder implements Emptiable {
     /**
      * Creates a new builder with the given properties.
      *
-     * @param  store            the data store which is creating a grid 
coverage.
+     * @param  owner            the resource which is creating a grid coverage.
      * @param  imageIndex       an index of the image, for information purpose 
only.
      * @param  properties       source of coverage properties for this 
coverage item.
      * @param  duplicatedBoxes  names of boxes that were duplicated. Used for 
logging a warning only once per type of box.
      */
-    CoverageBuilder(final GeoHeifStore store,
+    CoverageBuilder(final ResourceBuilder owner,
                     final int imageIndex,
                     final ItemProperties.ForID properties,
                     final Set<String> duplicatedBoxes)
     {
-        this.store = store;
+        this.owner = owner;
         this.imageIndex = imageIndex;
         unknownBoxes = new LinkedHashMap<>();
         if (properties == null) {
@@ -281,7 +285,7 @@ final class CoverageBuilder implements Emptiable {
             if (duplicated) {
                 final String type = Box.formatFourCC(property.type());
                 if (duplicatedBoxes.add(type)) {
-                    store.warning(Errors.Keys.DuplicatedElement_1, type);
+                    store().warning(Errors.Keys.DuplicatedElement_1, type);
                 }
             }
         }
@@ -350,7 +354,7 @@ final class CoverageBuilder implements Emptiable {
                 sj.add(id.toString());
             }
             final var record = new LogRecord(level, 
message.append(sj).append('.').toString());
-            store.warning(record);
+            store().warning(record);
         }
         return essential;
     }
@@ -408,12 +412,21 @@ final class CoverageBuilder implements Emptiable {
         return new ImageResource(this, tiles.toArray(Image[]::new), null);
     }
 
+    /**
+     * Returns the data store which is creating a grid coverage.
+     *
+     * @return the data store which is creating a grid coverage.
+     */
+    public final GeoHeifStore store() {
+        return owner.store;
+    }
+
     /**
      * Returns a name for the resource to create and opportunistically adds it 
to the metadata.
      * This method should be invoked exactly once.
      */
     public final GenericName name() {
-        GenericName gn = store.createComponentName(name);
+        GenericName gn = store().createComponentName(name);
         metadata().addIdentifier(gn, MetadataBuilder.Scope.RESOURCE);
         return gn;
     }
@@ -487,7 +500,7 @@ final class CoverageBuilder implements Emptiable {
      */
     final void setImageLayout(final Image image) throws DataStoreException, 
IOException {
         if (imageModel == null) {
-            imageModel = new ImageModel(image.getImageType(store));
+            imageModel = new ImageModel(image.getImageType(store()), this);
         }
     }
 
@@ -534,6 +547,7 @@ final class CoverageBuilder implements Emptiable {
      * @throws DataStoreException if the "grid to <abbr>CRS</abbr>" transform 
cannot be created.
      */
     public final GridGeometry gridGeometry() throws DataStoreException {
+        final GeoHeifStore store = store();
         final var extent = new GridExtent(width, height);
         MathTransform gridToCRS = null;
         if (affine != null) {
diff --git 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/Image.java
 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/Image.java
index f662062f3c..cea5719bb0 100644
--- 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/Image.java
+++ 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/Image.java
@@ -79,7 +79,7 @@ abstract class Image {
         byteOrder    = builder.byteOrder();
         numXTiles    = builder.numTiles(0);
         numYTiles    = builder.numTiles(1);
-        listeners    = builder.store.listeners();
+        listeners    = builder.store().listeners();
         // Do NOT invoke `builder.sampleModel()`, because that information is 
not available for all types.
     }
 
diff --git 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageModel.java
 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageModel.java
index c7fa5c9c51..9c285ab3d0 100644
--- 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageModel.java
+++ 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageModel.java
@@ -76,17 +76,11 @@ final class ImageModel {
     private final SampleDimension[] sampleDimensions;
 
     /**
-     * Creates a new image model from the given Image I/O specifier.
-     *
-     * @param  type  the image specifier from the Image I/O <abbr>API</abbr>.
+     * index of the image which has been used for deriving the sample 
dimensions.
+     * This is used by {@link #sampleDimensions} for detecting if we can skip 
the
+     * reconstruction of sample dimensions.
      */
-    ImageModel(final ImageTypeSpecifier type) {
-        colorModel  = type.getColorModel();
-        sampleModel = type.getSampleModel();
-        dataType    = DataType.forDataBufferType(sampleModel.getDataType());
-        sampleDimensions = null;
-        defaultBandNames = null;
-    }
+    private final int imageIndex;
 
     /**
      * Computes date type, color model, sample model, and sample dimensions.
@@ -168,8 +162,9 @@ final class ImageModel {
                 sb.setName(band);
             }
             defaultBandNames[band] = sb.getName();
-            var source = new CoverageModifier.BandSource(builder.store, 
builder.imageIndex, band, numBands, dataType);
-            builder.metadata().addNewBand(sampleDimensions[band] = 
builder.store.customizer.customize(source, sb));
+            final GeoHeifStore store = builder.store();
+            var source = new CoverageModifier.BandSource(store, 
builder.imageIndex, band, numBands, dataType);
+            builder.metadata().addNewBand(sampleDimensions[band] = 
store.customizer.customize(source, sb));
             sb.clear();
             if (bitDepth == 0) {
                 bitDepth = Component.DEFAULT_BIT_DEPTH;
@@ -253,27 +248,44 @@ final class ImageModel {
             colorModel = cb.createRGB(sampleModel);
         }
         this.colorModel = colorModel;
+        imageIndex = builder.imageIndex;
+    }
+
+    /**
+     * Creates a new image model from the given Image I/O specifier.
+     *
+     * @param  builder  the builder which is creating a grid coverage.
+     * @param  type     the image specifier from the Image I/O 
<abbr>API</abbr>.
+     */
+    ImageModel(final ImageTypeSpecifier type, final CoverageBuilder builder) {
+        colorModel  = type.getColorModel();
+        sampleModel = type.getSampleModel();
+        dataType    = DataType.forDataBufferType(sampleModel.getDataType());
+        imageIndex  = builder.imageIndex;
+        sampleDimensions = null;
+        defaultBandNames = null;
     }
 
     /**
      * Returns the sample dimensions.
      * If the {@code coverage} argument is null, it is assumed the same as at 
construction time.
      *
-     * @param  builder  builder of the coverage for which to create sample 
dimensions, or {@code null}.
+     * @param  builder  builder of the coverage for which to create sample 
dimensions.
      * @return the sample dimensions.
      * @throws DataStoreContentException if the sample dimensions cannot be 
created.
      */
     final List<SampleDimension> sampleDimensions(final CoverageBuilder 
builder) throws DataStoreException {
         SampleDimension[] bands = sampleDimensions;
         boolean share = true;
-        if (builder != null) {
+        if (builder.imageIndex != imageIndex) {
             bands = bands.clone();
             final int numBands = bands.length;
+            final GeoHeifStore store = builder.store();
             final var sb = new SampleDimension.Builder();
             for (int band = 0; band < numBands; band++) {
                 sb.setName(defaultBandNames[band]);
-                var source = new CoverageModifier.BandSource(builder.store, 
builder.imageIndex, band, numBands, dataType);
-                final SampleDimension sd = 
builder.store.customizer.customize(source, sb);
+                var source = new CoverageModifier.BandSource(store, 
builder.imageIndex, band, numBands, dataType);
+                final SampleDimension sd = store.customizer.customize(source, 
sb);
                 if (!sd.equals(bands[band])) {
                     bands[band] = sd;
                     share = false;
diff --git 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageResource.java
 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageResource.java
index 3686e778f6..274aa98072 100644
--- 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageResource.java
+++ 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageResource.java
@@ -129,10 +129,10 @@ final class ImageResource extends 
TiledGridCoverageResource implements StoreReso
      * @throws DataStoreException if the "grid to <abbr>CRS</abbr>" transform 
or the sample dimensions cannot be created.
      */
     ImageResource(final CoverageBuilder builder, Image[] tiles, final Image 
image) throws DataStoreException {
-        super(builder.store);
-        this.store       = builder.store;
+        super(builder.store());
+        this.store       = builder.store();
         identifier       = builder.name();
-        sampleDimensions = builder.imageModel().sampleDimensions(null);
+        sampleDimensions = builder.imageModel().sampleDimensions(builder);
         gridGeometry     = builder.gridGeometry();
         if (tiles == null) {
             // Shall be after the call to `sampleDimensions()`.
diff --git 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ResourceBuilder.java
 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ResourceBuilder.java
index 53cc82e09a..be195117b2 100644
--- 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ResourceBuilder.java
+++ 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ResourceBuilder.java
@@ -64,7 +64,7 @@ final class ResourceBuilder {
     /**
      * The data store for which the resources are built.
      */
-    private final GeoHeifStore store;
+    final GeoHeifStore store;
 
     /**
      * Identifier of the primary item. Should contain at most one element, but 
we are paranoiac.
@@ -323,7 +323,7 @@ final class ResourceBuilder {
             final int imageIndex = (addTo != null ? addTo : resources).size();
             final ItemProperties.ForID itemProperties = 
properties.remove(itemID);
             final CoverageBuilder coverage = 
builders.computeIfAbsent(itemProperties,
-                    (p) -> new CoverageBuilder(store, imageIndex, p, 
duplicatedBoxes));
+                    (p) -> new CoverageBuilder(this, imageIndex, p, 
duplicatedBoxes));
             if (coverage.reportUnknownBoxes(name)) {
                 // Warning already logged by `reportUnknownBoxes(…)`.
                 continue;

Reply via email to