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