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 2a7346399cee74a04d065e8e750307d2a3b4965f Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Tue Dec 24 17:05:30 2024 +0100 Consolidation in the way that a sample model is created from an `ImageLayout` for an image operation. Some `int` arguments are replaced by more type-safe objects such as `DataType` or `Dimension`. --- .../sis/coverage/grid/GridCoverageBuilder.java | 3 +- .../apache/sis/coverage/grid/ImageRenderer.java | 3 +- .../sis/coverage/privy/ColorScaleBuilder.java | 35 +++++-- .../sis/coverage/privy/SampleModelFactory.java | 12 +-- .../org/apache/sis/image/BandAggregateLayout.java | 7 +- .../apache/sis/image/BandedSampleConverter.java | 6 +- .../main/org/apache/sis/image/Colorizer.java | 2 +- .../main/org/apache/sis/image/ImageLayout.java | 104 ++++++++++++++------- .../main/org/apache/sis/image/ImageProcessor.java | 3 +- .../main/org/apache/sis/image/Visualization.java | 16 ++-- .../sis/coverage/privy/ColorModelBuilderTest.java | 11 ++- .../sis/coverage/privy/SampleModelFactoryTest.java | 18 +++- .../sis/image/BandedSampleConverterTest.java | 16 ++-- .../sis/storage/geotiff/ImageFileDirectory.java | 4 +- 14 files changed, 154 insertions(+), 86 deletions(-) diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverageBuilder.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverageBuilder.java index 37e9c3e3f7..042ac90136 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverageBuilder.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverageBuilder.java @@ -37,7 +37,6 @@ import org.opengis.referencing.operation.TransformException; import org.apache.sis.image.PlanarImage; import org.apache.sis.coverage.SampleDimension; import org.apache.sis.coverage.privy.ColorScaleBuilder; -import org.apache.sis.coverage.privy.ImageUtilities; import org.apache.sis.coverage.privy.ObservableImage; import org.apache.sis.coverage.privy.TiledImage; import org.apache.sis.coverage.privy.WritableTiledImage; @@ -476,7 +475,7 @@ public class GridCoverageBuilder { final var colorizer = new ColorScaleBuilder(ColorScaleBuilder.GRAYSCALE, null, false); final ColorModel colors; if (colorizer.initialize(sm, bands.get(visibleBand)) || colorizer.initialize(sm, visibleBand)) { - colors = colorizer.createColorModel(ImageUtilities.getBandType(sm), bands.size(), visibleBand); + colors = colorizer.createColorModel(sm, bands.size(), visibleBand); } else { colors = ColorScaleBuilder.NULL_COLOR_MODEL; } diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/ImageRenderer.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/ImageRenderer.java index 8867349e4f..5483da9234 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/ImageRenderer.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/ImageRenderer.java @@ -754,7 +754,8 @@ public class ImageRenderer { final ColorModel cm; final SampleModel sm = raster.getSampleModel(); if (colorizer.initialize(sm, bands[visibleBand]) || colorizer.initialize(sm, visibleBand)) { - cm = colorizer.createColorModel(buffer.getDataType(), bands.length, visibleBand); + DataType type = DataType.forDataBufferType(buffer.getDataType()); + cm = colorizer.createColorModel(type, bands.length, visibleBand); } else { cm = ColorScaleBuilder.NULL_COLOR_MODEL; } diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorScaleBuilder.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorScaleBuilder.java index d36c7adad2..54905cfc09 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorScaleBuilder.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorScaleBuilder.java @@ -35,10 +35,11 @@ import org.apache.sis.referencing.operation.transform.MathTransforms; import org.apache.sis.coverage.Category; import org.apache.sis.coverage.SampleDimension; import org.apache.sis.feature.internal.Resources; +import org.apache.sis.image.DataType; +import org.apache.sis.measure.NumberRange; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.ArraysExt; import org.apache.sis.util.privy.Numerics; -import org.apache.sis.measure.NumberRange; import org.apache.sis.util.resources.Errors; import org.apache.sis.util.resources.Vocabulary; @@ -666,24 +667,40 @@ reuse: if (source != null) { * given by {@link #getSampleToIndexValues()}. Images using this color model shall * use a {@link DataBuffer} of type {@link #TYPE_COMPACT}. * - * @param dataType the color model type. One of {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT}, - * {@link DataBuffer#TYPE_SHORT}, {@link DataBuffer#TYPE_INT}, {@link DataBuffer#TYPE_FLOAT} - * or {@link DataBuffer#TYPE_DOUBLE}. + * @param dataType the type of data elements used for storing sample values. * @param numBands the number of bands for the color model (usually 1). The returned color model will render only * 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 visibleBand the band to be made visible (usually 0). All other bands, if any, will be ignored. * @return a color model suitable for {@link java.awt.image.RenderedImage} objects with values in the given ranges. */ - public ColorModel createColorModel(int dataType, final int numBands, final int visibleBand) { + public ColorModel createColorModel(final DataType dataType, final int numBands, final int visibleBand) { checkInitializationStatus(true); + int typeCode = dataType.toDataBufferType(); + ArgumentChecks.ensureStrictlyPositive("numBands", numBands); + ArgumentChecks.ensureBetween("visibleBand", 0, numBands - 1, visibleBand); if (compact) { compact(); - dataType = TYPE_COMPACT; + typeCode = TYPE_COMPACT; } - ArgumentChecks.ensureStrictlyPositive("numBands", numBands); - ArgumentChecks.ensureBetween("visibleBand", 0, numBands - 1, visibleBand); - return ColorModelFactory.createPiecewise(dataType, numBands, visibleBand, entries); + return ColorModelFactory.createPiecewise(typeCode, numBands, visibleBand, entries); + } + + /** + * Returns a color model to use in a rendered image together with the given sample model. + * This method delegates to {@link #createColorModel(DataType, int, int)} after having + * inferred the data type from the given sample model. + * + * @todo Current implementation does not verify that the color model is compatible + * with the sample model. We should add that verification. + * + * @param target the sample model for which to create a color model. + * @param numBands the number of bands for the color model (usually 1). + * @param visibleBand the band to be made visible (usually 0). All other bands, if any, will be ignored. + * @return a color model using a data type inferred from the given sample model. + */ + public ColorModel createColorModel(final SampleModel target, final int numBands, final int visibleBand) { + return createColorModel(DataType.forDataBufferType(ImageUtilities.getBandType(target)), numBands, visibleBand); } /** diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/SampleModelFactory.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/SampleModelFactory.java index b842cc5e11..ce47dee9e2 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/SampleModelFactory.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/SampleModelFactory.java @@ -17,6 +17,7 @@ package org.apache.sis.coverage.privy; import java.util.Arrays; +import java.awt.Dimension; import java.awt.image.DataBuffer; import java.awt.image.SampleModel; import java.awt.image.BandedSampleModel; @@ -103,22 +104,21 @@ public final class SampleModelFactory { private int scanlineStride; /** - * Creates a factory initialized to the given values. + * Creates a builder for a sample model of a type inferred from the given properties. * * @param type type of sample values. - * @param width tile width in pixels. - * @param height tile height in pixels. + * @param size tile width and height in pixels. * @param numBands number of bands. * @param bitsPerSample number of bits per sample values. * @param isBanded {@code true} if each band is stored in a separated bank. * @throws RasterFormatException if the arguments imply a sample model of unsupported type. */ - public SampleModelFactory(final DataType type, final int width, final int height, + public SampleModelFactory(final DataType type, final Dimension size, final int numBands, final int bitsPerSample, final boolean isBanded) { this.dataType = type.toDataBufferType(); - this.width = width; - this.height = height; + this.width = size.width; + this.height = size.height; this.numBands = numBands; scanlineStride = width; pixelStride = 1; diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateLayout.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateLayout.java index 7b5ae49354..a52a519d45 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateLayout.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandAggregateLayout.java @@ -204,7 +204,8 @@ final class BandAggregateLayout extends ImageLayout { chooseMinTile(tileGridYOffset, domain.y, preferredTileSize.height)); return new BandAggregateLayout(sources, bandsPerSource, bandSelect, domain, preferredTileSize, exactTileSize, - minTile, commonDataType, aggregate.numBands(), allowSharing ? scanlineStride : 0); + minTile, DataType.forDataBufferType(commonDataType), aggregate.numBands(), + allowSharing ? scanlineStride : 0); } /** @@ -227,14 +228,14 @@ final class BandAggregateLayout extends ImageLayout { */ private BandAggregateLayout(final RenderedImage[] sources, final int[][] bandsPerSource, final int[] bandSelect, final Rectangle domain, final Dimension preferredTileSize, final boolean exactTileSize, - final Point minTile, final int commonDataType, final int numBands, final int scanlineStride) + final Point minTile, final DataType commonDataType, final int numBands, final int scanlineStride) { super(null, preferredTileSize, !exactTileSize, false, false, minTile); this.bandsPerSource = bandsPerSource; this.bandSelect = bandSelect; this.sources = sources; this.domain = domain; - this.sampleModel = createBandedSampleModel(commonDataType, numBands, null, domain, scanlineStride); + this.sampleModel = createBandedSampleModel(null, domain, commonDataType, numBands, scanlineStride); /* * Note: above call to `createBandedSampleModel(…)` must be last, * except for `filteredSources` which is not needed by that method. diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandedSampleConverter.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandedSampleConverter.java index 99aed560f5..9d18e48b88 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandedSampleConverter.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandedSampleConverter.java @@ -25,7 +25,6 @@ import java.awt.image.RenderedImage; import java.awt.image.WritableRenderedImage; import java.awt.image.BandedSampleModel; import java.awt.image.ColorModel; -import java.awt.image.DataBuffer; import java.awt.image.SampleModel; import java.lang.reflect.Array; import org.opengis.referencing.operation.MathTransform1D; @@ -196,7 +195,6 @@ class BandedSampleConverter extends WritableComputedImage { * @param sourceRanges the expected range of values for each band in source image, or {@code null} if unknown. * @param converters the transfer functions to apply on each band of the source image. * @param targetType the type of this image resulting from conversion of given image. - * Shall be one of {@link DataBuffer} constants. * @param colorizer provider of color model for the expected range of values, or {@code null}. * @return the image which compute converted values from the given source. * @@ -204,7 +202,7 @@ class BandedSampleConverter extends WritableComputedImage { */ static BandedSampleConverter create(RenderedImage source, final ImageLayout layout, final NumberRange<?>[] sourceRanges, final MathTransform1D[] converters, - final int targetType, final Colorizer colorizer) + final DataType targetType, final Colorizer colorizer) { /* * Since this operation applies its own ColorModel anyway, skip operation that was doing nothing else @@ -215,7 +213,7 @@ class BandedSampleConverter extends WritableComputedImage { source = ((RecoloredImage) source).source; } final int numBands = converters.length; - final BandedSampleModel sampleModel = layout.createBandedSampleModel(targetType, numBands, source, null, 0); + final BandedSampleModel sampleModel = layout.createBandedSampleModel(source, null, targetType, numBands, 0); final SampleDimension[] sampleDimensions = SampleDimensions.IMAGE_PROCESSOR_ARGUMENT.get(); final int visibleBand = ImageUtilities.getVisibleBand(source); ColorModel colorModel = ColorScaleBuilder.NULL_COLOR_MODEL; 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 be69136e2f..2c6c9e363a 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 @@ -321,7 +321,7 @@ public interface Colorizer extends Function<Colorizer.Target, Optional<ColorMode final SampleModel model = target.getSampleModel(); final var c = new ColorScaleBuilder(colors, null, false); if (c.initialize(model, ranges.get(visibleBand))) { - return Optional.ofNullable(c.createColorModel(model.getDataType(), model.getNumBands(), visibleBand)); + return Optional.ofNullable(c.createColorModel(model, model.getNumBands(), visibleBand)); } } } diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageLayout.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageLayout.java index 2aa8e81412..469b5bb49e 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageLayout.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageLayout.java @@ -28,6 +28,7 @@ import java.awt.image.SampleModel; import java.awt.image.BandedSampleModel; import java.awt.image.WritableRenderedImage; import org.apache.sis.math.MathFunctions; +import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.ArraysExt; import org.apache.sis.util.resources.Errors; import org.apache.sis.util.privy.Strings; @@ -526,39 +527,22 @@ public class ImageLayout { } /** - * Creates a banded sample model of the given type with an automatic tile size. - * At least one of {@code image} and {@code bounds} arguments must be non null. - * This method uses the {@linkplain #suggestTileSize(RenderedImage, Rectangle) - * suggested tile size} for the given image and bounds. - * - * <p>This method constructs the simplest possible banded sample model: - * All {@linkplain BandedSampleModel#getBandOffsets() band offsets} are zero and - * all {@linkplain BandedSampleModel#getBankIndices() bank indices} are identity mapping. - * This simplicity is needed by current implementation of {@link BandAggregateImage}.</p> + * Ensures that the number of bands specified (directly or indirectly) in a method call + * is compatible with the sample model. * - * @param dataType desired data type as a {@link java.awt.image.DataBuffer} constant. - * @param numBands desired number of bands. - * @param image the image which will be the source of the image for which a sample model is created. - * @param bounds the bounds of the image to create, or {@code null} if same as {@code image}. - * @param scanlineStride the line stride of the of the image data, or ≤ 0 for automatic. - * @return a banded sample model of the given type with the given number of bands. + * @param actual the number of bands inferred from the argument in a method call. */ - final BandedSampleModel createBandedSampleModel(final int dataType, final int numBands, - final RenderedImage image, final Rectangle bounds, int scanlineStride) - { - final Dimension tileSize = suggestTileSize(image, bounds); - if (scanlineStride <= 0) { - scanlineStride = tileSize.width; + private void checkBandCount(final int actual) { + int expected = sampleModel.getNumBands(); + if (expected != actual) { + throw new IllegalStateException(Resources.format(Resources.Keys.UnexpectedNumberOfBands_2, expected, actual)); } - // Pixel stride, bank indices and band offsets intentionally non-configurable. See Javadoc. - return RasterFactory.unique(new BandedSampleModel(dataType, tileSize.width, tileSize.height, - scanlineStride, ArraysExt.range(0, numBands), new int[numBands])); } /** - * Creates a sample model with a size computed from the given image size. - * If a {@link #sampleModel} has been specified, the new sample model is derived from that field value. - * Otherwise, the new sample model is derived from the image sample model. + * Returns a sample model with a size computed from the given image size. + * If this {@code ImageLayout} contains a {@link #sampleModel}, then the latter is used as a template. + * Otherwise, the new sample model is {@linkplain RenderedImage#getSampleModel() derived from the image}. * * @param image the image from which to derive a sample model. * @param bounds the bounds of the image to create, or {@code null} if same as {@code image}. @@ -571,14 +555,17 @@ public class ImageLayout { public SampleModel createCompatibleSampleModel(final RenderedImage image, final Rectangle bounds) { SampleModel sm = image.getSampleModel(); if (sampleModel != null) { - int expected = sampleModel.getNumBands(); - int actual = sm.getNumBands(); - if (expected != actual) { - throw new IllegalStateException(Resources.format(Resources.Keys.UnexpectedNumberOfBands_2, expected, actual)); - } + checkBandCount(sm.getNumBands()); sm = sampleModel; } - final Dimension tile = suggestTileSize(image, bounds); + return createCompatibleSampleModel(sm, suggestTileSize(image, bounds)); + } + + /** + * Returns a sample model equivalent to the given one, but using a different width and height. + * If the given sample model already has the desired size, then it is returned unchanged. + */ + private static SampleModel createCompatibleSampleModel(SampleModel sm, final Dimension tile) { if (sm.getWidth() != tile.width || sm.getHeight() != tile.height) { sm = sm.createCompatibleSampleModel(tile.width, tile.height); sm = RasterFactory.unique(sm); @@ -586,6 +573,57 @@ public class ImageLayout { return sm; } + /** + * Returns a sample model for the given data type with a size computed from the given image bounds. + * If this {@code ImageLayout} contains a {@link #sampleModel}, then the latter is used as a template. + * + * @param dataType the default data type for the sample model to create. + * @param bounds the bounds of the image to create. + * @param numBands the number of bands in the sample model to create. + * @return image sample model with a tile size derived from the given image bounds. + * @throws IllegalStateException if {@link #sampleModel} is non-null but does not + * have the same number of bands as the given {@code numBands} argument. + */ + public SampleModel createSampleModel(final DataType dataType, final Rectangle bounds, final int numBands) { + ArgumentChecks.ensureNonNull("bounds", bounds); + if (sampleModel != null) { + checkBandCount(numBands); + return createCompatibleSampleModel(sampleModel, suggestTileSize(null, bounds)); + } + return createBandedSampleModel(null, bounds, dataType, numBands, 0); + } + + /** + * Creates a banded sample model for the given data type. + * At least one of {@code image} and {@code bounds} arguments must be non null. + * This method uses the {@linkplain #suggestTileSize(RenderedImage, Rectangle) + * suggested tile size} for the given image and bounds. + * + * <p>This method constructs the simplest possible banded sample model: + * All {@linkplain BandedSampleModel#getBandOffsets() band offsets} are zero and + * all {@linkplain BandedSampleModel#getBankIndices() bank indices} are identity mapping. + * This simplicity is needed by current implementation of {@link BandAggregateImage}. + * User-specified {@link #sampleModel} is ignored.</p> + * + * @param image the image which will be the source of the image for which a sample model is created. + * @param bounds the bounds of the image to create, or {@code null} if same as {@code image}. + * @param dataType desired data type. + * @param numBands desired number of bands. + * @param scanlineStride the line stride of the image data, or ≤ 0 for automatic. + * @return a banded sample model of the given type with the given number of bands. + */ + final BandedSampleModel createBandedSampleModel(final RenderedImage image, final Rectangle bounds, + final DataType dataType, final int numBands, int scanlineStride) + { + final Dimension tileSize = suggestTileSize(image, bounds); + if (scanlineStride <= 0) { + scanlineStride = tileSize.width; + } + // Pixel stride, bank indices and band offsets intentionally non-configurable. See Javadoc. + return RasterFactory.unique(new BandedSampleModel(dataType.toDataBufferType(), + tileSize.width, tileSize.height, scanlineStride, ArraysExt.range(0, numBands), new int[numBands])); + } + /** * Returns the preferred indices of the upper-left tile in an image tile matrix. * This property usually has no incidence on the appearance or performance of an image. diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageProcessor.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageProcessor.java index 3ea729e744..a79c0c775a 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageProcessor.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageProcessor.java @@ -1155,8 +1155,7 @@ public class ImageProcessor implements Cloneable { colorizer = this.colorizer; } // No need to clone `sourceRanges` because it is not stored by `BandedSampleConverter`. - return unique(BandedSampleConverter.create(source, layout, sourceRanges, converters, - targetType.toDataBufferType(), colorizer)); + return unique(BandedSampleConverter.create(source, layout, sourceRanges, converters, targetType, colorizer)); } /** diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Visualization.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Visualization.java index 260c5edf15..a712ae34d9 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Visualization.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/Visualization.java @@ -258,7 +258,13 @@ final class Visualization extends ResampledImage { * requires the tile layout of destination image to be the same as source image. * Otherwise combine interpolation and value conversions in a single operation. */ - final boolean shortcut = toSource.isIdentity() && (bounds == null || ImageUtilities.getBounds(source).contains(bounds)); + final boolean shortcut; + if (bounds == null) { + bounds = ImageUtilities.getBounds(source); + shortcut = toSource.isIdentity(); + } else { + shortcut = toSource.isIdentity() && ImageUtilities.getBounds(source).contains(bounds); + } if (shortcut) { layout = ImageLayout.DEFAULT.withTileMatrix(source).allowTileSizeAdjustments(false); } @@ -267,7 +273,8 @@ final class Visualization extends ResampledImage { * The sample model is a mandatory argument before we invoke user supplied colorizer, * which must be done before to build the color model. */ - sampleModel = layout.createBandedSampleModel(ColorScaleBuilder.TYPE_COMPACT, NUM_BANDS, source, bounds, 0); + final DataType dataType = DataType.forDataBufferType(ColorScaleBuilder.TYPE_COMPACT); + sampleModel = layout.createSampleModel(dataType, bounds, NUM_BANDS); final Target target = new Target(sampleModel, VISIBLE_BAND, visibleSD != null); if (colorizer != null) { colorModel = colorizer.apply(target).orElse(null); @@ -335,7 +342,7 @@ final class Visualization extends ResampledImage { builder.initialize(statistics.minimum(), statistics.maximum(), sourceSM.getDataType()); } if (colorModel == null) { - colorModel = builder.createColorModel(ColorScaleBuilder.TYPE_COMPACT, NUM_BANDS, VISIBLE_BAND); + colorModel = builder.createColorModel(dataType, NUM_BANDS, VISIBLE_BAND); } converters = new MathTransform1D[] { builder.getSampleToIndexValues() // Must be after `createColorModel(…)`. @@ -349,9 +356,6 @@ final class Visualization extends ResampledImage { interpolation = combine(interpolation.toCompatible(source), converters); converters = null; } - if (bounds == null) { - bounds = ImageUtilities.getBounds(source); - } return ImageProcessor.unique(new Visualization(this)); } } diff --git a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/privy/ColorModelBuilderTest.java b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/privy/ColorModelBuilderTest.java index f14aac7103..c031e3c3d6 100644 --- a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/privy/ColorModelBuilderTest.java +++ b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/privy/ColorModelBuilderTest.java @@ -19,11 +19,11 @@ package org.apache.sis.coverage.privy; import java.util.List; import java.util.AbstractMap.SimpleEntry; import java.awt.Color; -import java.awt.image.DataBuffer; import java.awt.image.IndexColorModel; import org.opengis.referencing.operation.MathTransform1D; import org.opengis.referencing.operation.TransformException; import org.apache.sis.coverage.SampleDimension; +import org.apache.sis.image.DataType; import org.apache.sis.math.MathFunctions; import org.apache.sis.measure.NumberRange; import org.apache.sis.measure.Units; @@ -53,7 +53,7 @@ public final class ColorModelBuilderTest extends TestCase { */ @Test public void testRangeAndColors() throws TransformException { - final ColorScaleBuilder colorizer = new ColorScaleBuilder(List.of( + final var colorizer = new ColorScaleBuilder(List.of( new SimpleEntry<>(NumberRange.create(0, true, 0, true), new Color[] {Color.GRAY}), new SimpleEntry<>(NumberRange.create(1, true, 1, true), new Color[] {ColorModelFactory.TRANSPARENT}), new SimpleEntry<>(NumberRange.create(2, true, 15, true), new Color[] {Color.BLUE, Color.WHITE, Color.RED})), null); @@ -62,7 +62,7 @@ public final class ColorModelBuilderTest extends TestCase { * above-given ranges already fit in a 4-bits IndexColormodel. */ assertTrue(colorizer.getSampleToIndexValues().isIdentity()); - final IndexColorModel cm = (IndexColorModel) colorizer.createColorModel(DataBuffer.TYPE_BYTE, 1, 0); + final var cm = (IndexColorModel) colorizer.createColorModel(DataType.BYTE, 1, 0); final int[] expected = { 0xFF808080, // Color.GRAY 0x00000000, // ColorModelFactory.TRANSPARENT @@ -102,9 +102,10 @@ public final class ColorModelBuilderTest extends TestCase { .addQualitative ("Error", MathFunctions.toNanFloat(3)) .setName("Temperature").build(); - final ColorScaleBuilder colorizer = new ColorScaleBuilder(ColorScaleBuilder.GRAYSCALE, null, true); + final var colorizer = new ColorScaleBuilder(ColorScaleBuilder.GRAYSCALE, null, true); assertTrue(colorizer.initialize(null, sd)); - final var cm = (IndexColorModel) colorizer.createColorModel(ColorScaleBuilder.TYPE_COMPACT, 1, 0); // Must be first. + final var dt = DataType.forDataBufferType(ColorScaleBuilder.TYPE_COMPACT); + final var cm = (IndexColorModel) colorizer.createColorModel(dt, 1, 0); // Must be first. /* * Test conversion of a few sample values to packed values. */ diff --git a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/privy/SampleModelFactoryTest.java b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/privy/SampleModelFactoryTest.java index 2507bdb347..421485a15b 100644 --- a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/privy/SampleModelFactoryTest.java +++ b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/privy/SampleModelFactoryTest.java @@ -16,6 +16,7 @@ */ package org.apache.sis.coverage.privy; +import java.awt.Dimension; import java.awt.image.DataBuffer; import java.awt.image.SampleModel; import java.awt.image.BandedSampleModel; @@ -48,13 +49,20 @@ public final class SampleModelFactoryTest extends TestCase { public SampleModelFactoryTest() { } + /** + * Returns the width and height of the sample models to create. + */ + private static Dimension size() { + return new Dimension(WIDTH, HEIGHT); + } + /** * Tests the creation and modification of a {@link BandedSampleModel}. */ @Test public void testBanded() { final BandedSampleModel model = test(BandedSampleModel.class, - new SampleModelFactory(DataType.FLOAT, WIDTH, HEIGHT, NUM_BANDS, Float.SIZE, true)); + new SampleModelFactory(DataType.FLOAT, size(), NUM_BANDS, Float.SIZE, true)); assertArrayEquals(new int[] {1, 0, 2}, model.getBankIndices()); assertArrayEquals(new int[] {0, 0, 0}, model.getBandOffsets()); @@ -69,7 +77,7 @@ public final class SampleModelFactoryTest extends TestCase { @Test public void testPixelInterleaved() { final PixelInterleavedSampleModel model = test(PixelInterleavedSampleModel.class, - new SampleModelFactory(DataType.BYTE, WIDTH, HEIGHT, NUM_BANDS, Byte.SIZE, false)); + new SampleModelFactory(DataType.BYTE, size(), NUM_BANDS, Byte.SIZE, false)); assertArrayEquals(new int[] {0, 0, 0}, model.getBankIndices()); assertArrayEquals(new int[] {1, 0, 2}, model.getBandOffsets()); @@ -86,7 +94,7 @@ public final class SampleModelFactoryTest extends TestCase { @Test public void testSinglePixelPacked() { final SinglePixelPackedSampleModel model = test(SinglePixelPackedSampleModel.class, - new SampleModelFactory(DataType.INT, WIDTH, HEIGHT, NUM_BANDS, 5, false)); + new SampleModelFactory(DataType.INT, size(), NUM_BANDS, 5, false)); final int[] expected = { 0b1111100000, // Band 2 specified, 1 after compression. @@ -106,8 +114,8 @@ public final class SampleModelFactoryTest extends TestCase { @Test public void testPixelMultiPixelPacked() { final int bitsPerSample = 4; - SampleModelFactory factory = new SampleModelFactory(DataType.INT, WIDTH, HEIGHT, 1, bitsPerSample, false); - final MultiPixelPackedSampleModel model = (MultiPixelPackedSampleModel) factory.build(); + var factory = new SampleModelFactory(DataType.INT, size(), 1, bitsPerSample, false); + final var model = (MultiPixelPackedSampleModel) factory.build(); assertEquals(bitsPerSample, model.getPixelBitStride()); assertEquals(WIDTH / (Integer.SIZE / bitsPerSample), model.getScanlineStride()); diff --git a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/BandedSampleConverterTest.java b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/BandedSampleConverterTest.java index 07d1957a2f..42ffbd71c8 100644 --- a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/BandedSampleConverterTest.java +++ b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/BandedSampleConverterTest.java @@ -50,10 +50,10 @@ public final class BandedSampleConverterTest extends ImageTestCase { * The created image is assigned to the {@link #image} field. * * @param sourceType source data type as one of the {@link DataBuffer} constants. - * @param targetType target data type as one of the {@link DataBuffer} constants. + * @param targetType target data type. * @param scale the scale factor of the conversion to apply. */ - private void createImage(final int sourceType, final int targetType, final double scale) { + private void createImage(final int sourceType, final DataType targetType, final double scale) { final Random random = TestUtilities.createRandomNumberGenerator(); final TiledImageMock source = new TiledImageMock( sourceType, 1, @@ -106,7 +106,7 @@ public final class BandedSampleConverterTest extends ImageTestCase { */ @Test public void testUShortToFloat() { - createImage(DataBuffer.TYPE_USHORT, DataBuffer.TYPE_FLOAT, 0.1); + createImage(DataBuffer.TYPE_USHORT, DataType.FLOAT, 0.1); assertValuesDivided(); } @@ -115,7 +115,7 @@ public final class BandedSampleConverterTest extends ImageTestCase { */ @Test public void testFloatToUShort() { - createImage(DataBuffer.TYPE_FLOAT, DataBuffer.TYPE_USHORT, 10); + createImage(DataBuffer.TYPE_FLOAT, DataType.USHORT, 10); assertValuesMultiplied(); } @@ -124,7 +124,7 @@ public final class BandedSampleConverterTest extends ImageTestCase { */ @Test public void testFloatToFloat() { - createImage(DataBuffer.TYPE_FLOAT, DataBuffer.TYPE_FLOAT, 0.1); + createImage(DataBuffer.TYPE_FLOAT, DataType.FLOAT, 0.1); assertValuesDivided(); } @@ -133,7 +133,7 @@ public final class BandedSampleConverterTest extends ImageTestCase { */ @Test public void testUShortToUShort() { - createImage(DataBuffer.TYPE_USHORT, DataBuffer.TYPE_USHORT, 10); + createImage(DataBuffer.TYPE_USHORT, DataType.USHORT, 10); assertValuesMultiplied(); } @@ -142,7 +142,7 @@ public final class BandedSampleConverterTest extends ImageTestCase { */ @Test public void testShortToInteger() { - createImage(DataBuffer.TYPE_SHORT, DataBuffer.TYPE_INT, 10); + createImage(DataBuffer.TYPE_SHORT, DataType.INT, 10); assertValuesMultiplied(); } @@ -151,7 +151,7 @@ public final class BandedSampleConverterTest extends ImageTestCase { */ @Test public void testDoubleToInteger() { - createImage(DataBuffer.TYPE_DOUBLE, DataBuffer.TYPE_INT, 10); + createImage(DataBuffer.TYPE_DOUBLE, DataType.INT, 10); assertValuesMultiplied(); } } 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 a5abf73b0d..23c8926929 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 @@ -25,6 +25,7 @@ import java.util.logging.Level; import java.util.logging.LogRecord; import java.nio.charset.Charset; import java.awt.Color; +import java.awt.Dimension; import java.awt.image.ColorModel; import java.awt.image.SampleModel; import java.awt.image.SinglePixelPackedSampleModel; @@ -1622,7 +1623,8 @@ final class ImageFileDirectory extends DataCube { RuntimeException error = null; final DataType type = getDataType(); if (type != null) try { - sampleModel = new SampleModelFactory(type, tileWidth, tileHeight, samplesPerPixel, bitsPerSample, isPlanar).build(); + var size = new Dimension(tileWidth, tileHeight); + sampleModel = new SampleModelFactory(type, size, samplesPerPixel, bitsPerSample, isPlanar).build(); } catch (IllegalArgumentException | RasterFormatException e) { error = e; }