Merge pull request #446 from bernhardf-ro/master

Fix for corrupted output from non-RGB TIFF images with extra samples
This commit is contained in:
Harald Kuhr 2018-10-26 20:21:12 +02:00 committed by GitHub
commit 38ea0989d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 46 deletions

View File

@ -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 createImageTypeSpecifier(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 createImageTypeSpecifier(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 createImageTypeSpecifier(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 createImageTypeSpecifier(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 createImageTypeSpecifier(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 createImageTypeSpecifier(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,22 @@ public final class TIFFImageReader extends ImageReaderBase {
}
}
private ImageTypeSpecifier createImageTypeSpecifier(int planarConfiguration, ColorSpace cs, int dataType, int significantSamples, int samplesPerPixel, boolean alpha, boolean alphaPremultiplied) throws IIOException {
switch (planarConfiguration) {
case TIFFBaseline.PLANARCONFIG_CHUNKY:
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);
case TIFFExtension.PLANARCONFIG_PLANAR:
return ImageTypeSpecifiers.createBanded(cs, createOffsets(significantSamples), new int[significantSamples], dataType, alpha, alphaPremultiplied);
default:
throw new IIOException(String.format("Unsupported PlanarConfiguration (expected 1 or 2): %d", planarConfiguration));
}
}
private static int[] createOffsets(int samplesPerPixel) {
int[] offsets = new int[samplesPerPixel];
for (int i = 0; i < samplesPerPixel; i++) {