sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/10: BandSelectImage should propagate known image properties, with band reduction if needed.
Date Wed, 29 Jul 2020 16:18:54 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 f48ab74134a37e9aef1c421bcf6a5c02ce960fb7
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Mon Jul 27 18:38:54 2020 +0200

    BandSelectImage should propagate known image properties, with band reduction if needed.
---
 .../java/org/apache/sis/image/BandSelectImage.java | 67 +++++++++++++++++++++-
 .../org/apache/sis/image/BandSelectImageTest.java  | 52 ++++++++++++++---
 2 files changed, 109 insertions(+), 10 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/BandSelectImage.java b/core/sis-feature/src/main/java/org/apache/sis/image/BandSelectImage.java
index b27fcc4..8234fd9 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/BandSelectImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/BandSelectImage.java
@@ -16,6 +16,10 @@
  */
 package org.apache.sis.image;
 
+import java.util.Set;
+import java.util.Hashtable;
+import java.lang.reflect.Array;
+import java.awt.Image;
 import java.awt.image.Raster;
 import java.awt.image.BufferedImage;
 import java.awt.image.RenderedImage;
@@ -25,6 +29,7 @@ import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.internal.coverage.j2d.ImageUtilities;
 import org.apache.sis.internal.coverage.j2d.ColorModelFactory;
+import org.apache.sis.internal.jdk9.JDK9;
 
 
 /**
@@ -38,6 +43,15 @@ import org.apache.sis.internal.coverage.j2d.ColorModelFactory;
  */
 final class BandSelectImage extends SourceAlignedImage {
     /**
+     * Properties to inherit from the source image, after bands reduction if applicable.
+     *
+     * @see #getProperty(String)
+     */
+    private static final Set<String> INHERITED_PROPERTIES = JDK9.setOf(
+            GRID_GEOMETRY_KEY, POSITIONAL_ACCURACY_KEY,         // Properties to forward
as-is.
+            SAMPLE_RESOLUTIONS_KEY, STATISTICS_KEY);            // Properties to forward
after band reduction.
+
+    /**
      * The selected bands.
      */
     private final int[] bands;
@@ -72,18 +86,67 @@ final class BandSelectImage extends SourceAlignedImage {
         /*
          * If the image is an instance of `BufferedImage`, create the subset immediately
          * (reminder: this operation will not copy pixel data). It allows us to return a
-         * new instance of `BufferedImage`, which has optimization in Java2D.
+         * new instance of `BufferedImage`, which has optimizations in Java2D.
          */
         if (source instanceof BufferedImage) {
             final BufferedImage bi = (BufferedImage) source;
+            @SuppressWarnings("UseOfObsoleteCollectionType")
+            final Hashtable<String,Object> properties = new Hashtable<>(8);
+            for (final String key : INHERITED_PROPERTIES) {
+                final Object value = getProperty(bi, key, bands);
+                if (value != Image.UndefinedProperty) {
+                    properties.put(key, value);
+                }
+            }
             return new BufferedImage(cm,
                     bi.getRaster().createWritableChild(0, 0, bi.getWidth(), bi.getHeight(),
0, 0, bands),
-                    bi.isAlphaPremultiplied(), null);
+                    bi.isAlphaPremultiplied(), properties);
         }
         return new BandSelectImage(source, cm, bands.clone());
     }
 
     /**
+     * Returns the names of all recognized properties,
+     * or {@code null} if this image has no properties.
+     */
+    @Override
+    public String[] getPropertyNames() {
+        return getPropertyNames(INHERITED_PROPERTIES, null);
+    }
+
+    /**
+     * Gets a property from this image.
+     */
+    @Override
+    public Object getProperty(final String key) {
+        if (INHERITED_PROPERTIES.contains(key)) {
+            return getProperty(getSource(), key, bands);
+        } else {
+            return super.getProperty(key);
+        }
+    }
+
+    /**
+     * Gets a property from the given image, reducing the number of dimensions if needed.
+     * It is caller responsibility to verify that the given key is one of the keys enumerated
+     * in {@link #INHERITED_PROPERTIES}.
+     */
+    private static Object getProperty(final RenderedImage source, final String key, final
int[] bands) {
+        final Object value = source.getProperty(key);
+        if (value != null && (key.equals(SAMPLE_RESOLUTIONS_KEY) || key.equals(STATISTICS_KEY)))
{
+            final Class<?> componentType = value.getClass().getComponentType();
+            if (componentType != null) {
+                final Object reduced = Array.newInstance(componentType, bands.length);
+                for (int i=0; i<bands.length; i++) {
+                    Array.set(reduced, i, Array.get(value, bands[i]));
+                }
+                return reduced;
+            }
+        }
+        return value;
+    }
+
+    /**
      * Creates a raster sharing the same data buffer than the source image but showing only
a subset of the bands.
      *
      * @param  tileX     the column index of the tile to compute.
diff --git a/core/sis-feature/src/test/java/org/apache/sis/image/BandSelectImageTest.java
b/core/sis-feature/src/test/java/org/apache/sis/image/BandSelectImageTest.java
index bbcdac3..4575edc 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/image/BandSelectImageTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/image/BandSelectImageTest.java
@@ -17,6 +17,7 @@
 package org.apache.sis.image;
 
 import java.util.Random;
+import java.util.Hashtable;
 import java.awt.image.DataBuffer;
 import java.awt.image.Raster;
 import java.awt.image.WritableRaster;
@@ -83,13 +84,29 @@ public final strictfp class BandSelectImageTest extends TestCase {
         } else {
             cm = ColorModelFactory.createGrayScale(DataBuffer.TYPE_BYTE, numBands, checkedBand,
Byte.MIN_VALUE, Byte.MAX_VALUE);
         }
-        bufferedImage = new BufferedImage(cm, (WritableRaster) image.getTile(0, 0), false,
null);
+        @SuppressWarnings("UseOfObsoleteCollectionType")
+        final Hashtable<String,Object> properties = new Hashtable<>();
+        final double[] resolutions = new double[numBands];
+        for (int i=0; i<numBands; i++) resolutions[i] = resolution(i);
+        properties.put(PlanarImage.SAMPLE_RESOLUTIONS_KEY, resolutions);
+        bufferedImage = new BufferedImage(cm, (WritableRaster) image.getTile(0, 0), false,
properties);
+    }
+
+    /**
+     * Computes a dummy resolution for the given band.
+     */
+    private static double resolution(final int band) {
+        return (band+1) * 10;
     }
 
     /**
      * Verifies that the given image contains the data expected for the {@code checkedBand}.
+     *
+     * @param  image        the image resulting from a call to {@link ImageProcessor#selectBands(RenderedImage,
int...)}.
+     * @param  numBands     expected number of bands.
+     * @param  checkedBand  band in which to check values.
      */
-    private static void verify(final RenderedImage image, final int numBands, final int checkedBand)
{
+    private static void verifySamples(final RenderedImage image, final int numBands, final
int checkedBand) {
         final Raster tile = image.getTile(0,0);
         assertEquals("numBands", numBands, tile.getNumBands());
         assertEquals("numBands", numBands, ImageUtilities.getNumBands(image));
@@ -103,6 +120,22 @@ public final strictfp class BandSelectImageTest extends TestCase {
     }
 
     /**
+     * Verifies the property values.
+     *
+     * @param  image  the image resulting from a call to {@link ImageProcessor#selectBands(RenderedImage,
int...)}.
+     * @param  bands  selected bands.
+     */
+    private static void verifyProperties(final RenderedImage image, final int... bands) {
+        assertArrayEquals("propertyNames", new String[] {PlanarImage.SAMPLE_RESOLUTIONS_KEY},
image.getPropertyNames());
+        final double[] resolutions = (double[]) image.getProperty(PlanarImage.SAMPLE_RESOLUTIONS_KEY);
+        final double[] expected = new double[bands.length];
+        for (int i=0; i<bands.length; i++) {
+            expected[i] = resolution(bands[i]);
+        }
+        assertArrayEquals(expected, resolutions, STRICT);
+    }
+
+    /**
      * Tests bands selection in an image using index color model.
      */
     @Test
@@ -113,20 +146,22 @@ public final strictfp class BandSelectImageTest extends TestCase {
         assertSame(bufferedImage,  processor.selectBands(bufferedImage, 0, 1, 2));
 
         RenderedImage test = processor.selectBands(image, 1);
-        verify(test, 1, 0);
+        verifySamples(test, 1, 0);
 
         test = processor.selectBands(image, 0, 1);
-        verify(test, 2, 1);
+        verifySamples(test, 2, 1);
 
         test = processor.selectBands(bufferedImage, 1);
         assertInstanceOf("image", BufferedImage.class, test);
         assertEquals("colorModel", IndexColorModel.class, test.getColorModel().getClass());
-        verify(test, 1, 0);
+        verifySamples(test, 1, 0);
+        verifyProperties(test, 1);
 
         test = processor.selectBands(bufferedImage, 0, 1);
         assertInstanceOf("image", BufferedImage.class, test);
         assertInstanceOf("colorModel", IndexColorModel.class, test.getColorModel());
-        verify(test, 2, 1);
+        verifySamples(test, 2, 1);
+        verifyProperties(test, 0, 1);
     }
 
     /**
@@ -140,11 +175,12 @@ public final strictfp class BandSelectImageTest extends TestCase {
         assertSame(bufferedImage, processor.selectBands(bufferedImage, 0, 1, 2, 3));
 
         RenderedImage test = processor.selectBands(image, 3, 0, 2);
-        verify(test, 3, 2);
+        verifySamples(test, 3, 2);
 
         test = processor.selectBands(bufferedImage, 3, 0, 2);
         assertInstanceOf("image", BufferedImage.class, test);
         assertNotNull("colorModel", test.getColorModel());
-        verify(test, 3, 2);
+        verifySamples(test, 3, 2);
+        verifyProperties(test, 3, 0, 2);
     }
 }


Mime
View raw message