sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] branch geoapi-4.0 updated: Add a method for computing immediately an image.
Date Sun, 29 Mar 2020 22:10:52 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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 2f78016  Add a method for computing immediately an image.
2f78016 is described below

commit 2f78016df4177d58e5c38752cbaac1833027b3cd
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Mon Mar 30 00:10:08 2020 +0200

    Add a method for computing immediately an image.
---
 .../java/org/apache/sis/image/ImageProcessor.java  | 67 ++++++++++++++++++++++
 .../sis/internal/coverage/j2d/TiledImage.java      |  3 +
 2 files changed, 70 insertions(+)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java b/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java
index bec2a66..d6f0b87 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java
@@ -18,13 +18,18 @@ package org.apache.sis.image;
 
 import java.util.logging.Filter;
 import java.util.logging.LogRecord;
+import java.awt.image.Raster;
+import java.awt.image.BufferedImage;
 import java.awt.image.RenderedImage;
 import java.awt.image.ImagingOpException;
+import java.awt.image.RasterFormatException;
 import org.apache.sis.math.Statistics;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.coverage.j2d.ImageUtilities;
+import org.apache.sis.internal.coverage.j2d.TileOpExecutor;
+import org.apache.sis.internal.coverage.j2d.TiledImage;
 
 
 /**
@@ -340,4 +345,66 @@ public class ImageProcessor {
         }
         return source;
     }
+
+    /**
+     * Computes all tiles immediately, then return an image will all tiles ready.
+     * Computations will use many threads if {@linkplain #getExecutionMode() execution mode}
is parallel.
+     *
+     * @param  source  the image to compute immediately (may be {@code null}).
+     * @return image with all tiles computed, or {@code null} if the given image was null.
+     * @throws ImagingOpException if an exception occurred during {@link RenderedImage#getTile(int,
int)} call.
+     *         This exception wraps the original exception as its {@linkplain ImagingOpException#getCause()
cause}.
+     */
+    public RenderedImage prefetch(final RenderedImage source) {
+        if (source == null || source instanceof BufferedImage || source instanceof TiledImage)
{
+            return source;
+        }
+        final Prefetch worker = new Prefetch(source);
+        if (parallel(source)) {
+            worker.parallelReadFrom(source);
+        } else {
+            worker.readFrom(source);
+        }
+        return new TiledImage(source.getColorModel(), source.getWidth(), source.getHeight(),
+                              source.getMinTileX(), source.getMinTileY(), worker.tiles);
+    }
+
+    /**
+     * A worker for prefetching tiles in an image.
+     */
+    private static final class Prefetch extends TileOpExecutor {
+        /** Number of tiles in a row. */
+        private final int numXTiles;
+
+        /** Image properties for converting pixel coordinates to tile indices. */
+        private final long tileWidth, tileHeight, tileGridXOffset, tileGridYOffset;
+
+        /** The tiles in a row-major fashion. */
+        final Raster[] tiles;
+
+        /** Prepares an instance for prefetching tiles from the given image. */
+        Prefetch(final RenderedImage source) {
+            super(source, null);
+            numXTiles       = source.getNumXTiles();
+            tileWidth       = source.getTileWidth();
+            tileHeight      = source.getTileHeight();
+            tileGridXOffset = source.getTileGridXOffset();
+            tileGridYOffset = source.getTileGridYOffset();
+            tiles           = new Raster[Math.multiplyExact(source.getNumYTiles(), numXTiles)];
+        }
+
+        /** Invoked in a when a tile have been computed, possibly in a background thread.
*/
+        @Override protected void readFrom(final Raster source) {
+            final long tx = Math.floorDiv(source.getMinX() - tileGridXOffset, tileWidth);
+            final long ty = Math.floorDiv(source.getMinY() - tileGridYOffset, tileHeight);
+            final int index = Math.toIntExact(tx + ty*numXTiles);
+            synchronized (tiles) {
+                if (tiles[index] != null) {
+                    throw new RasterFormatException(Errors.format(
+                            Errors.Keys.DuplicatedElement_1, "Tile[" + tx + ", " + ty + ']'));
+                }
+                tiles[index] = source;
+            }
+        }
+    }
 }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/TiledImage.java
b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/TiledImage.java
index bf363d4..0747f6b 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/TiledImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/TiledImage.java
@@ -28,6 +28,9 @@ import org.apache.sis.util.ArgumentChecks;
  * This class may become public in a future version, but not yet because managing large tiled
  * images would require a more sophisticated class than current implementation.
  *
+ * <p>This class should not perform any computation; all tiles are given at construction
time.
+ * This requirement makes this class thread-safe and concurrent without the need for synchronization.</p>
+ *
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @version 1.1


Mime
View raw message