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 87ea45d  Take in account the fact that the valid range of sample 
values may vary for different bands.
87ea45d is described below

commit 87ea45dec4b29a98eaf8c020b0b42d15b458b7d4
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Mar 20 14:33:16 2019 +0100

    Take in account the fact that the valid range of sample values may vary for 
different bands.
---
 .../java/org/apache/sis/image/PixelIterator.java   | 52 ++++++++++++----------
 1 file changed, 28 insertions(+), 24 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 36861d7..5499140 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
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.image;
 
+import java.util.Arrays;
 import java.nio.Buffer;
 import java.awt.Point;
 import java.awt.Dimension;
@@ -408,53 +409,56 @@ 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).
+     * The ranges depend 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 ranges are 
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>
+     * <p>Usually, the range is the same for all bands. A situation where the 
ranges may differ is when an
+     * image uses {@link SinglePixelPackedSampleModel}, in which case the 
number of bits per pixel may vary
+     * for different bands.</p>
      *
-     * @return the range of valid sample values. May be unbounded.
+     * @return the ranges of valid sample values for each band. Ranges may be 
{@linkplain NumberRange#isBounded() unbounded}.
      */
-    public NumberRange<?> getSampleRange() {
+    public NumberRange<?>[] getSampleRanges() {
         final SampleModel model = (currentRaster != null) ? 
currentRaster.getSampleModel() : image.getSampleModel();
-        int numBits;
+        final NumberRange<?>[] ranges = new 
NumberRange<?>[model.getNumBands()];
+        final NumberRange<?> range;
         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();
+            final int numBits = ((MultiPixelPackedSampleModel) 
model).getPixelBitStride();
+            range = NumberRange.create(0, true, (1 << numBits) - 1, true);
         } 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;
+            final int[] masks = ((SinglePixelPackedSampleModel) 
model).getBitMasks();
+            for (int i=0; i<masks.length; i++) {
+                final int numBits = Integer.bitCount(masks[i]);
+                ranges[i] = NumberRange.create(0, true, (1 << numBits) - 1, 
true);
             }
+            return ranges;
         } 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);
-                }
+            final int type = model.getDataType();
+            switch (type) {
+                case DataBuffer.TYPE_BYTE:   range = 
NumberRange.create((short) 0,                 true,  (short)   0xFF,            
true);  break;
+                case DataBuffer.TYPE_USHORT: range = NumberRange.create(       
 0,                 true,          0xFFFF,            true);  break;
+                case DataBuffer.TYPE_SHORT:  range = NumberRange.create(Short. 
 MIN_VALUE,         true,  Short.  MAX_VALUE,         true);  break;
+                case DataBuffer.TYPE_INT:    range = 
NumberRange.create(Integer.MIN_VALUE,         true,  Integer.MAX_VALUE,         
true);  break;
+                case DataBuffer.TYPE_FLOAT:  range = NumberRange.create(Float. 
 NEGATIVE_INFINITY, false, Float.  POSITIVE_INFINITY, false); break;
+                case DataBuffer.TYPE_DOUBLE: range = 
NumberRange.create(Double. NEGATIVE_INFINITY, false, Double. POSITIVE_INFINITY, 
false); break;
+                default: throw new 
IllegalStateException(Errors.format(Errors.Keys.UnknownType_1, type));
             }
-            throw new 
IllegalStateException(Errors.format(Errors.Keys.UnknownType_1, type));
         }
-        return NumberRange.create(0, true, (1 << numBits) - 1, true);
+        Arrays.fill(ranges, range);
+        return ranges;
     }
 
     /**

Reply via email to