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 c9a672132b340426af8beacbf1e9d0bf96b07809
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sat Dec 14 13:10:38 2024 +0100

    Move the `createPackedRGB(…)` and createBandedRGB(…)` methods in a new 
`ColorModelBuilder` class.
    In gives more flexibility for configuring the RGB color model to create.
---
 .../sis/coverage/privy/ColorModelBuilder.java      | 302 +++++++++++++++++++++
 .../sis/coverage/privy/ColorModelFactory.java      | 103 +------
 .../main/org/apache/sis/image/Colorizer.java       |   3 +-
 .../sis/storage/geotiff/ImageFileDirectory.java    |   7 +-
 .../org/apache/sis/storage/geotiff/WriterTest.java |   4 +-
 .../sis/storage/sql/postgis/RasterReader.java      |   3 +-
 .../org/apache/sis/storage/esri/RasterStore.java   |  13 +-
 .../org/apache/sis/storage/gdal/TiledResource.java |   3 +-
 8 files changed, 323 insertions(+), 115 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelBuilder.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelBuilder.java
new file mode 100644
index 0000000000..6a9327bc71
--- /dev/null
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelBuilder.java
@@ -0,0 +1,302 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.coverage.privy;
+
+import java.util.Arrays;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.BandedSampleModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.SampleModel;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.ArraysExt;
+
+
+/**
+ * Helper classes for creating a <abbr>RGB</abbr> color model suitable for a 
sample model.
+ * Usage:
+ *
+ * <ol>
+ *   <li>Create a new {@link ColorModelBuilder} instance.</li>
+ *   <li>Invoke setter methods.</li>
+ *   <li>Invoke {@link #createPackedRGB()} or {@link #createBandedRGB()}.</li>
+ *   <li>Discards {@code ColorModelBuilder}. Each instance shall be used only 
once.</li>
+ * </ol>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ *
+ * @see ColorModelType
+ */
+public final class ColorModelBuilder {
+    /**
+     * The usual position of the alpha channel.
+     * This channel is usually immediately after the <abbr>RGB</abbr> 
components.
+     */
+    private static final int STANDARD_ALPHA_BAND = 3;
+
+    /**
+     * Number of bits per sample, or {@code null} for the default values in 
all bands.
+     * The array length is the number of bands: 3 for <abbr>RGB</abbr> or 4 
for <abbr>ARGB</abbr>.
+     * Each array element may be 0, which means to use the default for that 
specific band.
+     * If no number of bits is specified, the default is {@value Byte#SIZE}.
+     */
+    private int[] bitsPerSample;
+
+    /**
+     * Index of the alpha channel (usually the last band), or -1 if none.
+     */
+    private int alphaBand;
+
+    /**
+     * Whether the alpha value (if present) is premultiplied.
+     */
+    private boolean isAlphaPremultiplied;
+
+    /**
+     * Creates a new builder initialized with default values.
+     */
+    public ColorModelBuilder() {
+        alphaBand = -1;
+    }
+
+    /**
+     * Sets the number of bits per sample as a potentially different number 
for each band.
+     * The given array is stored without copy on the assumption that is will 
not be modified
+     * (this is okay for internal API).
+     * If no number of bits is specified, the default is {@value Byte#SIZE}.
+     *
+     * @param  numBits  number of bits per sample, or {@code null} for the 
default values.
+     * @return {@code this} for method calls chaining.
+     */
+    public ColorModelBuilder bitsPerSample(final int[] numBits) {
+        bitsPerSample = numBits;
+        if (hasDefaultBitsPerSample()) {
+            bitsPerSample = null;
+        }
+        return this;
+    }
+
+    /**
+     * Sets the number of bits per sample as a unique number for all bands.
+     * If no number of bits is specified, the default is {@value Byte#SIZE}.
+     *
+     * @param  numBits  number of bits per sample in each band.
+     * @return {@code this} for method calls chaining.
+     * @throws IllegalArgumentException if the given value is out of bounds.
+     */
+    public ColorModelBuilder bitsPerSample(final int numBits) {
+        ArgumentChecks.ensureBetween("bitsPerSample", 1, Integer.SIZE, 
numBits);
+        if (numBits != Byte.SIZE) {
+            bitsPerSample = new int[STANDARD_ALPHA_BAND + 1];
+            Arrays.fill(bitsPerSample, numBits);
+        } else {
+            bitsPerSample = null;
+        }
+        return this;
+    }
+
+    /**
+     * Returns whether this builder currently uses the default number of bits 
per sample.
+     */
+    private boolean hasDefaultBitsPerSample() {
+        if (bitsPerSample != null) {
+            for (int numBits : bitsPerSample) {
+                if (numBits != Byte.SIZE) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the number of bits per sample in the given band.
+     * If no number of bits per sample was specified, the default value is 
{@link Byte#SIZE}.
+     *
+     * @param  band  the band index for which to get the number of bits per 
sample.
+     * @param  max   maximal value allowed.
+     * @return the number of bits per sample in the given band, guaranteed 
between 1 and {@code max} inclusive.
+     * @throws IllegalArgumentException if the number of bits per sample is 
out of bounds.
+     */
+    private int getBitsPerSample(final int band, final int max) {
+        if (bitsPerSample != null && band < bitsPerSample.length) {
+            int numBits = bitsPerSample[band];
+            if (numBits != 0) {
+                ArgumentChecks.ensureBetween("bitsPerSample", 1, max, numBits);
+                return numBits;
+            }
+        }
+        return Byte.SIZE;
+    }
+
+    /**
+     * Sets the index of the alpha channel. It should be the band immediately 
after the color bands,
+     * but some color model allows other position.
+     *
+     * @param  index  of the alpha channel (usually the last band), or -1 if 
none.
+     * @return {@code this} for method calls chaining.
+     */
+    public ColorModelBuilder alphaBand(final int index) {
+        if (index >= 0) {
+            ArgumentChecks.ensureBetween("alphaBand", 0, STANDARD_ALPHA_BAND, 
index);
+        }
+        alphaBand = index;
+        return this;
+    }
+
+    /**
+     * Sets whether the alpha value (if present) is premultiplied.
+     *
+     * @param  p  whether the alpha value (if present) is premultiplied.
+     * @return {@code this} for method calls chaining.
+     */
+    public ColorModelBuilder isAlphaPremultiplied(final boolean p) {
+        isAlphaPremultiplied = p;
+        return this;
+    }
+
+    /**
+     * Returns the color space of the color model to build.
+     * The current implementation fixes the color space to <abbr>RGB</abbr>,
+     * but it may change in a future implementation if needed.
+     *
+     * <h4>Limitation</h4>
+     * Note that {@link #createPackedRGB()} is limited to color spaces of the 
<abbr>RGB</abbr> family.
+     * This is a restriction of {@link DirectColorModel}.
+     */
+    private static ColorSpace colorSpace() {
+        return ColorSpace.getInstance(ColorSpace.CS_sRGB);
+    }
+
+    /**
+     * Returns the data type to use for the given number of bits.
+     */
+    private static int dataType(final int numBits) {
+        return (numBits <=  Byte.SIZE) ? DataBuffer.TYPE_BYTE :
+               (numBits <= Short.SIZE) ? DataBuffer.TYPE_USHORT : 
DataBuffer.TYPE_INT;
+    }
+
+    /**
+     * Creates a RGB color model for use with {@link 
SinglePixelPackedSampleModel}.
+     * Pixel values are packed in a single integer (usually 32-bits) per pixel.
+     * Color components are separated using a bitmask for each 
<abbr>RGBA</abbr> value.
+     *
+     * <h4>Limitations</h4>
+     * The color model is restricted to the <abbr>RGB</abbr> family.
+     *
+     * @return color model for use with {@link 
java.awt.image.SinglePixelPackedSampleModel}.
+     * @throws IllegalArgumentException if any argument specified to the 
builder is invalid.
+     */
+    public ColorModel createPackedRGB() {
+        if (!isAlphaPremultiplied && alphaBand == STANDARD_ALPHA_BAND && 
hasDefaultBitsPerSample()) {
+            return ColorModel.getRGBdefault();
+        }
+        // Red, Green, Blue, Alpha masks in that order.
+        final int[] masks = new int[STANDARD_ALPHA_BAND + 1];
+        int numBits = 0;
+        for (int i=STANDARD_ALPHA_BAND - 1; i >= -1; i--) {
+            int band = i;
+            if (band < 0) {
+                band = alphaBand;
+                if (band < 0) break;
+            }
+            int n = getBitsPerSample(band, Math.min(Byte.SIZE, Integer.SIZE - 
numBits));
+            masks[i] = ((1 << n) - 1) << numBits;
+            numBits += n;
+        }
+        return ColorModelFactory.unique(new DirectColorModel(colorSpace(),
+                numBits, masks[0], masks[1], masks[2], masks[3], 
isAlphaPremultiplied, dataType(numBits)));
+    }
+
+    /**
+     * Creates a RGB color model for use with {@link BandedSampleModel}.
+     * Each color component (sample value) is stored in a separated data 
element.
+     *
+     * <h4>Limitations</h4>
+     * The current version requires the alpha channel (if present) to be the 
last band.
+     * If this condition is not met, this method returns {@code null}.
+     *
+     * @return color model for use with {@link 
java.awt.image.BandedSampleModel}.
+     * @throws IllegalArgumentException if any argument specified to the 
builder is invalid.
+     */
+    public ColorModel createBandedRGB() {
+        final int numBands;
+        final int transparency;
+        final boolean hasAlpha = (alphaBand >= 0);
+        if (hasAlpha) {
+            if (alphaBand != STANDARD_ALPHA_BAND) {
+                throw new IllegalArgumentException("Alpha channel must be 
after the color components.");
+            }
+            numBands = 4;
+            transparency = Transparency.TRANSLUCENT;
+        } else {
+            numBands = 3;
+            transparency = Transparency.OPAQUE;
+        }
+        int[] numBits = bitsPerSample;
+        numBits = ArraysExt.resize(numBits != null ? numBits : 
ArraysExt.EMPTY_INT, numBands);
+        int maxSize = 0;
+        for (int i=0; i<numBands; i++) {
+            if (numBits[i] == 0) {
+                if (numBits == bitsPerSample) {
+                    numBits = numBits.clone();
+                }
+                numBits[i] = Byte.SIZE;
+            } else {
+                maxSize = Math.max(maxSize, numBits[i]);
+            }
+        }
+        return ColorModelFactory.unique(new ComponentColorModel(colorSpace(),
+                numBits, hasAlpha, isAlphaPremultiplied, transparency, 
dataType(maxSize)));
+    }
+
+    /**
+     * Creates a <abbr>RGB</abbr> color model for the given sample model.
+     * The sample model shall use integer type and have 3 or 4 bands.
+     * This method may return {@code null} if the color model cannot be 
created.
+     *
+     * @param  targetModel  the sample model for which to create a color model.
+     * @return the color model, or {@code null} if the given sample model is 
not supported.
+     * @throws IllegalArgumentException if any argument specified to the 
builder is invalid.
+     */
+    public ColorModel create(final SampleModel targetModel) {
+check:  if (ImageUtilities.isIntegerType(targetModel)) {
+            final int numBands = targetModel.getNumBands();
+            switch (numBands) {
+                case 3:  alphaBand = -1; break;
+                case 4:  alphaBand = STANDARD_ALPHA_BAND; break;
+                default: break check;
+            }
+            bitsPerSample = targetModel.getSampleSize();
+            if (targetModel.getNumDataElements() != 1) {
+                return createBandedRGB();
+            } else {
+                for (int i=0; i<numBands; i++) {
+                    if (bitsPerSample[i] > Byte.SIZE) {
+                        break check;
+                    }
+                }
+                return createPackedRGB();
+            }
+        }
+        return null;
+    }
+}
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelFactory.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelFactory.java
index a17bb04d1d..c71c4b5379 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelFactory.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelFactory.java
@@ -455,7 +455,7 @@ public final class ColorModelFactory {
      * @param  cm  the color model.
      * @return a unique instance of the given color model.
      */
-    private static ColorModel unique(final ColorModel cm) {
+    static ColorModel unique(final ColorModel cm) {
         return CACHE.unique(cm);
     }
 
@@ -591,107 +591,6 @@ public final class ColorModelFactory {
         return createGrayScale(model.getDataType(), model.getNumBands(), 
visibleBand, minimum, maximum);
     }
 
-    /**
-     * Creates a RGB color model for the given sample model.
-     * The sample model shall use integer type and have 3 or 4 bands.
-     * This method may return {@code null} if the color model cannot be 
created.
-     *
-     * @param  targetModel           the sample model for which to create a 
color model.
-     * @param  isAlphaPremultiplied  whether the alpha value (if present) is 
premultiplied.
-     * @return the color model, or null if a precondition does not hold.
-     */
-    public static ColorModel createRGB(final SampleModel targetModel, final 
boolean isAlphaPremultiplied) {
-check:  if (ImageUtilities.isIntegerType(targetModel)) {
-            final int numBands = targetModel.getNumBands();
-            final int alphaBand;
-            switch (numBands) {
-                case 3:  alphaBand = -1; break;
-                case 4:  alphaBand =  3; break;
-                default: break check;
-            }
-            int bitsPerSample = 0;
-            for (int i=0; i<numBands; i++) {
-                bitsPerSample = Math.max(bitsPerSample, 
targetModel.getSampleSize(i));
-            }
-            if (targetModel.getNumDataElements() != 1) {
-                return createBandedRGB(bitsPerSample, alphaBand, 
isAlphaPremultiplied);
-            } else if (bitsPerSample <= Byte.SIZE) {
-                return createPackedRGB(bitsPerSample, alphaBand, 
isAlphaPremultiplied);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Creates a RGB color model for use with {@code 
SinglePixelPackedSampleModel}.
-     * Pixel values are packed in a single integer (usually 32-bits) per pixel.
-     * Color components are separated using a bitmask for each 
<abbr>RGBA</abbr> value.
-     *
-     * @param  bitsPerSample         number of bits per sample, between 1 and 
8 inclusive.
-     * @param  alphaBand             index of the alpha channel (usually the 
last band), or -1 if none.
-     * @param  isAlphaPremultiplied  whether the alpha value (if present) is 
premultiplied.
-     * @return color model for use with {@link 
java.awt.image.SinglePixelPackedSampleModel}.
-     */
-    public static ColorModel createPackedRGB(final int bitsPerSample, final 
int alphaBand, final boolean isAlphaPremultiplied) {
-        if (bitsPerSample == Byte.SIZE && alphaBand == 3 && 
!isAlphaPremultiplied) {
-            return ColorModel.getRGBdefault();
-        }
-        ArgumentChecks.ensureBetween("bitsPerSample", 1, Byte.SIZE, 
bitsPerSample);
-        final int[] masks = new int[4];         // Red, Green, Blue, Alpha 
masks in that order.
-        int mask = (1 << bitsPerSample) - 1;    // Start with blue = 0xFF 
(usually).
-        for (int i=2; i >= 0; i--) {
-            masks[i] = mask;
-            mask <<= bitsPerSample;
-        }
-        int numBands = 3;
-        if (alphaBand >= 0) {
-            System.arraycopy(masks, alphaBand, masks, alphaBand+1, 3 - 
alphaBand);
-            masks[alphaBand] = mask;
-            numBands = 4;
-        }
-        int numBits = numBands * bitsPerSample;
-        int dataType = (numBits <=  Byte.SIZE) ? DataBuffer.TYPE_BYTE :
-                       (numBits <= Short.SIZE) ? DataBuffer.TYPE_USHORT : 
DataBuffer.TYPE_INT;
-        var cm = new 
DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
-                        numBits, masks[0], masks[1], masks[2], masks[3],
-                        isAlphaPremultiplied, dataType);
-        return unique(cm);
-    }
-
-    /**
-     * Creates a RGB color model for use with {@code BandedSampleModel}.
-     * Each color component (sample value) is stored in a separated data 
element.
-     *
-     * <h4>Limitations</h4>
-     * The current version requires the alpha channel (if present) to be the 
last band.
-     * If this condition is not met, this method returns {@code null}.
-     *
-     * @param  bitsPerSample         number of bits per sample, between 1 and 
32 inclusive.
-     * @param  alphaBand             index of the alpha channel (usually the 
last band), or -1 if none.
-     * @param  isAlphaPremultiplied  whether the alpha value (if present) is 
premultiplied.
-     * @return color model for use with {@link 
java.awt.image.BandedSampleModel}, or {@code null}.
-     */
-    public static ColorModel createBandedRGB(final int bitsPerSample, final 
int alphaBand, final boolean isAlphaPremultiplied) {
-        ArgumentChecks.ensureBetween("bitsPerSample", 1, Integer.SIZE, 
bitsPerSample);
-        final int[] numBits;
-        final int transparency;
-        final boolean hasAlpha = (alphaBand >= 0);
-        if (hasAlpha) {
-            if (alphaBand != 3) {
-                return null;        // Limitation documented in method Javadoc.
-            }
-            numBits = new int[4];
-            transparency = Transparency.TRANSLUCENT;
-        } else {
-            numBits = new int[3];
-            transparency = Transparency.OPAQUE;
-        }
-        Arrays.fill(numBits, bitsPerSample);
-        var cm = new 
ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
-                        numBits, hasAlpha, isAlphaPremultiplied, transparency, 
DataBuffer.TYPE_BYTE);
-        return unique(cm);
-    }
-
     /**
      * Creates a color model with only a subset of the bands of the given 
color model. The returned color model
      * is compatible with a {@linkplain 
SampleModel#createSubsetSampleModel(int[]) subset sample model} created
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Colorizer.java 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Colorizer.java
index 82ae3baa77..cc55809967 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Colorizer.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Colorizer.java
@@ -31,6 +31,7 @@ import java.awt.image.IndexColorModel;
 import java.awt.image.RenderedImage;
 import org.apache.sis.coverage.Category;
 import org.apache.sis.coverage.SampleDimension;
+import org.apache.sis.coverage.privy.ColorModelBuilder;
 import org.apache.sis.coverage.privy.ColorScaleBuilder;
 import org.apache.sis.coverage.privy.ColorModelFactory;
 import org.apache.sis.measure.NumberRange;
@@ -160,7 +161,7 @@ public interface Colorizer extends 
Function<Colorizer.Target, Optional<ColorMode
      * The color model is <abbr>RGB</abbr> for image having 3 bands, or 
<abbr>ARGB</abbr> for images having 4 bands.
      * In the latter case, the color components are considered <em>not</em> 
premultiplied by the alpha value.
      */
-    Colorizer ARGB = (target) -> 
Optional.ofNullable(ColorModelFactory.createRGB(target.getSampleModel(), 
false));
+    Colorizer ARGB = (target) -> Optional.ofNullable(new 
ColorModelBuilder().create(target.getSampleModel()));
 
     /**
      * Creates a colorizer which will interpolate the given colors in the 
given range of values.
diff --git 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
index abe78d10dc..1e7dbed31b 100644
--- 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
+++ 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
@@ -52,6 +52,7 @@ import org.apache.sis.io.stream.ChannelDataInput;
 import org.apache.sis.coverage.SampleDimension;
 import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.coverage.grid.GridExtent;
+import org.apache.sis.coverage.privy.ColorModelBuilder;
 import org.apache.sis.coverage.privy.ColorModelFactory;
 import org.apache.sis.coverage.privy.SampleModelFactory;
 import org.apache.sis.util.Numbers;
@@ -1760,10 +1761,12 @@ final class ImageFileDirectory extends DataCube {
                 }
                 case PHOTOMETRIC_INTERPRETATION_RGB: {
                     if (alphaBand >= 0) alphaBand += 3;     // Must add the 
number of color bands.
+                    final var builder = new 
ColorModelBuilder().bitsPerSample(bitsPerSample)
+                            
.alphaBand(alphaBand).isAlphaPremultiplied(isAlphaPremultiplied);
                     if (getSampleModel(null) instanceof 
SinglePixelPackedSampleModel) {
-                        colorModel = 
ColorModelFactory.createPackedRGB(bitsPerSample, alphaBand, 
isAlphaPremultiplied);
+                        colorModel = builder.createPackedRGB();
                     } else {
-                        colorModel = 
ColorModelFactory.createBandedRGB(bitsPerSample, alphaBand, 
isAlphaPremultiplied);
+                        colorModel = builder.createBandedRGB();
                     }
                     break;
                 }
diff --git 
a/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/WriterTest.java
 
b/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/WriterTest.java
index 5577acd807..16971a8f4e 100644
--- 
a/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/WriterTest.java
+++ 
b/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/WriterTest.java
@@ -41,7 +41,7 @@ import org.apache.sis.storage.geotiff.base.Tags;
 import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.coverage.grid.GridOrientation;
-import org.apache.sis.coverage.privy.ColorModelFactory;
+import org.apache.sis.coverage.privy.ColorModelBuilder;
 import org.apache.sis.geometry.Envelope2D;
 import org.apache.sis.image.DataType;
 
@@ -237,7 +237,7 @@ public final class WriterTest extends TestCase {
     @Test
     public void testUntiledRGB() throws IOException, DataStoreException {
         initialize(DataType.BYTE, ByteOrder.LITTLE_ENDIAN, false, 3, 1, 1);
-        
image.setColorModel(ColorModelFactory.createRGB(image.getSampleModel(), false));
+        image.setColorModel(new 
ColorModelBuilder().create(image.getSampleModel()));
         writeImage();
         verifyHeader(false, IOBase.LITTLE_ENDIAN);
         verifyImageFileDirectory(Writer.COMMON_NUMBER_OF_TAGS - 1,          // 
One less tag because stripped layout.
diff --git 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/postgis/RasterReader.java
 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/postgis/RasterReader.java
index 0827136e77..1d7a0a3ecf 100644
--- 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/postgis/RasterReader.java
+++ 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/postgis/RasterReader.java
@@ -44,6 +44,7 @@ import org.apache.sis.coverage.grid.GridCoverage;
 import org.apache.sis.coverage.grid.GridCoverage2D;
 import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.coverage.grid.GridGeometry;
+import org.apache.sis.coverage.privy.ColorModelBuilder;
 import org.apache.sis.coverage.privy.ColorModelFactory;
 import org.apache.sis.coverage.privy.ObservableImage;
 import org.apache.sis.referencing.CRS;
@@ -316,7 +317,7 @@ public final class RasterReader extends RasterFormat {
         final int dataType = sm.getDataType();
         final int numBands = sm.getNumBands();
         if ((numBands == 3) && (dataType == DataBuffer.TYPE_BYTE)) {
-            cm = ColorModelFactory.createBandedRGB(Byte.SIZE, -1, false);
+            cm = new ColorModelBuilder().createBandedRGB();
         } else {
             final int visibleBand = 0;              // Arbitrary value (could 
be configurable).
             final double minimum, maximum;
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
index 5fea017665..e222f4711c 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
@@ -43,6 +43,7 @@ import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.base.PRJDataStore;
 import org.apache.sis.storage.base.MetadataBuilder;
 import org.apache.sis.coverage.privy.ColorModelFactory;
+import org.apache.sis.coverage.privy.ColorModelBuilder;
 import org.apache.sis.coverage.privy.ImageUtilities;
 import org.apache.sis.coverage.privy.ObservableImage;
 import org.apache.sis.coverage.privy.RangeArgument;
@@ -395,14 +396,14 @@ abstract class RasterStore extends PRJDataStore 
implements GridCoverageResource
              * The color file is optional and will be used if present.
              */
             if (band == VISIBLE_BAND) {
-                if (isRGB) {
-                    colorModel = ColorModelFactory.createRGB(sm, false);    // 
Should never be null.
-                } else {
-                    try {
+                try {
+                    if (isRGB) {
+                        colorModel = new ColorModelBuilder().create(sm);
+                    } else {
                         colorModel = readColorMap(dataType, (int) (maximum + 
1), bands.length);
-                    } catch (URISyntaxException | IOException | 
NumberFormatException e) {
-                        cannotReadAuxiliaryFile(CLR, e);
                     }
+                } catch (URISyntaxException | IOException | 
IllegalArgumentException e) {
+                    cannotReadAuxiliaryFile(CLR, e);
                 }
                 if (colorModel == null) {
                     colorModel = ColorModelFactory.createGrayScale(dataType, 
bands.length, band, minimum, maximum);
diff --git 
a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java
 
b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java
index 7e72b37161..0bec8c97c9 100644
--- 
a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java
+++ 
b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java
@@ -43,6 +43,7 @@ import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.coverage.grid.GridCoverage;
 import org.apache.sis.coverage.grid.PixelInCell;
 import org.apache.sis.coverage.privy.ImageLayout;
+import org.apache.sis.coverage.privy.ColorModelBuilder;
 import org.apache.sis.coverage.privy.ColorModelFactory;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreReferencingException;
@@ -473,7 +474,7 @@ final class TiledResource extends TiledGridResource {
              */
         }
         if ((red | green | blue) >= 0) {
-            colorModel = ColorModelFactory.createBandedRGB(dataType.numBits, 
alpha, false);
+            colorModel = new 
ColorModelBuilder().bitsPerSample(dataType.numBits).alphaBand(alpha).createBandedRGB();
             // TODO: needs custom color model if too many bands, or if order 
is not (A)RGB.
         } else if (palette != null) {
             colorModel = 
ColorModelFactory.createIndexColorModel(selectedBands.length, paletteIndex, 
palette, true, -1);

Reply via email to