sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/04: Move the calculation of sample range into getSampleRange() method since this information is expected to be requested only one or none at all. Take in account the number of bits per pixel. Reorder a few methods for keeping related methods together. Minor formatting.
Date Thu, 14 Mar 2019 22:44:58 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 b9a0ead72af5293156e1f0f07b277b22d431a8fb
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Thu Mar 14 21:11:31 2019 +0100

    Move the calculation of sample range into getSampleRange() method since this information
is expected to be requested only one or none at all.
    Take in account the number of bits per pixel. Reorder a few methods for keeping related
methods together. Minor formatting.
---
 .../java/org/apache/sis/image/PixelIterator.java   | 95 ++++++++++++++--------
 .../org/apache/sis/image/LinearIteratorTest.java   | 14 ++--
 2 files changed, 68 insertions(+), 41 deletions(-)

diff --git a/core/sis-raster/src/main/java/org/apache/sis/image/PixelIterator.java b/core/sis-raster/src/main/java/org/apache/sis/image/PixelIterator.java
index ec36654..36861d7 100644
--- a/core/sis-raster/src/main/java/org/apache/sis/image/PixelIterator.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/image/PixelIterator.java
@@ -25,14 +25,17 @@ import java.awt.image.Raster;
 import java.awt.image.RenderedImage;
 import java.awt.image.WritableRaster;
 import java.awt.image.WritableRenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.MultiPixelPackedSampleModel;
 import java.util.NoSuchElementException;
 import org.opengis.coverage.grid.SequenceType;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.measure.NumberRange;
 
 import static java.lang.Math.floorDiv;
 import static org.apache.sis.internal.util.Numerics.ceilDiv;
-import org.apache.sis.measure.NumberRange;
 
 
 /**
@@ -56,6 +59,7 @@ import org.apache.sis.measure.NumberRange;
  *
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
+ * @author  Johann Sorel (Geomatys)
  * @version 1.0
  * @since   1.0
  * @module
@@ -82,11 +86,6 @@ public abstract class PixelIterator {
     final int numBands;
 
     /**
-     * Value range supported by storage.
-     */
-    final NumberRange sampleRange;
-
-    /**
      * The domain, in pixel coordinates, of the region traversed by this pixel iterator.
      * This may be smaller than the image or raster bounds, but not greater.
      * The lower values are inclusive and the upper values exclusive.
@@ -131,7 +130,6 @@ public abstract class PixelIterator {
         image           = null;
         currentRaster   = data;
         numBands        = data.getNumBands();
-        sampleRange     = rangeForDataType(data.getSampleModel().getDataType());
         tileWidth       = data.getWidth();
         tileHeight      = data.getHeight();
         tileGridXOffset = data.getMinX();
@@ -161,7 +159,6 @@ public abstract class PixelIterator {
         final Rectangle bounds;
         image           = data;
         numBands        = data.getSampleModel().getNumBands();
-        sampleRange     = rangeForDataType(data.getSampleModel().getDataType());
         tileWidth       = data.getTileWidth();
         tileHeight      = data.getTileHeight();
         tileGridXOffset = data.getTileGridXOffset();
@@ -179,16 +176,6 @@ public abstract class PixelIterator {
         windowHeight    = (window != null) ? window.height : 0;
     }
 
-    private static NumberRange<?> rangeForDataType(int dataType) {
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE : return NumberRange.create(0, true, 255, true);
-            case DataBuffer.TYPE_SHORT : return NumberRange.create(Short.MIN_VALUE, true,
Short.MAX_VALUE, true);
-            case DataBuffer.TYPE_USHORT : return NumberRange.create(0, true, 65535, true);
-            case DataBuffer.TYPE_INT : return NumberRange.create(Integer.MIN_VALUE, true,
Integer.MAX_VALUE, true);
-            default : return NumberRange.create(Double.NEGATIVE_INFINITY, true, Double.POSITIVE_INFINITY,
true);
-        }
-    }
-
     /**
      * Computes the intersection between the given bounds and and {@code subArea} if {@code
subArea} is non-null.
      * If the result is empty, then the width and/or height are set to zero (not negative).
@@ -420,6 +407,57 @@ public abstract class PixelIterator {
     }
 
     /**
+     * Returns the range of sample values that can be stored in each band of the rendered
image or raster.
+     * The range depends on the data type (byte, integer, <i>etc.</i>) and the
number of bits per sample.
+     * If the samples are stored as floating point values, then the range is infinite (unbounded).
+     *
+     * <p>{@linkplain SinglePixelPackedSampleModel Some models} do not allow the same
range of values for all bands.
+     * In such case, this method returns the largest range allowed by the model.</p>
+     *
+     * @return the range of valid sample values. May be unbounded.
+     */
+    public NumberRange<?> getSampleRange() {
+        final SampleModel model = (currentRaster != null) ? currentRaster.getSampleModel()
: image.getSampleModel();
+        int numBits;
+        if (model instanceof MultiPixelPackedSampleModel) {
+            /*
+             * This model supports only unsigned integer types: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT
+             * or DataBuffer.TYPE_INT (considered unsigned in the context of this sample
model).  The number
+             * of bits per sample is defined by the "pixel bit stride".
+             */
+            numBits = ((MultiPixelPackedSampleModel) model).getPixelBitStride();
+        } else if (model instanceof SinglePixelPackedSampleModel) {
+            /*
+             * This model supports only unsigned integer types: TYPE_BYTE, TYPE_USHORT, TYPE_INT
(considered
+             * unsigned in the context of this sample model). The number of bits may vary
for each band.
+             */
+            numBits = 0;
+            for (int mask : ((SinglePixelPackedSampleModel) model).getBitMasks()) {
+                final int n = Integer.bitCount(mask);
+                if (n > numBits) numBits = n;
+            }
+        } else {
+            /*
+             * For all other sample models, the range is determined by the data type.
+             * The following cases invoke the NumberRange constructor which best fit the
data type.
+             */
+            int type = DataBuffer.TYPE_UNDEFINED;
+            if (model != null) {
+                switch (type = model.getDataType()) {
+                    case DataBuffer.TYPE_BYTE:   return NumberRange.create((short) 0,   
             true,  (short)   0xFF,            true);
+                    case DataBuffer.TYPE_USHORT: return NumberRange.create(        0,   
             true,          0xFFFF,            true);
+                    case DataBuffer.TYPE_SHORT:  return NumberRange.create(Short.  MIN_VALUE,
        true,  Short.  MAX_VALUE,         true);
+                    case DataBuffer.TYPE_INT:    return NumberRange.create(Integer.MIN_VALUE,
        true,  Integer.MAX_VALUE,         true);
+                    case DataBuffer.TYPE_FLOAT:  return NumberRange.create(Float.  NEGATIVE_INFINITY,
false, Float.  POSITIVE_INFINITY, false);
+                    case DataBuffer.TYPE_DOUBLE: return NumberRange.create(Double. NEGATIVE_INFINITY,
false, Double. POSITIVE_INFINITY, false);
+                }
+            }
+            throw new IllegalStateException(Errors.format(Errors.Keys.UnknownType_1, type));
+        }
+        return NumberRange.create(0, true, (1 << numBits) - 1, true);
+    }
+
+    /**
      * Returns the order in which pixels are traversed. {@link SequenceType#LINEAR} means
that pixels on the first
      * row are traversed from left to right, then pixels on the second row from left to right,
<i>etc.</i>
      * A {@code null} value means that the iteration order is unspecified.
@@ -429,17 +467,7 @@ public abstract class PixelIterator {
     public abstract SequenceType getIterationOrder();
 
     /**
-     * Returns the pixel coordinates of the region where this iterator is doing the iteration.
-     * If no region was specified at construction time, then this method returns the image
or raster bounds.
-     *
-     * @return pixel coordinates of the iteration region.
-     */
-    public Rectangle getDomain() {
-        return new Rectangle(lowerX, lowerY, upperX - lowerX, upperY - lowerY);
-    }
-
-    /**
-     * Returns the number of bands (samples per pixel) from Image or Raster within this Iterator.
+     * Returns the number of bands (samples per pixel) in the image or raster.
      *
      * @return number of bands.
      */
@@ -448,12 +476,13 @@ public abstract class PixelIterator {
     }
 
     /**
-     * Returns the numeric range supported by datas from Image or Raster within this Iterator.
+     * Returns the pixel coordinates of the region where this iterator is doing the iteration.
+     * If no region was specified at construction time, then this method returns the image
or raster bounds.
      *
-     * @return primitive samples range.
+     * @return pixel coordinates of the iteration region.
      */
-    public NumberRange<?> getSampleRange() {
-        return sampleRange;
+    public Rectangle getDomain() {
+        return new Rectangle(lowerX, lowerY, upperX - lowerX, upperY - lowerY);
     }
 
     /**
diff --git a/core/sis-raster/src/test/java/org/apache/sis/image/LinearIteratorTest.java b/core/sis-raster/src/test/java/org/apache/sis/image/LinearIteratorTest.java
index 3cb6835..aa86d81 100644
--- a/core/sis-raster/src/test/java/org/apache/sis/image/LinearIteratorTest.java
+++ b/core/sis-raster/src/test/java/org/apache/sis/image/LinearIteratorTest.java
@@ -25,18 +25,16 @@ import java.awt.image.Raster;
 import java.awt.image.WritableRaster;
 import java.awt.image.WritableRenderedImage;
 import java.nio.FloatBuffer;
+import org.opengis.coverage.grid.SequenceType;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.util.ArraysExt;
 import org.junit.After;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 import org.junit.Ignore;
 import org.junit.Test;
-import org.opengis.coverage.grid.SequenceType;
+
+import static org.junit.Assert.*;
+
 
 /**
  * This base class tests the linear read-write iterator
@@ -47,7 +45,7 @@ import org.opengis.coverage.grid.SequenceType;
  * @version 1.0
  * @since   1.0
  */
-public class LinearIteratorTest extends TestCase {
+public final strictfp class LinearIteratorTest extends TestCase {
     /**
      * The pixel iterator being tested.
      * This field is initialized by a call to one of the {@code createPixelIterator(…)}
methods.
@@ -230,7 +228,7 @@ public class LinearIteratorTest extends TestCase {
             }
             value += 7;             // Arbitrary offset.
         }
-        
+
         assertEquals("Number of expected values", expected.length, n);
         return image;
     }


Mime
View raw message