sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 04/07: Fix the case where subsampling is larger than tile size.
Date Thu, 29 Jul 2021 13:07:19 GMT
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 23ff7d0843bae4b6b10eb1309a0f025426e6739f
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Sat Jul 24 23:19:58 2021 +0200

    Fix the case where subsampling is larger than tile size.
---
 .../org/apache/sis/storage/geotiff/DataSubset.java | 34 ++++++++++++++++------
 .../sis/internal/storage/TiledGridCoverage.java    |  7 ++++-
 .../sis/test/storage/CoverageReadConsistency.java  |  3 ++
 3 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataSubset.java
b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataSubset.java
index 920ecb7..97170c6 100644
--- a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataSubset.java
+++ b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataSubset.java
@@ -292,18 +292,34 @@ class DataSubset extends TiledGridCoverage implements Localized {
             final Point  origin      = new Point();
             final long[] offsets     = new long[tileOffsets.size() / numTiles];
             final long[] byteCounts  = new long[tileByteCounts.size() / numTiles];
+            boolean needsCompaction  = false;
             for (int i=0; i<numMissings; i++) {
                 final Tile tile = missings[i];
-                origin.x = tile.originX;
-                origin.y = tile.originY;
-                tile.getRegionInsideTile(lower, upper, subsampling, BIDIMENSIONAL);
-                tile.copyTileInfo(tileOffsets,    offsets,    numTiles);
-                tile.copyTileInfo(tileByteCounts, byteCounts, numTiles);
-                for (int b=0; b<offsets.length; b++) {
-                    offsets[b] = addExact(offsets[b], reader().origin);
+                if (tile.getRegionInsideTile(lower, upper, subsampling, BIDIMENSIONAL)) {
+                    origin.x = tile.originX;
+                    origin.y = tile.originY;
+                    tile.copyTileInfo(tileOffsets,    offsets,    numTiles);
+                    tile.copyTileInfo(tileByteCounts, byteCounts, numTiles);
+                    for (int b=0; b<offsets.length; b++) {
+                        offsets[b] = addExact(offsets[b], reader().origin);
+                    }
+                    result[tile.indexInResultArray] = tile.cache(
+                            readSlice(offsets, byteCounts, lower, upper, subsampling, origin));
+                } else {
+                    needsCompaction = true;
+                }
+            }
+            /*
+             * If the subsampling is larger than tile size, some tiles were empty and excluded.
+             * The corresponding elements in the `result` array were left to the null value.
+             * We need to compact the array by removing those null elements.
+             */
+            if (needsCompaction) {
+                int n = 0;
+                for (final WritableRaster tile : result) {
+                    if (tile != null) result[n++] = tile;
                 }
-                result[tile.indexInResultArray] = tile.cache(
-                        readSlice(offsets, byteCounts, lower, upper, subsampling, origin));
+                return Arrays.copyOf(result, n);
             }
         }
         return result;
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java
index 7ea234e..3b30e63 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java
@@ -584,8 +584,9 @@ public abstract class TiledGridCoverage extends GridCoverage {
          * @param  upper        a pre-allocated array where to store relative coordinates
after the last pixel.
          * @param  subsampling  a pre-allocated array where to store subsampling.
          * @param  dimension    number of elements to write in the {@code lower} and {@code
upper} arrays.
+         * @return {@code true} on success, or {@code false} if the tile is empty.
          */
-        public void getRegionInsideTile(final long[] lower, final long[] upper, final int[]
subsampling, int dimension) {
+        public boolean getRegionInsideTile(final long[] lower, final long[] upper, final
int[] subsampling, int dimension) {
             System.arraycopy(coverage.subsampling, 0, subsampling, 0, dimension);
             while (--dimension >= 0) {
                 final int  tileSize  = coverage.tileSize[dimension];
@@ -620,8 +621,12 @@ public abstract class TiledGridCoverage extends GridCoverage {
                         offset += s;
                     }
                 }
+                if (offset >= upper[dimension]) {
+                    return false;
+                }
                 lower[dimension] = offset;
             }
+            return true;
         }
 
         /**
diff --git a/storage/sis-storage/src/test/java/org/apache/sis/test/storage/CoverageReadConsistency.java
b/storage/sis-storage/src/test/java/org/apache/sis/test/storage/CoverageReadConsistency.java
index 585db35..a3f5286 100644
--- a/storage/sis-storage/src/test/java/org/apache/sis/test/storage/CoverageReadConsistency.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/test/storage/CoverageReadConsistency.java
@@ -354,6 +354,9 @@ nextSlice:  for (;;) {
         if (allowSubsamplings) {
             final int subX = subsampling[0];
             final int subY = subsampling[1];
+            if (subX > image.getTileWidth() || subY > image.getTileHeight()) {
+                return null;        // `SubsampledImage` does not support this case.
+            }
             int offX = StrictMath.floorMod(image.getMinX(), subX);
             int offY = StrictMath.floorMod(image.getMinY(), subY);
             if (offX != 0) {sliceAOI.x--; offX = subX - offX;}

Mime
View raw message