james-willis commented on code in PR #3114:
URL: https://github.com/apache/sedona/pull/3114#discussion_r3647021779
##########
common/src/main/java/org/apache/sedona/common/utils/RasterUtils.java:
##########
@@ -647,6 +647,75 @@ public static boolean isDataTypeIntegral(int dataTypeCode)
{
}
}
+ /**
+ * Verifies that {@code noDataValue} can be stored in the pixel type named
by {@code pixelType}
+ * without silent coercion, returning it unchanged when it can. Writing a
value that is out of the
+ * pixel type's range, or fractional for an integer pixel type, coerces the
stored sample to a
+ * different number than the value recorded as the band's nodata metadata
(for example -1.0 or
+ * 300.0 wraps to 255 or 44 in an unsigned 8-bit band), so the background
would then read back as
+ * data rather than nodata. Such a value is a correctness violation, not a
per-row data condition,
+ * so this rejects it with an {@link IllegalArgumentException} instead of
coercing.
+ *
+ * @param noDataValue the candidate nodata / background value
+ * @param pixelType a Sedona pixel type string accepted by {@link
#getDataTypeCode(String)} (for
+ * example {@code "B"}, {@code "I"}, {@code "D"})
+ * @return {@code noDataValue}, unchanged, when it is representable in the
pixel type
+ * @throws IllegalArgumentException when {@code noDataValue} cannot be
represented in the pixel
+ * type
+ */
+ public static double assertNoDataValueRepresentable(double noDataValue,
String pixelType) {
+ int dataTypeCode = getDataTypeCode(pixelType);
+ long min;
+ long max;
+ String description;
+ switch (dataTypeCode) {
+ case DataBuffer.TYPE_BYTE:
+ min = 0;
+ max = 255;
+ description = "unsigned 8-bit";
+ break;
+ case DataBuffer.TYPE_USHORT:
+ min = 0;
+ max = 65535;
+ description = "unsigned 16-bit";
+ break;
+ case DataBuffer.TYPE_SHORT:
+ min = Short.MIN_VALUE;
+ max = Short.MAX_VALUE;
+ description = "signed 16-bit";
+ break;
+ case DataBuffer.TYPE_INT:
+ min = Integer.MIN_VALUE;
+ max = Integer.MAX_VALUE;
+ description = "signed 32-bit";
+ break;
+ case DataBuffer.TYPE_FLOAT:
+ // 32-bit float represents NaN and the infinities; reject only a
finite value whose
+ // magnitude overflows the float range (it would silently become an
infinity). Rounding a
+ // value to the nearest float is the inherent, expected behavior of a
float band.
+ if (Double.isFinite(noDataValue) && Math.abs(noDataValue) >
Float.MAX_VALUE) {
+ throw new IllegalArgumentException(
+ String.format(
+ "noDataValue %s is not representable in pixel type '%s'
(32-bit float, valid range %s..%s)",
+ noDataValue, pixelType, -Float.MAX_VALUE, Float.MAX_VALUE));
+ }
+ return noDataValue;
Review Comment:
0.1d doesn't make any sense as a no data value for a float. Floats cannot
represent 0.1 so you'll never have 0.1 in the data array.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]