diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java
index e1c51753..a5cbb987 100644
--- a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java
+++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java
@@ -781,11 +781,11 @@ public final class TIFFImageReader extends ImageReaderBase {
throw new IIOException("Unsupported BitsPerSample for SampleFormat 2/Signed Integer (expected 8/16/32): " + bitsPerSample);
case TIFFExtension.SAMPLEFORMAT_FP:
- if (bitsPerSample == 32) {
+ if (bitsPerSample == 16 || bitsPerSample == 32) {
return DataBuffer.TYPE_FLOAT;
}
- throw new IIOException("Unsupported BitsPerSample for SampleFormat 3/Floating Point (expected 32): " + bitsPerSample);
+ throw new IIOException("Unsupported BitsPerSample for SampleFormat 3/Floating Point (expected 16/32): " + bitsPerSample);
default:
throw new IIOException("Unknown TIFF SampleFormat (expected 1, 2, 3 or 4): " + sampleFormat);
}
@@ -1969,7 +1969,9 @@ public final class TIFFImageReader extends ImageReaderBase {
case DataBuffer.TYPE_FLOAT:
/*for (int band = 0; band < bands; band++)*/ {
+ boolean needsWidening = getBitsPerSample() == 16;
float[] rowDataFloat = ((DataBufferFloat) tileRowRaster.getDataBuffer()).getData(band);
+ short[] rowDataShort = needsWidening ? new short[rowDataFloat.length] : null;
WritableRaster destChannel = banded
? raster.createWritableChild(raster.getMinX(), raster.getMinY(), raster.getWidth(), raster.getHeight(), 0, 0, new int[] {band})
@@ -1978,12 +1980,19 @@ public final class TIFFImageReader extends ImageReaderBase {
? tileRowRaster.createChild(tileRowRaster.getMinX(), 0, tileRowRaster.getWidth(), 1, 0, 0, new int[] {band})
: tileRowRaster;
+
for (int row = startRow; row < startRow + rowsInTile; row++) {
if (row >= srcRegion.y + srcRegion.height) {
break; // We're done with this tile
}
- readFully(input, rowDataFloat);
+ if (needsWidening) {
+ readFully(input, rowDataShort);
+ toFloat(rowDataFloat, rowDataShort);
+ }
+ else {
+ readFully(input, rowDataFloat);
+ }
if (row >= srcRegion.y) {
normalizeColor(interpretation, rowDataFloat);
@@ -2008,7 +2017,52 @@ public final class TIFFImageReader extends ImageReaderBase {
}
}
- private void clamp(float[] rowDataFloat) {
+ private void toFloat(final float[] rowDataFloat, final short[] rowDataShort) {
+ for (int i = 0; i < rowDataFloat.length; i++) {
+ rowDataFloat[i] = toFloat(rowDataShort[i]);
+ }
+ }
+
+ /**
+ * Converts an IEEE 754 half-precision data type to single-precision.
+ *
+ * @param shortValue a 16 bit half precision value
+ * @return an IEE 754 single precision float
+ *
+ * @see Stack Overflow answer by x4u
+ * @see