[jira] [Resolved] (SIS-320) Enable SIS to run is security-constrained environments

2021-10-23 Thread Martin Desruisseaux (Jira)


 [ 
https://issues.apache.org/jira/browse/SIS-320?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Martin Desruisseaux resolved SIS-320.
-
Fix Version/s: 1.2
   Resolution: Won't Fix

{{java.security.AccessController}} is deprecated for removal since Java 17. All 
usages of this class will be removed.

> Enable SIS to run is security-constrained environments
> --
>
> Key: SIS-320
> URL: https://issues.apache.org/jira/browse/SIS-320
> Project: Spatial Information Systems
>  Issue Type: Improvement
>  Components: Metadata, Referencing, Storage, Utilities
>Affects Versions: 0.3, 0.4, 0.5, 0.6, 0.7
>Reporter: Martin Desruisseaux
>Assignee: Martin Desruisseaux
>Priority: Major
>  Labels: Jigsaw
> Fix For: 1.2
>
>
> Wraps some code necessary to SIS working in 
> {{AccessController.doPrivileged(...)}} blocks. Examples:
> {code:java}
> String dir = AccessController.doPrivileged((PrivilegedAction) () -> {
> return System.getenv("SIS_DATA");
> });
> {code}
> We should not wrap all security-sensitive request for information, but only 
> those that are needed for SIS working. Examples:
> * Environment variable value for {{SIS_DATA}}.
> * Property value for {{"java.naming.factory.initial"}}, 
> {{"derby.system.home"}}.
> * Call to {{Field.setAccessible(true)}} in {{clone()}} methods for setting 
> final fields.
> Information for which we do *not* request privileged actions at this time:
> * MBean registration.
> * Property value for {{"java.home"}}.
> * Call to {{Field.setAccessible(true)}} on deserialization for setting final 
> transient fields.
> Initial patch for SIS has been submitted by Guilhem Légal.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)


[jira] [Created] (SIS-525) Remove AccessController usage

2021-10-23 Thread Martin Desruisseaux (Jira)
Martin Desruisseaux created SIS-525:
---

 Summary: Remove AccessController usage
 Key: SIS-525
 URL: https://issues.apache.org/jira/browse/SIS-525
 Project: Spatial Information Systems
  Issue Type: New Feature
  Components: Features, Metadata, Referencing, Utilities
Affects Versions: 1.0, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3
Reporter: Martin Desruisseaux
Assignee: Martin Desruisseaux
 Fix For: 1.2


{{java.security.AccessController}} is deprecated for removal since Java 17. All 
usage of this class should be removed. There would be no real lost of 
functionality since we never completed the security policy work.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)


[sis] branch geoapi-4.0 updated: Merge the "clip" and "mask" methods in a single "mask" method with boolean argument.

2021-10-23 Thread desruisseaux
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 d5601f3  Merge the "clip" and "mask" methods in a single "mask" method 
with boolean argument.
d5601f3 is described below

commit d5601f3eca46f519d5f8ef14b7832237f0066f98
Author: Martin Desruisseaux 
AuthorDate: Sat Oct 23 18:24:57 2021 +0200

Merge the "clip" and "mask" methods in a single "mask" method with boolean 
argument.
---
 .../sis/coverage/grid/GridCoverageProcessor.java   | 37 +++---
 .../java/org/apache/sis/image/ImageProcessor.java  | 37 ++
 2 files changed, 21 insertions(+), 53 deletions(-)

diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
index d79cea9..c631458 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
@@ -163,42 +163,27 @@ public class GridCoverageProcessor implements Cloneable {
 }
 
 /**
- * Applies a clip defined by a region of interest (ROI).
- * All pixels outside the given ROI are set to the {@linkplain 
#getFillValues() fill values}.
+ * Applies a mask defined by a region of interest (ROI). If {@code 
maskInside} is {@code true},
+ * then all pixels inside the given ROI are set to the {@linkplain 
#getFillValues() fill values}.
+ * If {@code maskInside} is {@code false}, then the mask is reversed:
+ * the pixels set to fill values are the ones outside the ROI.
  *
- * @param  source  the coverage on which to apply a clip.
- * @param  clipregion (in arbitrary CRS) of pixels to keep.
- * @return a coverage with clip applied.
- * @throws TransformException if ROI coordinates can not be transformed to 
grid coordinates.
- *
- * @since 1.2
- */
-public GridCoverage clip(final GridCoverage source, final RegionOfInterest 
clip) throws TransformException {
-ArgumentChecks.ensureNonNull("source", source);
-ArgumentChecks.ensureNonNull("clip", clip);
-final Shape roi = clip.toShape2D(source.getGridGeometry());
-RenderedImage data = source.render(null);
-data = imageProcessor.clip(data, roi);
-return new GridCoverage2D(source, data);
-}
-
-/**
- * Applies a mask defined by a region of interest (ROI).
- * All pixels inside the given ROI are set to the {@linkplain 
#getFillValues() fill values}.
- *
- * @param  source  the coverage on which to apply a mask.
- * @param  maskregion (in arbitrary CRS) of pixels to mask.
+ * @param  source  the coverage on which to apply a mask.
+ * @param  maskregion (in arbitrary CRS) of the mask.
+ * @param  maskInside  {@code true} for masking pixels inside the shape, 
or {@code false} for masking outside.
  * @return a coverage with mask applied.
  * @throws TransformException if ROI coordinates can not be transformed to 
grid coordinates.
  *
  * @since 1.2
  */
-public GridCoverage mask(final GridCoverage source, final RegionOfInterest 
mask) throws TransformException {
+public GridCoverage mask(final GridCoverage source, final RegionOfInterest 
mask, final boolean maskInside)
+throws TransformException
+{
 ArgumentChecks.ensureNonNull("source", source);
 ArgumentChecks.ensureNonNull("mask", mask);
 final Shape roi = mask.toShape2D(source.getGridGeometry());
 RenderedImage data = source.render(null);
-data = imageProcessor.mask(data, roi);
+data = imageProcessor.mask(data, roi, maskInside);
 return new GridCoverage2D(source, data);
 }
 
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 ab99ab8..08866cb 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
@@ -744,43 +744,26 @@ public class ImageProcessor implements Cloneable {
 }
 
 /**
- * Applies a clip defined by a geometric shape.
- * All pixels outside the given shape are set to the {@linkplain 
#getFillValues() fill values}.
- *
- * @param  source  the image on which to apply a clip.
- * @param  clipgeometric area (in pixel coordinates) of pixels to keep.
- * @return an image with clip applied.
- *
- * @since 1.2
- */
-public RenderedImage clip(final RenderedImage source, final Shape clip) {
-ArgumentChecks.ensureNonNull("source", source);
-

[sis] branch geoapi-4.0 updated: Compute only the tiles that intersect the bounding box of the mask. It saves memory and computation when a tile does not intersect the clip.

2021-10-23 Thread desruisseaux
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 6fb53af  Compute only the tiles that intersect the bounding box of the 
mask. It saves memory and computation when a tile does not intersect the clip.
6fb53af is described below

commit 6fb53af600bbab808fde0f1330c12328e5c42676
Author: Martin Desruisseaux 
AuthorDate: Sat Oct 23 15:32:41 2021 +0200

Compute only the tiles that intersect the bounding box of the mask.
It saves memory and computation when a tile does not intersect the clip.
---
 .../java/org/apache/sis/image/MaskedImage.java | 203 -
 .../java/org/apache/sis/image/package-info.java|   7 +
 2 files changed, 165 insertions(+), 45 deletions(-)

diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java 
b/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java
index 1266a54..9ac7dab 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java
@@ -19,6 +19,7 @@ package org.apache.sis.image;
 import java.util.Objects;
 import java.nio.ByteBuffer;
 import java.nio.LongBuffer;
+import java.awt.Rectangle;
 import java.awt.Point;
 import java.awt.Shape;
 import java.awt.Color;
@@ -33,6 +34,7 @@ import java.awt.image.MultiPixelPackedSampleModel;
 import java.lang.ref.SoftReference;
 import java.nio.ByteOrder;
 import org.apache.sis.internal.coverage.j2d.FillValues;
+import org.apache.sis.internal.coverage.j2d.ImageUtilities;
 import org.apache.sis.internal.coverage.j2d.TilePlaceholder;
 
 import static org.apache.sis.internal.util.Numerics.ceilDiv;
@@ -60,12 +62,23 @@ final class MaskedImage extends SourceAlignedImage {
 private final boolean maskInside;
 
 /**
+ * Bounds of the {@linkplain #clip} in pixels coordinates and in tile 
coordinates.
+ * The later provides a fast way to determine if a tile intersects the 
mask.
+ * The bounds are computed together when first needed.
+ *
+ * @see #getMaskTiles()
+ */
+private transient volatile Rectangle maskBounds, maskTiles;
+
+/**
  * The clip after rasterization. Each element contains 8 pixel values.
  * Index of pixel value at coordinate (x,y) can be obtained as below:
  *
  * {@preformat java
- * int element = mask[y*scanlineStride + x/Byte.SIZE];
- * int shift   = (Byte.SIZE-1) - (x & (Byte.SIZE-1));
+ * int xm  = x - maskBounds.x;
+ * int xy  = y - maskBounds.y;
+ * int element = mask[ym*scanlineStride + xm/Byte.SIZE];
+ * int shift   = (Byte.SIZE-1) - (xm & (Byte.SIZE-1));
  * int pixel   = (element >>> shift) & 1;
  * }
  *
@@ -124,37 +137,68 @@ final class MaskedImage extends SourceAlignedImage {
 }
 
 /**
+ * Returns the bounds of the {@linkplain #clip} in tile coordinates.
+ * It provides a fast way to determine if a tile intersects the mask.
+ */
+private Rectangle getMaskTiles() {
+Rectangle bt = maskTiles;
+if (bt == null) {
+synchronized (this) {
+bt = maskTiles;
+if (bt == null) {
+final RenderedImage source = getSource();
+final Rectangle bp = clip.getBounds();
+ImageUtilities.clipBounds(source, bp);
+bt = new Rectangle();
+if (!bp.isEmpty()) {
+final int xmax = ImageUtilities.pixelToTileX(source, 
bp.x + bp.width  - 1) + 1;
+final int ymax = ImageUtilities.pixelToTileY(source, 
bp.y + bp.height - 1) + 1;
+bt.width  = xmax - (bt.x = 
ImageUtilities.pixelToTileX(source, bp.x));
+bt.height = ymax - (bt.y = 
ImageUtilities.pixelToTileY(source, bp.y));
+}
+maskBounds = bp;
+maskTiles  = bt;
+}
+}
+}
+return bt;
+}
+
+/**
  * Returns pixel values of the mask in a multi pixel packed array.
  * After conversion to {@link LongBuffer}, index of pixel value at
  * coordinate (x,y) can be obtained as below:
  *
  * {@preformat java
- * int element = mask[y*scanlineStride + x/Long.SIZE];
- * int shift   = (Long.SIZE-1) - (x & (Long.SIZE-1));
+ * int xm  = x - maskBounds.x;
+ * int xy  = y - maskBounds.y;
+ * int element = mask[ym*scanlineStride + xm/Long.SIZE];
+ * int shift   = (Long.SIZE-1) - (xm & (Long.SIZE-1));
  * int pixel   = (element >>> shift) & 1;
  * }
+ *
+ * Pre-conditions
+ * The {@link #getMaskTiles()} method must have been invoked at least once 
before