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 3b01827 Fix an IllegalArgumentException when creating one-banded
image of type DataBuffer.TYPE_INT. Remove ScaledColorSpace from public API
(provide a static method instead). Remove
ColorModelFactory.getNumBands(ColorModel) method.
3b01827 is described below
commit 3b018271c92399931234f52a387e2be9b9f9a815
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Apr 10 10:41:27 2019 +0200
Fix an IllegalArgumentException when creating one-banded image of type
DataBuffer.TYPE_INT.
Remove ScaledColorSpace from public API (provide a static method instead).
Remove ColorModelFactory.getNumBands(ColorModel) method.
---
.../sis/internal/raster/ColorModelFactory.java | 78 +++++++++++-----------
.../apache/sis/internal/raster/RasterFactory.java | 10 ++-
.../sis/internal/raster/ScaledColorSpace.java | 10 +--
3 files changed, 52 insertions(+), 46 deletions(-)
diff --git
a/core/sis-raster/src/main/java/org/apache/sis/internal/raster/ColorModelFactory.java
b/core/sis-raster/src/main/java/org/apache/sis/internal/raster/ColorModelFactory.java
index cfe9d19..f35deee 100644
---
a/core/sis-raster/src/main/java/org/apache/sis/internal/raster/ColorModelFactory.java
+++
b/core/sis-raster/src/main/java/org/apache/sis/internal/raster/ColorModelFactory.java
@@ -26,6 +26,7 @@ import java.awt.Color;
import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
+import java.awt.image.PackedColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import org.apache.sis.coverage.Category;
@@ -33,7 +34,6 @@ import org.apache.sis.coverage.SampleDimension;
import org.apache.sis.measure.NumberRange;
import org.apache.sis.util.ArraysExt;
import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.collection.WeakHashSet;
import org.apache.sis.util.collection.WeakValueHashMap;
@@ -60,6 +60,8 @@ public final class ColorModelFactory {
* for most kind of color models, except {@link IndexColorModel} which can
potentially be quite big.
* This class works for all color models because they were no technical
reasons to restrict, but the
* real interest is to share index color models.
+ *
+ * @see #unique(ColorModel)
*/
@SuppressWarnings("rawtypes")
private static final WeakHashSet<ColorModelPatch> CACHE = new
WeakHashSet<>(ColorModelPatch.class);
@@ -94,7 +96,7 @@ public final class ColorModelFactory {
/**
* The minimum and maximum sample values.
*/
- private final float minimum, maximum;
+ private final double minimum, maximum;
/**
* In a color map defined by a piecewise function, indices where to store
the first interpolated value in the color map.
@@ -124,8 +126,14 @@ public final class ColorModelFactory {
private final int numBands;
/**
- * The color model type. One of {@link DataBuffer#TYPE_BYTE}, {@link
DataBuffer#TYPE_USHORT},
- * {@link DataBuffer#TYPE_FLOAT} or {@link DataBuffer#TYPE_DOUBLE}.
+ * The color model type. One of the following types:
+ * <ul>
+ * <li>{@link DataBuffer#TYPE_BYTE} or {@link DataBuffer#TYPE_USHORT}:
will create a {@link IndexColorModel} (unless grayscale).</li>
+ * <li>{@link DataBuffer#TYPE_FLOAT} or {@link DataBuffer#TYPE_DOUBLE}:
will create a {@link ComponentColorModel}.</li>
+ * <li>{@link DataBuffer#TYPE_INT}: should create a {@link
PackedColorModel} according {@link java.awt.image.Raster} javadoc
+ * (for compatibility with {@code Raster.createPackedRaster(…)}),
but we nevertheless create {@link ComponentColorModel}
+ * for the 1-banded sample model created by {@link
RasterFactory}.</li>
+ * </ul>
*
* @todo The user may want to set explicitly the number of bits each pixel
occupies.
* We need to think about an API to allows that.
@@ -196,8 +204,8 @@ public final class ColorModelFactory {
if (starts.length != 0) {
starts = ArraysExt.resize(starts, count + 1);
}
- this.minimum = (float) minimum;
- this.maximum = (float) maximum;
+ this.minimum = minimum;
+ this.maximum = maximum;
this.pieceStarts = starts;
this.ARGB = codes;
}
@@ -213,8 +221,8 @@ public final class ColorModelFactory {
* fallback on a generic (but very slow!) color model.
*/
if (type != DataBuffer.TYPE_BYTE && type != DataBuffer.TYPE_USHORT) {
- final ColorSpace colors = new ScaledColorSpace(numBands,
visibleBand, minimum, maximum);
- return new ComponentColorModel(colors, false, false,
Transparency.OPAQUE, type);
+ final ColorSpace colors = createColorSpace(numBands, visibleBand,
minimum, maximum);
+ return unique(new ComponentColorModel(colors, false, false,
Transparency.OPAQUE, type));
}
/*
* If there is no category, constructs a gray scale palette.
@@ -225,7 +233,7 @@ public final class ColorModelFactory {
final int[] nBits = {
DataBuffer.getDataTypeSize(type)
};
- return new ComponentColorModel(cs, nBits, false, true,
Transparency.OPAQUE, type);
+ return unique(new ComponentColorModel(cs, nBits, false, true,
Transparency.OPAQUE, type));
}
/*
* Interpolates the colors in the color palette. Colors that do not
fall
@@ -297,7 +305,7 @@ public final class ColorModelFactory {
* @param bands the sample dimensions for which to create a color
model.
* @param visibleBand the band to be made visible (usually 0). All other
bands, if any will be ignored.
* @param type the color model type. One of {@link
DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT},
- * {@link DataBuffer#TYPE_FLOAT} or {@link
DataBuffer#TYPE_DOUBLE}.
+ * {@link DataBuffer#TYPE_INT}, {@link
DataBuffer#TYPE_FLOAT} or {@link DataBuffer#TYPE_DOUBLE}.
* @param colors the colors to use for each category. The function
may return {@code null}, which means transparent.
* @return a color model suitable for {@link java.awt.image.RenderedImage}
objects with values in the given ranges.
*/
@@ -324,16 +332,14 @@ public final class ColorModelFactory {
* the {@code visibleBand} and ignore the others, but
the existence of all {@code numBands} will
* be at least tolerated. Supplemental bands, even
invisible, are useful for processing.
* @param type the color model type. One of {@link
DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT},
- * {@link DataBuffer#TYPE_FLOAT} or {@link
DataBuffer#TYPE_DOUBLE}.
+ * {@link DataBuffer#TYPE_INT}, {@link
DataBuffer#TYPE_FLOAT} or {@link DataBuffer#TYPE_DOUBLE}.
* @return a color model suitable for {@link java.awt.image.RenderedImage}
objects with values in the given ranges.
*/
public static ColorModel createColorModel(final Map<? extends
NumberRange<?>, ? extends Color[]> categories,
final int visibleBand, final int numBands, final int type)
{
ArgumentChecks.ensureNonNull("categories", categories);
- if (visibleBand < 0 || visibleBand >= numBands) {
- throw new
IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2,
"visibleBand", visibleBand));
- }
+ ArgumentChecks.ensureBetween("visibleBand", 0, numBands - 1,
visibleBand);
final ColorModelFactory key = new ColorModelFactory(categories,
visibleBand, numBands, type);
synchronized (PIECEWISES) {
ColorModel model = PIECEWISES.get(key);
@@ -377,6 +383,25 @@ public final class ColorModelFactory {
}
/**
+ * Returns a color space for images storing pixels as real numbers. The
color space can have an arbitrary number of bands,
+ * but in current implementation only one band is used. Current
implementation create a gray scale.
+ *
+ * <p>The use of this color space is very slow. It should be used only
when no standard color space can be used.</p>
+ *
+ * @param numComponents the number of components.
+ * @param visibleBand the band to use for computing colors.
+ * @param minimum the minimal sample value expected.
+ * @param maximum the maximal sample value expected.
+ * @return the color space for the given range of values.
+ */
+ public static ColorSpace createColorSpace(final int numComponents, final
int visibleBand, final double minimum, final double maximum) {
+ if (numComponents == 1 && minimum == 0 && maximum == 1) {
+ return ColorSpace.getInstance(ColorSpace.CS_GRAY);
+ }
+ return new ScaledColorSpace(numComponents, visibleBand, minimum,
maximum);
+ }
+
+ /**
* Returns a unique instance of the given color model. This method is
automatically invoked by {@code create(…)} methods
* in this class. This {@code unique(ColorModel)} method is public for use
by color models created by other ways.
*
@@ -397,7 +422,7 @@ public final class ColorModelFactory {
* @param mapSize the number of colors in the map.
* @return the suggested transfer type.
*/
- public static int getTransferType(final int mapSize) {
+ private static int getTransferType(final int mapSize) {
return (mapSize <= 256) ? DataBuffer.TYPE_BYTE :
DataBuffer.TYPE_USHORT;
}
@@ -420,29 +445,6 @@ public final class ColorModelFactory {
}
/**
- * Tries to guess the number of bands from the specified color model. The
recommended approach is to invoke
- * {@link java.awt.image.SampleModel#getNumBands()}. This method should be
used only as a fallback when the
- * sample model is not available. This method uses some heuristic rules
for guessing the number of bands,
- * so the return value may not be exact in all cases.
- *
- * @param model the color model for which to guess the number of bands.
May be {@code null}.
- * @return the number of bands in the given color model, or 0 if the given
model is {@code null}.
- */
- public static int getNumBands(final ColorModel model) {
- if (model == null) {
- return 0;
- } else if (model instanceof IndexColorModel) {
- if (model instanceof MultiBandsIndexColorModel) {
- return ((MultiBandsIndexColorModel) model).numBands;
- } else {
- return 1;
- }
- } else {
- return model.getNumComponents();
- }
- }
-
- /**
* Returns the ARGB codes for the given colors. If all colors are
transparent, returns an empty array.
*
* @param colors the colors to convert to ARGB codes, or {@code null}.
diff --git
a/core/sis-raster/src/main/java/org/apache/sis/internal/raster/RasterFactory.java
b/core/sis-raster/src/main/java/org/apache/sis/internal/raster/RasterFactory.java
index 3d877d2..e568d33 100644
---
a/core/sis-raster/src/main/java/org/apache/sis/internal/raster/RasterFactory.java
+++
b/core/sis-raster/src/main/java/org/apache/sis/internal/raster/RasterFactory.java
@@ -111,9 +111,13 @@ public final class RasterFactory extends Static {
return WritableRaster.createInterleavedRaster(buffer,
width, height, scanlineStride, pixelStride, bandOffsets, location);
}
case DataBuffer.TYPE_INT: {
- if (bandOffsets.length == 1) {
- // From JDK javadoc: "To create a 1-band Raster of
type TYPE_INT, use createPackedRaster()".
- return WritableRaster.createPackedRaster(buffer,
width, height, Integer.SIZE, location);
+ if (bandOffsets.length == 1 && pixelStride == 1) {
+ /*
+ * From JDK javadoc: "To create a 1-band Raster of
type TYPE_INT, use createPackedRaster()".
+ * However this would require the creation of a
PackedColorModel subclass. For SIS purposes,
+ * it is easier to create a banded sample model.
+ */
+ return WritableRaster.createBandedRaster(buffer,
width, width, scanlineStride, new int[1], bandOffsets, location);
}
// else fallthrough.
}
diff --git
a/core/sis-raster/src/main/java/org/apache/sis/internal/raster/ScaledColorSpace.java
b/core/sis-raster/src/main/java/org/apache/sis/internal/raster/ScaledColorSpace.java
index 8f745f1..784f4e7 100644
---
a/core/sis-raster/src/main/java/org/apache/sis/internal/raster/ScaledColorSpace.java
+++
b/core/sis-raster/src/main/java/org/apache/sis/internal/raster/ScaledColorSpace.java
@@ -21,19 +21,19 @@ import org.apache.sis.internal.util.Strings;
/**
- * Color space for images storing pixels as real numbers. The color model can
have an
+ * Color space for images storing pixels as real numbers. The color space can
have an
* arbitrary number of bands, but in current implementation only one band is
used.
* Current implementation create a gray scale.
*
- * <p>The use of this color model is very slow.
- * It should be used only when no standard color model can be used.</p>
+ * <p>The use of this color space is very slow.
+ * It should be used only when no standard color space can be used.</p>
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @version 1.0
* @since 1.0
* @module
*/
-public final class ScaledColorSpace extends ColorSpace {
+final class ScaledColorSpace extends ColorSpace {
/**
* For cross-version compatibility.
*/
@@ -72,7 +72,7 @@ public final class ScaledColorSpace extends ColorSpace {
* @param minimum the minimal sample value expected.
* @param maximum the maximal sample value expected.
*/
- public ScaledColorSpace(final int numComponents, final int visibleBand,
final double minimum, final double maximum) {
+ ScaledColorSpace(final int numComponents, final int visibleBand, final
double minimum, final double maximum) {
super(TYPE_GRAY, numComponents);
this.visibleBand = visibleBand;
final double scale = (MAX_VALUE - MIN_VALUE) / (maximum - minimum);