You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2020/03/29 22:10:52 UTC
[sis] branch geoapi-4.0 updated: Add a method for computing
immediately an image.
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 <ma...@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