From 9f9a9fe900ba43a2319a32627552492eefa35958 Mon Sep 17 00:00:00 2001 From: abhilash-mishra Date: Mon, 6 May 2019 12:36:37 +0530 Subject: [PATCH 1/2] Handling icc profile for TIFF with extra samples. --- .../tiff/TIFFExtraSamplesColorModel.java | 60 +++++++++++++++++++ .../impl/plugins/tiff/TIFFImageReader.java | 31 ++++++---- 2 files changed, 81 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFExtraSamplesColorModel.java diff --git a/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFExtraSamplesColorModel.java b/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFExtraSamplesColorModel.java new file mode 100644 index 0000000..abbcae4 --- /dev/null +++ b/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFExtraSamplesColorModel.java @@ -0,0 +1,60 @@ +package com.github.jaiimageio.impl.plugins.tiff; + +import java.awt.color.ColorSpace; +import java.awt.image.ComponentColorModel; +import java.awt.image.ComponentSampleModel; +import java.awt.image.SampleModel; +import java.awt.image.WritableRaster; +import java.awt.image.DataBuffer; + +public class TIFFExtraSamplesColorModel extends ComponentColorModel { + + private final int numComponents; + + private final int componentSize; + + public TIFFExtraSamplesColorModel(ColorSpace colorSpace, + int[] bits, + boolean hasAlpha, + boolean isAlphaPremultiplied, + int transparency, + int transferType, + int extraComponents) { + super(colorSpace, bits, hasAlpha, isAlphaPremultiplied, transparency, transferType); + this.numComponents = colorSpace.getNumComponents() + (hasAlpha ? 1 : 0) + extraComponents; + this.componentSize = DataBuffer.getDataTypeSize(transferType); + } + + @Override + public int getNumComponents() { + return numComponents; + } + + @Override + public int getComponentSize(int componentIdx) { + return componentSize; + } + + @Override + public boolean isCompatibleSampleModel(SampleModel sm) { + // Must have the same number of components + return (sm instanceof ComponentSampleModel) && numComponents == sm.getNumBands() && transferType == sm.getTransferType(); + } + + @Override + public WritableRaster getAlphaRaster(WritableRaster raster) { + if (!hasAlpha()) { + return null; + } + + int x = raster.getMinX(); + int y = raster.getMinY(); + int[] band = new int[] {getAlphaComponent()}; + + return raster.createWritableChild(x, y, raster.getWidth(), raster.getHeight(), x, y, band); + } + + private int getAlphaComponent() { + return super.getNumComponents() - 1; + } +} diff --git a/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFImageReader.java b/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFImageReader.java index a753b9d..ef6fd42 100644 --- a/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFImageReader.java +++ b/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFImageReader.java @@ -767,22 +767,33 @@ public Iterator getImageTypes(int imageIndex) throws IIOException { // Replace the ColorModel with the ICC ColorModel if the // numbers of samples and color components are amenable. - if(numBands == numComponents || - numBands == numComponents + 1) { + if(numBands == numComponents + extraSamples.length || + numBands == numComponents + 1 + extraSamples.length) { // Set alpha flags. - boolean hasAlpha = numComponents != numBands; + boolean hasAlpha = numComponents + extraSamples.length != numBands; boolean isAlphaPre = hasAlpha && cmRaw.isAlphaPremultiplied(); // Create a ColorModel of the same class and with // the same transfer type. - ColorModel iccColorModel = - new ComponentColorModel(iccColorSpace, - cmRaw.getComponentSize(), - hasAlpha, - isAlphaPre, - cmRaw.getTransparency(), - cmRaw.getTransferType()); + ColorModel iccColorModel = null; + if (extraSamples.length == 0) { + iccColorModel = + new ComponentColorModel(iccColorSpace, + cmRaw.getComponentSize(), + hasAlpha, + isAlphaPre, + cmRaw.getTransparency(), + cmRaw.getTransferType()); + } else { + iccColorModel = new TIFFExtraSamplesColorModel(iccColorSpace, + cmRaw.getComponentSize(), + hasAlpha, + isAlphaPre, + cmRaw.getTransparency(), + cmRaw.getTransferType(), + extraSamples.length); + } // Prepend the ICC profile-based ITS to the List. The // ColorModel and SampleModel are guaranteed to be From 8b7d735fd151311e8930f2cc3a0ebd2d28dbfd03 Mon Sep 17 00:00:00 2001 From: z003vhm Date: Thu, 16 May 2019 01:55:51 +0530 Subject: [PATCH 2/2] extraSamples array could be null. --- .../impl/plugins/tiff/TIFFImageReader.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFImageReader.java b/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFImageReader.java index ef6fd42..7d01688 100644 --- a/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFImageReader.java +++ b/src/main/java/com/github/jaiimageio/impl/plugins/tiff/TIFFImageReader.java @@ -765,19 +765,25 @@ public Iterator getImageTypes(int imageIndex) throws IIOException { int numBands = smRaw.getNumBands(); int numComponents = iccColorSpace.getNumComponents(); + int extraSamplesLength = 0; + + if (extraSamples != null) { + extraSamplesLength = extraSamples.length; + } + // Replace the ColorModel with the ICC ColorModel if the // numbers of samples and color components are amenable. - if(numBands == numComponents + extraSamples.length || - numBands == numComponents + 1 + extraSamples.length) { + if(numBands == numComponents + extraSamplesLength || + numBands == numComponents + 1 + extraSamplesLength) { // Set alpha flags. - boolean hasAlpha = numComponents + extraSamples.length != numBands; + boolean hasAlpha = numComponents + extraSamplesLength != numBands; boolean isAlphaPre = hasAlpha && cmRaw.isAlphaPremultiplied(); // Create a ColorModel of the same class and with // the same transfer type. ColorModel iccColorModel = null; - if (extraSamples.length == 0) { + if (extraSamplesLength == 0) { iccColorModel = new ComponentColorModel(iccColorSpace, cmRaw.getComponentSize(), @@ -792,7 +798,7 @@ public Iterator getImageTypes(int imageIndex) throws IIOException { isAlphaPre, cmRaw.getTransparency(), cmRaw.getTransferType(), - extraSamples.length); + extraSamplesLength); } // Prepend the ICC profile-based ITS to the List. The