From faab9517ddf8db4241f9bc3daec76dc534706ae3 Mon Sep 17 00:00:00 2001 From: Bernhard Fey <43403851+bernhardf-ro@users.noreply.github.com> Date: Tue, 25 Sep 2018 10:24:20 +0200 Subject: [PATCH] Fix for non-RGB images with extra sample Added "create" method to TIFFImageReader that centralizes the use of "createBanded" and "createInterleaved" as well as the "extra samples" special case and fixes non-RGB images with non-alpha extra samples (cherry picked from commit f9b8cae0ea2f3df56af3d5272f6b252a49fad445) --- .../imageio/plugins/tiff/TIFFImageReader.java | 64 ++++++------------- 1 file changed, 18 insertions(+), 46 deletions(-) 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 75c589cb..5d8351cd 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 @@ -498,7 +498,7 @@ public final class TIFFImageReader extends ImageReaderBase { return ImageTypeSpecifiers.createPackedGrayscale(cs, bitsPerSample, dataType); } else if (bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) { - return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0}, dataType, false, false); + return create(TIFFBaseline.PLANARCONFIG_CHUNKY, cs, dataType, significantSamples, samplesPerPixel, false, false); } else if (bitsPerSample % 2 == 0) { ColorModel colorModel = new ComponentColorModel(cs, new int[] {bitsPerSample}, false, false, Transparency.OPAQUE, dataType); @@ -530,12 +530,7 @@ public final class TIFFImageReader extends ImageReaderBase { else if (/*bitsPerSample == 1 || bitsPerSample == 2 || bitsPerSample == 4 ||*/ bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) { // TODO: Should use packed format for 1/2/4 chunky. // TODO: For 1/2/4 bit planar, we might need to fix while reading... Look at IFFImageReader? - switch (planarConfiguration) { - case TIFFBaseline.PLANARCONFIG_CHUNKY: - return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1}, dataType, true, isAlphaPremultiplied); - case TIFFExtension.PLANARCONFIG_PLANAR: - return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1}, new int[] {0, 0}, dataType, true, isAlphaPremultiplied); - } + return create(planarConfiguration, cs, dataType, significantSamples, samplesPerPixel, true, isAlphaPremultiplied); } throw new IIOException(String.format("Unsupported BitsPerSample for Gray + Alpha TIFF (expected 8, 16 or 32): %d", bitsPerSample)); @@ -559,14 +554,7 @@ public final class TIFFImageReader extends ImageReaderBase { switch (significantSamples) { case 3: if (bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) { - switch (planarConfiguration) { - case TIFFBaseline.PLANARCONFIG_CHUNKY: - // "TYPE_3BYTE_RGB" if cs.isCS_sRGB() - return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1, 2}, dataType, false, false); - - case TIFFExtension.PLANARCONFIG_PLANAR: - return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1, 2}, new int[] {0, 0, 0}, dataType, false, false); - } + return create(planarConfiguration, cs, dataType, significantSamples, samplesPerPixel, false, false); } else if (bitsPerSample > 8 && bitsPerSample % 2 == 0) { // TODO: Support variable bits/sample? @@ -578,22 +566,7 @@ public final class TIFFImageReader extends ImageReaderBase { } case 4: if (bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) { - switch (planarConfiguration) { - case TIFFBaseline.PLANARCONFIG_CHUNKY: - // "TYPE_4BYTE_RGBA" if cs.isCS_sRGB() - if (hasAlpha && extraSamples.length == 1) { - return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1, 2, 3}, dataType, true, isAlphaPremultiplied); - } - else { - return new ImageTypeSpecifier( - new ExtraSamplesColorModel(cs, hasAlpha, isAlphaPremultiplied, dataType, samplesPerPixel - significantSamples), - new PixelInterleavedSampleModel(dataType, 1, 1, samplesPerPixel, samplesPerPixel, createOffsets(samplesPerPixel)) - ); - } - - case TIFFExtension.PLANARCONFIG_PLANAR: - return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1, 2, 3}, new int[] {0, 0, 0, 0}, dataType, true, isAlphaPremultiplied); - } + return create(planarConfiguration, cs, dataType, significantSamples, samplesPerPixel, true, isAlphaPremultiplied); } else if (significantSamples == 4 && bitsPerSample == 4) { return ImageTypeSpecifiers.createPacked(cs, 0xF000, 0xF00, 0xF0, 0xF, DataBuffer.TYPE_USHORT, isAlphaPremultiplied); @@ -646,22 +619,9 @@ public final class TIFFImageReader extends ImageReaderBase { switch (significantSamples) { case 4: - if (bitsPerSample == 8 || bitsPerSample == 16) { - switch (planarConfiguration) { - case TIFFBaseline.PLANARCONFIG_CHUNKY: - return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1, 2, 3}, dataType, false, false); - case TIFFExtension.PLANARCONFIG_PLANAR: - return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1, 2, 3}, new int[] {0, 0, 0, 0}, dataType, false, false); - } - } case 5: if (bitsPerSample == 8 || bitsPerSample == 16) { - switch (planarConfiguration) { - case TIFFBaseline.PLANARCONFIG_CHUNKY: - return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1, 2, 3, 4}, dataType, true, isAlphaPremultiplied); - case TIFFExtension.PLANARCONFIG_PLANAR: - return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1, 2, 3, 4}, new int[] {0, 0, 0, 0, 0}, dataType, true, isAlphaPremultiplied); - } + return create(planarConfiguration, cs, dataType, significantSamples, samplesPerPixel, significantSamples == 5, isAlphaPremultiplied); } default: @@ -677,7 +637,7 @@ public final class TIFFImageReader extends ImageReaderBase { cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); switch (planarConfiguration) { case TIFFBaseline.PLANARCONFIG_CHUNKY: - return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1, 2}, dataType, false, false); + return create(TIFFBaseline.PLANARCONFIG_CHUNKY, cs, dataType, 3, samplesPerPixel, false, false); case TIFFExtension.PLANARCONFIG_PLANAR: // TODO: Reading works fine, but we can't convert the Lab values properly yet. Need to rewrite normalizeColor //return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1, 2}, new int[] {0, 0, 0}, dataType, false, false); @@ -701,6 +661,18 @@ public final class TIFFImageReader extends ImageReaderBase { } } + private ImageTypeSpecifier create(int planarConfiguration, ColorSpace cs, int dataType, int significantSamples, int samplesPerPixel, boolean alpha, boolean alphaPremultiplied) { + if (planarConfiguration != TIFFExtension.PLANARCONFIG_PLANAR) { + if (samplesPerPixel > significantSamples) { + return new ImageTypeSpecifier( + new ExtraSamplesColorModel(cs, alpha, alphaPremultiplied, dataType, samplesPerPixel - significantSamples), + new PixelInterleavedSampleModel(dataType, 1, 1, samplesPerPixel, samplesPerPixel, createOffsets(samplesPerPixel))); + } + return ImageTypeSpecifiers.createInterleaved(cs, createOffsets(significantSamples), dataType, alpha, alphaPremultiplied); + } + return ImageTypeSpecifiers.createBanded(cs, createOffsets(significantSamples), new int[significantSamples], dataType, alpha, alphaPremultiplied); + } + private static int[] createOffsets(int samplesPerPixel) { int[] offsets = new int[samplesPerPixel]; for (int i = 0; i < samplesPerPixel; i++) {