[jira] [Resolved] (SIS-320) Enable SIS to run is security-constrained environments
[ 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
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.
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.
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