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 8ddfe3bb09e1d66158b18af731ea0d857300fd83 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Sat Dec 28 11:19:05 2024 +0100 Slight simplification of `DataType` usage when mapping to Java primitive types. --- .../main/org/apache/sis/image/DataType.java | 81 +++++++++++++++------- .../org/apache/sis/image/privy/RasterFactory.java | 4 +- .../test/org/apache/sis/image/DataTypeTest.java | 14 ++++ .../storage/geotiff/inflater/CopyFromBytes.java | 4 +- .../geotiff/inflater/HorizontalPredictor.java | 4 +- .../geotiff/writer/HorizontalPredictor.java | 4 +- .../sis/storage/geotiff/writer/TileMatrix.java | 15 ++-- 7 files changed, 80 insertions(+), 46 deletions(-) diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/DataType.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/DataType.java index caea60edb2..9b4fa8d71a 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/DataType.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/DataType.java @@ -65,6 +65,9 @@ public enum DataType { * Mapped to {@link DataBuffer#TYPE_INT} in Java2D <abbr>API</abbr>. * Note that the sign of the latter Java2D type is ambiguous. * See {@link #forDataBufferType(int)} for more information. + * + * <p>This type is selected by default for all {@link DataBuffer#TYPE_INT} + * cases that cannot be resolved as an {@link #UINT} case.</p> */ INT(DataBuffer.TYPE_INT, 0), @@ -74,6 +77,9 @@ public enum DataType { * Note that the sign of the latter Java2D type is ambiguous. * See {@link #forDataBufferType(int)} for more information. * + * <p>This case is selected when the data are used with any packed sample model: + * {@link SinglePixelPackedSampleModel} or {@link MultiPixelPackedSampleModel}.</p> + * * @since 1.5 */ UINT(DataBuffer.TYPE_INT, 0), @@ -110,6 +116,7 @@ public enum DataType { * @see #forDataBufferType(int) */ private static final DataType[] VALUES = ArraysExt.remove(values(), DataBuffer.TYPE_INT + 1, 1); + // Initialization trick: ordinal values would be DataBuffer.TYPE_* values is UINT wasn't present. /** * Creates a new enumeration value. @@ -175,13 +182,13 @@ public enum DataType { * and maximum value rounded toward positive infinity.</li> * </ul> * - * @param range the range of values. - * @param asInteger whether to handle floating point values as integers. + * @param range the range of values. + * @param forceInteger whether to handle floating point values as integers. * @return smallest data type for the given range of values. */ - public static DataType forRange(final NumberRange<?> range, final boolean asInteger) { + public static DataType forRange(final NumberRange<?> range, final boolean forceInteger) { final byte nt = Numbers.getEnumConstant(range.getElementType()); - if (!asInteger) { + if (!forceInteger) { if (nt >= Numbers.DOUBLE) return DOUBLE; if (nt >= Numbers.FRACTION) return FLOAT; } @@ -308,16 +315,14 @@ public enum DataType { case Float.SIZE: return FLOAT; case Double.SIZE: return DOUBLE; } - } else { + } else if (size <= Integer.SIZE) { switch (size) { case Short.SIZE: return signed ? SHORT : USHORT; case Integer.SIZE: return signed ? INT : UINT; + default: if (!signed) return BYTE; else break; } - if (size <= Byte.SIZE) { - if (!signed) return BYTE; - argument = "signed"; - value = signed; - } + argument = "signed"; + value = signed; } throw new RasterFormatException(Resources.format(Resources.Keys.UnsupportedSampleType_3, size, argument, value)); } @@ -343,6 +348,30 @@ public enum DataType { return Math.max(size() >>> 3, 1); } + /** + * Returns whether this type is an integer type, signed or not. + * Integer types are {@link #BYTE}, {@link #USHORT}, {@link #SHORT}, {@link #INT} and {@link #UINT}. + * + * @return {@code true} if this type is an integer type. + */ + public final boolean isInteger() { + return dataType <= DataBuffer.TYPE_INT; + } + + /** + * Returns {@code true} if the given sample model uses an integer type. + * Returns {@code false} if the type is a floating point type or in case + * of doubt (e.g. for {@link DataBuffer#TYPE_UNDEFINED}). + * + * @param sm the sample model, or {@code null}. + * @return whether the given sample model uses an integer type. + * + * @since 1.5 + */ + public static boolean isInteger(final SampleModel sm) { + return (sm != null) && ImageUtilities.isIntegerType(sm.getDataType()); + } + /** * Returns whether this type is an unsigned integer type. * Unsigned types are {@link #BYTE}, {@link #USHORT} and {@link #UINT}. @@ -383,27 +412,27 @@ public enum DataType { } /** - * Returns whether this type is an integer type, signed or not. - * Integer types are {@link #BYTE}, {@link #USHORT}, {@link #SHORT}, {@link #INT} and {@link #UINT}. + * Returns the primitive (signed) variant of this data type. + * This method returns the value that most closely maps to a Java primitive type of the same number of bits. + * Since all Java primitive types are signed, this method returns the signed variant of this type except for + * the special case of {@link #BYTE} (because {@code DataType} does not define signed variant of that type). * - * @return {@code true} if this type is an integer type. - */ - public final boolean isInteger() { - return dataType <= DataBuffer.TYPE_INT; - } - - /** - * Returns {@code true} if the given sample model uses an integer type. - * Returns {@code false} if the type is a floating point type or in case - * of doubt (e.g. for {@link DataBuffer#TYPE_UNDEFINED}). + * <p>More specifically, this methods replaces {@link #UINT} by {@link #INT}, + * replaces {@link #USHORT} by {@link #SHORT}, and returns all other types unchanged. + * The purpose of this method is to simplify the {@code switch} statements with cases + * restricted to Java primitive types, such as mapping to specific <abbr>NIO</abbr> + * {@link java.nio.Buffer} subclasses.</p> * - * @param sm the sample model, or {@code null}. - * @return whether the given sample model works on integer values. + * @return the data type that most closely corresponds to a Java primitive type. * * @since 1.5 */ - public static boolean isInteger(final SampleModel sm) { - return (sm != null) && ImageUtilities.isIntegerType(sm.getDataType()); + public final DataType toPrimitive() { + switch (dataType) { + default: return this; + case DataBuffer.TYPE_INT: return INT; + case DataBuffer.TYPE_USHORT: return SHORT; + } } /** diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/privy/RasterFactory.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/privy/RasterFactory.java index 1fb7e06a37..bff3284753 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/privy/RasterFactory.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/privy/RasterFactory.java @@ -210,11 +210,9 @@ public final class RasterFactory extends Static { * @return buffer of the specified type and size. */ public static Buffer createBuffer(final DataType dataType, final int capacity) { - switch (dataType) { + switch (dataType.toPrimitive()) { case BYTE: return ByteBuffer .allocate(capacity); - case USHORT: // Fallthrough case SHORT: return ShortBuffer .allocate(capacity); - case UINT: // Fallthrough case INT: return IntBuffer .allocate(capacity); case FLOAT: return FloatBuffer .allocate(capacity); case DOUBLE: return DoubleBuffer.allocate(capacity); diff --git a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/DataTypeTest.java b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/DataTypeTest.java index ae0728b148..f8360b8339 100644 --- a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/DataTypeTest.java +++ b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/DataTypeTest.java @@ -97,6 +97,20 @@ public final class DataTypeTest extends TestCase { assertFalse(DataType.DOUBLE.isInteger()); } + /** + * Tests {@link DataType#toPrimitive()}. + */ + @Test + public void testToPrimitive() { + assertEquals(DataType.BYTE, DataType.BYTE .toPrimitive()); + assertEquals(DataType.SHORT, DataType.USHORT.toPrimitive()); + assertEquals(DataType.SHORT, DataType.SHORT .toPrimitive()); + assertEquals(DataType.INT, DataType.INT .toPrimitive()); + assertEquals(DataType.INT, DataType.UINT .toPrimitive()); + assertEquals(DataType.FLOAT, DataType.FLOAT .toPrimitive()); + assertEquals(DataType.DOUBLE, DataType.DOUBLE.toPrimitive()); + } + /** * Tests {@link DataType#toFloat()}. */ diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CopyFromBytes.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CopyFromBytes.java index 2d47dc5615..1ff90bde51 100644 --- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CopyFromBytes.java +++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CopyFromBytes.java @@ -109,11 +109,9 @@ abstract class CopyFromBytes extends Inflater { final int pixelsPerElement) throws UnsupportedEncodingException { - switch (dataType) { + switch (dataType.toPrimitive()) { case BYTE: return new Bytes (input, chunksPerRow, samplesPerChunk, skipAfterChunks, pixelsPerElement); - case USHORT: // Fall through case SHORT: return new Shorts (input, chunksPerRow, samplesPerChunk, skipAfterChunks, pixelsPerElement); - case UINT: // Fall through case INT: return new Ints (input, chunksPerRow, samplesPerChunk, skipAfterChunks, pixelsPerElement); case FLOAT: return new Floats (input, chunksPerRow, samplesPerChunk, skipAfterChunks, pixelsPerElement); case DOUBLE: return new Doubles(input, chunksPerRow, samplesPerChunk, skipAfterChunks, pixelsPerElement); diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java index 82e5a12c89..57fa2ee2eb 100644 --- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java +++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java @@ -104,11 +104,9 @@ abstract class HorizontalPredictor extends PredictorChannel { static HorizontalPredictor create(final CompressionChannel input, final DataType dataType, final int pixelStride, final int width) { - switch (dataType) { + switch (dataType.toPrimitive()) { case BYTE: return new Bytes (input, pixelStride, width); - case USHORT: // Fall through case SHORT: return new Shorts (input, pixelStride, width); - case UINT: // Fall through case INT: return new Integers(input, pixelStride, width); case FLOAT: return new Floats (input, pixelStride, width); case DOUBLE: return new Doubles (input, pixelStride, width); diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/HorizontalPredictor.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/HorizontalPredictor.java index 2ec643fac2..a352558315 100644 --- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/HorizontalPredictor.java +++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/HorizontalPredictor.java @@ -71,11 +71,9 @@ abstract class HorizontalPredictor extends PredictorChannel { static HorizontalPredictor create(final PixelChannel output, final DataType dataType, final int pixelStride, final int scanlineStride) { - switch (dataType) { + switch (dataType.toPrimitive()) { case BYTE: return new Bytes (output, pixelStride, scanlineStride); - case USHORT: // Fall through case SHORT: return new Shorts (output, pixelStride, scanlineStride); - case UINT: // Fall through case INT: return new Integers(output, pixelStride, scanlineStride); case FLOAT: return new Floats (output, pixelStride, scanlineStride); case DOUBLE: return new Doubles (output, pixelStride, scanlineStride); diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/TileMatrix.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/TileMatrix.java index e38be04eb6..d7046f6661 100644 --- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/TileMatrix.java +++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/TileMatrix.java @@ -279,15 +279,14 @@ public final class TileMatrix { if (dataByteOrder != null) { compOutput.buffer.order(dataByteOrder); } - switch (type) { + switch (type.toDataBufferType()) { default: throw new AssertionError(type); - case BYTE: rect.write(compOutput, ((DataBufferByte) buffer).getData(b), offset, direct); break; - case USHORT: rect.write(compOutput, ((DataBufferUShort) buffer).getData(b), offset); break; - case SHORT: rect.write(compOutput, ((DataBufferShort) buffer).getData(b), offset); break; - case UINT: // Fall through - case INT: rect.write(compOutput, ((DataBufferInt) buffer).getData(b), offset); break; - case FLOAT: rect.write(compOutput, ((DataBufferFloat) buffer).getData(b), offset); break; - case DOUBLE: rect.write(compOutput, ((DataBufferDouble) buffer).getData(b), offset); break; + case DataBuffer.TYPE_BYTE: rect.write(compOutput, ((DataBufferByte) buffer).getData(b), offset, direct); break; + case DataBuffer.TYPE_USHORT: rect.write(compOutput, ((DataBufferUShort) buffer).getData(b), offset); break; + case DataBuffer.TYPE_SHORT: rect.write(compOutput, ((DataBufferShort) buffer).getData(b), offset); break; + case DataBuffer.TYPE_INT: rect.write(compOutput, ((DataBufferInt) buffer).getData(b), offset); break; + case DataBuffer.TYPE_FLOAT: rect.write(compOutput, ((DataBufferFloat) buffer).getData(b), offset); break; + case DataBuffer.TYPE_DOUBLE: rect.write(compOutput, ((DataBufferDouble) buffer).getData(b), offset); break; } if (compressor != null) { compressor.finish(compOutput);