mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 03:55:28 -04:00
#473: Fix for ColorMap (Indexed) TIFF with non-alpha ExtraSamples.
This commit is contained in:
parent
5ade293445
commit
3e4b14f984
@ -37,20 +37,26 @@ import static com.twelvemonkeys.lang.Validate.notNull;
|
||||
|
||||
/**
|
||||
* This class represents a hybrid between an {@link IndexColorModel} and a {@link ComponentColorModel},
|
||||
* having both a color map and a full, discrete alpha channel.
|
||||
* having both a color map and a full, discrete alpha channel and/or one or more "extra" channels.
|
||||
* The color map entries are assumed to be fully opaque and should have no transparent index.
|
||||
* <p>
|
||||
* ColorSpace will always be the default sRGB color space (as with {@code IndexColorModel}).
|
||||
* <p>
|
||||
* Component order is always P, A, where P is a palette index, and A is the alpha value.
|
||||
* Component order is always I, A, X<sub>1</sub>, X<sub>2</sub>... X<sub>n</sub>,
|
||||
* where I is a palette index, A is the alpha value and X<sub>n</sub> are extra samples (ignored for display).
|
||||
*
|
||||
* @see IndexColorModel
|
||||
* @see ComponentColorModel
|
||||
*/
|
||||
// TODO: ExtraSamplesIndexColorModel might be a better name?
|
||||
// TODO: Allow specifying which channel is the transparency mask?
|
||||
public final class DiscreteAlphaIndexColorModel extends ColorModel {
|
||||
// Our IndexColorModel delegate
|
||||
private final IndexColorModel icm;
|
||||
|
||||
private final int samples;
|
||||
private final boolean hasAlpha;
|
||||
|
||||
/**
|
||||
* Creates a {@code DiscreteAlphaIndexColorModel}, delegating color map look-ups
|
||||
* to the given {@code IndexColorModel}.
|
||||
@ -59,13 +65,34 @@ public final class DiscreteAlphaIndexColorModel extends ColorModel {
|
||||
* fully opaque, any transparency or transparent index will be ignored.
|
||||
*/
|
||||
public DiscreteAlphaIndexColorModel(final IndexColorModel icm) {
|
||||
this(icm, 1, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DiscreteAlphaIndexColorModel}, delegating color map look-ups
|
||||
* to the given {@code IndexColorModel}.
|
||||
*
|
||||
* @param icm The {@code IndexColorModel} delegate. Color map entries are assumed to be
|
||||
* fully opaque, any transparency or transparent index will be ignored.
|
||||
* @param extraSamples the number of extra samples in the color model.
|
||||
* @param hasAlpha {@code true} if the extra samples contains alpha, otherwise {@code false}.
|
||||
*/
|
||||
public DiscreteAlphaIndexColorModel(final IndexColorModel icm, int extraSamples, boolean hasAlpha) {
|
||||
super(
|
||||
notNull(icm, "IndexColorModel").getPixelSize() * 2,
|
||||
notNull(icm, "IndexColorModel").getPixelSize() * (1 + extraSamples),
|
||||
new int[] {icm.getPixelSize(), icm.getPixelSize(), icm.getPixelSize(), icm.getPixelSize()},
|
||||
icm.getColorSpace(), true, false, Transparency.TRANSLUCENT, icm.getTransferType()
|
||||
icm.getColorSpace(), hasAlpha, false, hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE,
|
||||
icm.getTransferType()
|
||||
);
|
||||
|
||||
this.icm = icm;
|
||||
this.samples = 1 + extraSamples;
|
||||
this.hasAlpha = hasAlpha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumComponents() {
|
||||
return samples;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -85,7 +112,7 @@ public final class DiscreteAlphaIndexColorModel extends ColorModel {
|
||||
|
||||
@Override
|
||||
public final int getAlpha(final int pixel) {
|
||||
return (int) ((((float) pixel) / ((1 << getComponentSize(3))-1)) * 255.0f + 0.5f);
|
||||
return hasAlpha ? (int) ((((float) pixel) / ((1 << getComponentSize(3))-1)) * 255.0f + 0.5f) : 0xff;
|
||||
}
|
||||
|
||||
private int getSample(final Object inData, final int index) {
|
||||
@ -128,17 +155,27 @@ public final class DiscreteAlphaIndexColorModel extends ColorModel {
|
||||
|
||||
@Override
|
||||
public final int getAlpha(final Object inData) {
|
||||
return getAlpha(getSample(inData, 1));
|
||||
return hasAlpha ? getAlpha(getSample(inData, 1)) : 0xff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SampleModel createCompatibleSampleModel(final int w, final int h) {
|
||||
return new PixelInterleavedSampleModel(transferType, w, h, 2, w * 2, new int[] {0, 1});
|
||||
return new PixelInterleavedSampleModel(transferType, w, h, samples, w * samples, createOffsets(samples));
|
||||
}
|
||||
|
||||
private int[] createOffsets(int samples) {
|
||||
int[] offsets = new int[samples];
|
||||
|
||||
for (int i = 0; i < samples; i++) {
|
||||
offsets[i] = i;
|
||||
}
|
||||
|
||||
return offsets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isCompatibleSampleModel(final SampleModel sm) {
|
||||
return sm instanceof PixelInterleavedSampleModel && sm.getNumBands() == 2;
|
||||
return sm instanceof PixelInterleavedSampleModel && sm.getNumBands() == samples;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -150,7 +187,7 @@ public final class DiscreteAlphaIndexColorModel extends ColorModel {
|
||||
public final boolean isCompatibleRaster(final Raster raster) {
|
||||
int size = raster.getSampleModel().getSampleSize(0);
|
||||
return ((raster.getTransferType() == transferType) &&
|
||||
(raster.getNumBands() == 2) && ((1 << size) >= icm.getMapSize()));
|
||||
(raster.getNumBands() == samples) && ((1 << size) >= icm.getMapSize()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -44,7 +44,7 @@ import static com.twelvemonkeys.lang.Validate.notNull;
|
||||
* Fixes some subtle bugs in {@code ImageTypeSpecifier}'s factory methods, but
|
||||
* in most cases, this class will delegate to the corresponding methods in {@link ImageTypeSpecifier}.
|
||||
*
|
||||
* @see javax.imageio.ImageTypeSpecifier
|
||||
* @see ImageTypeSpecifier
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: ImageTypeSpecifiers.java,v 1.0 24.01.11 17.51 haraldk Exp$
|
||||
@ -186,4 +186,9 @@ public final class ImageTypeSpecifiers {
|
||||
ColorModel colorModel = new DiscreteAlphaIndexColorModel(pColorModel);
|
||||
return new ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(1, 1));
|
||||
}
|
||||
|
||||
public static ImageTypeSpecifier createDiscreteExtraSamplesIndexedFromIndexColorModel(final IndexColorModel pColorModel, int extraSamples, boolean hasAlpha) {
|
||||
ColorModel colorModel = new DiscreteAlphaIndexColorModel(pColorModel, extraSamples, hasAlpha);
|
||||
return new ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(1, 1));
|
||||
}
|
||||
}
|
||||
|
@ -55,11 +55,14 @@ import com.twelvemonkeys.io.LittleEndianDataInputStream;
|
||||
import com.twelvemonkeys.io.enc.DecoderStream;
|
||||
import com.twelvemonkeys.io.enc.PackBitsDecoder;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import com.twelvemonkeys.xml.XMLSerializer;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.event.IIOReadWarningListener;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.plugins.jpeg.JPEGImageReadParam;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
@ -71,6 +74,7 @@ import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -80,6 +84,7 @@ import java.util.zip.InflaterInputStream;
|
||||
|
||||
import static com.twelvemonkeys.imageio.util.IIOUtil.createStreamAdapter;
|
||||
import static com.twelvemonkeys.imageio.util.IIOUtil.lookupProviderByName;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/**
|
||||
* ImageReader implementation for Aldus/Adobe Tagged Image File Format (TIFF).
|
||||
@ -111,7 +116,8 @@ import static com.twelvemonkeys.imageio.util.IIOUtil.lookupProviderByName;
|
||||
* </ul>
|
||||
*
|
||||
* @see <a href="http://partners.adobe.com/public/developer/tiff/index.html">Adobe TIFF developer resources</a>
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Tagged_Image_File_Format">Wikipedia</a>
|
||||
* @see <a href="http://www.alternatiff.com/resources/TIFF6.pdf">TIFF 6.0 specification</a>
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Tagged_Image_File_Format">Wikipedia TIFF</a>
|
||||
* @see <a href="http://www.awaresystems.be/imaging/tiff.html">AWare Systems TIFF pages</a>
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
@ -122,10 +128,6 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
// TODOs ImageIO basic functionality:
|
||||
// TODO: Thumbnail support (what is a TIFF thumbnail anyway? Photoshop way? Or use subfiletype?)
|
||||
|
||||
// TODOs Full BaseLine support:
|
||||
// TODO: Support ExtraSamples (an array, if multiple extra samples!)
|
||||
// (0: Unspecified (not alpha), 1: Associated Alpha (pre-multiplied), 2: Unassociated Alpha (non-multiplied)
|
||||
|
||||
// TODOs ImageIO advanced functionality:
|
||||
// TODO: Tiling support (readTile, readTileRaster)
|
||||
// TODO: Implement readAsRenderedImage to allow tiled RenderedImage?
|
||||
@ -148,6 +150,8 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
// Support ICCProfile
|
||||
// Support PlanarConfiguration 2
|
||||
// Support Compression 3 & 4 (CCITT T.4 & T.6)
|
||||
// Support ExtraSamples (an array, if multiple extra samples!)
|
||||
// (0: Unspecified (not alpha), 1: Associated Alpha (pre-multiplied), 2: Unassociated Alpha (non-multiplied)
|
||||
|
||||
final static boolean DEBUG = "true".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.imageio.plugins.tiff.debug"));
|
||||
|
||||
@ -469,6 +473,10 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
// as some software will treat black/white runs as-is, regardless of photometric.
|
||||
// Special handling is also in the normalizeColor method
|
||||
if (significantSamples == 1 && bitsPerSample == 1) {
|
||||
if (profile != null) {
|
||||
processWarningOccurred("Ignoring embedded ICC color profile for Bi-level/Gray TIFF");
|
||||
}
|
||||
|
||||
byte[] lut = new byte[] {-1, 0};
|
||||
return ImageTypeSpecifier.createIndexed(lut, lut, lut, null, bitsPerSample, dataType);
|
||||
}
|
||||
@ -591,8 +599,8 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
|
||||
IndexColorModel icm = createIndexColorModel(bitsPerSample, dataType, (int[]) colorMap.getValue());
|
||||
|
||||
if (hasAlpha) {
|
||||
return ImageTypeSpecifiers.createDiscreteAlphaIndexedFromIndexColorModel(icm);
|
||||
if (extraSamples != null) {
|
||||
return ImageTypeSpecifiers.createDiscreteExtraSamplesIndexedFromIndexColorModel(icm, extraSamples.length, hasAlpha);
|
||||
}
|
||||
|
||||
return ImageTypeSpecifiers.createFromIndexColorModel(icm);
|
||||
@ -921,6 +929,10 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
if (stripTileByteCounts == null) {
|
||||
processWarningOccurred("Missing TileByteCounts for tiled TIFF with compression: " + compression);
|
||||
}
|
||||
else if (stripTileByteCounts.length == 0 || containsZero(stripTileByteCounts)) {
|
||||
stripTileByteCounts = null;
|
||||
processWarningOccurred("Ignoring all-zero TileByteCounts for tiled TIFF with compression: " + compression);
|
||||
}
|
||||
|
||||
stripTileWidth = getValueAsInt(TIFF.TAG_TILE_WIDTH, "TileWidth");
|
||||
stripTileHeight = getValueAsInt(TIFF.TAG_TILE_HEIGTH, "TileHeight");
|
||||
@ -931,6 +943,10 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
if (stripTileByteCounts == null) {
|
||||
processWarningOccurred("Missing StripByteCounts for TIFF with compression: " + compression);
|
||||
}
|
||||
else if (stripTileByteCounts.length == 0 || containsZero(stripTileByteCounts)) {
|
||||
stripTileByteCounts = null;
|
||||
processWarningOccurred("Ignoring all-zero StripByteCounts for TIFF with compression: " + compression);
|
||||
}
|
||||
|
||||
// NOTE: This is really against the spec, but libTiff seems to handle it. TIFF 6.0 says:
|
||||
// "Do not use both strip- oriented and tile-oriented fields in the same TIFF file".
|
||||
@ -1309,13 +1325,11 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
int len = stripTileByteCounts != null ? (int) stripTileByteCounts[i] : Integer.MAX_VALUE;
|
||||
imageInput.seek(stripTileOffsets != null ? stripTileOffsets[i] : realJPEGOffset);
|
||||
|
||||
try (ImageInputStream stream = ImageIO.createImageInputStream(new SequenceInputStream(Collections.enumeration(
|
||||
Arrays.asList(
|
||||
try (ImageInputStream stream = ImageIO.createImageInputStream(new SequenceInputStream(Collections.enumeration(asList(
|
||||
new ByteArrayInputStream(jpegHeader),
|
||||
createStreamAdapter(imageInput, len),
|
||||
new ByteArrayInputStream(new byte[] {(byte) 0xff, (byte) 0xd9}) // EOI
|
||||
)
|
||||
)))) {
|
||||
new ByteArrayInputStream(new byte[]{(byte) 0xff, (byte) 0xd9}) // EOI
|
||||
))))) {
|
||||
jpegReader.setInput(stream);
|
||||
jpegParam.setSourceRegion(new Rectangle(0, 0, colsInTile, rowsInTile));
|
||||
jpegParam.setSourceSubsampling(xSub, ySub, 0, 0);
|
||||
@ -1460,7 +1474,7 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
try (ImageInputStream stream = ImageIO.createImageInputStream(new SequenceInputStream(Collections.enumeration(
|
||||
Arrays.asList(
|
||||
asList(
|
||||
createJFIFStream(destRaster.getNumBands(), stripTileWidth, stripTileHeight, qTables, dcTables, acTables, subsampling),
|
||||
createStreamAdapter(imageInput, length),
|
||||
new ByteArrayInputStream(new byte[] {(byte) 0xff, (byte) 0xd9}) // EOI
|
||||
@ -1538,6 +1552,16 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
return destination;
|
||||
}
|
||||
|
||||
private boolean containsZero(long[] byteCounts) {
|
||||
for (long byteCount : byteCounts) {
|
||||
if (byteCount <= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private IIOMetadata readJPEGMetadataSafe(final ImageReader jpegReader) throws IOException {
|
||||
try {
|
||||
return jpegReader.getImageMetadata(0);
|
||||
@ -2026,7 +2050,7 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
}
|
||||
}
|
||||
|
||||
private void normalizeColor(int photometricInterpretation, byte[] data) throws IIOException {
|
||||
private void normalizeColor(int photometricInterpretation, byte[] data) throws IOException {
|
||||
switch (photometricInterpretation) {
|
||||
case TIFFBaseline.PHOTOMETRIC_WHITE_IS_ZERO:
|
||||
// NOTE: Preserve WhiteIsZero for 1 bit monochrome, for CCITT compatibility
|
||||
@ -2543,6 +2567,13 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
|
||||
try {
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
|
||||
if (param.getClass().getName().equals("com.twelvemonkeys.imageio.plugins.svg.SVGReadParam")) {
|
||||
Method setBaseURI = param.getClass().getMethod("setBaseURI", String.class);
|
||||
String uri = file.getAbsoluteFile().toURI().toString();
|
||||
setBaseURI.invoke(param, uri);
|
||||
}
|
||||
|
||||
int numImages = reader.getNumImages(true);
|
||||
for (int imageNo = 0; imageNo < numImages; imageNo++) {
|
||||
// if (args.length > 1) {
|
||||
@ -2557,6 +2588,7 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
// int height = reader.getHeight(imageNo);
|
||||
// param.setSourceRegion(new Rectangle(width / 4, height / 4, width / 2, height / 2));
|
||||
// param.setSourceRegion(new Rectangle(100, 300, 400, 400));
|
||||
// param.setSourceRegion(new Rectangle(95, 105, 100, 100));
|
||||
// param.setSourceRegion(new Rectangle(3, 3, 9, 9));
|
||||
// param.setDestinationOffset(new Point(50, 150));
|
||||
// param.setSourceSubsampling(2, 2, 0, 0);
|
||||
@ -2564,16 +2596,18 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
BufferedImage image = reader.read(imageNo, param);
|
||||
System.err.println("Read time: " + (System.currentTimeMillis() - start) + " ms");
|
||||
|
||||
// IIOMetadata metadata = reader.getImageMetadata(imageNo);
|
||||
// if (metadata != null) {
|
||||
// if (metadata.getNativeMetadataFormatName() != null) {
|
||||
// new XMLSerializer(System.out, "UTF-8").serialize(metadata.getAsTree(metadata.getNativeMetadataFormatName()), false);
|
||||
// }
|
||||
// /*else*/
|
||||
// if (metadata.isStandardMetadataFormatSupported()) {
|
||||
// new XMLSerializer(System.out, "UTF-8").serialize(metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName), false);
|
||||
// }
|
||||
// }
|
||||
IIOMetadata metadata = reader.getImageMetadata(imageNo);
|
||||
if (metadata != null) {
|
||||
if (metadata.getNativeMetadataFormatName() != null) {
|
||||
Node tree = metadata.getAsTree(metadata.getNativeMetadataFormatName());
|
||||
replaceBytesWithUndefined((IIOMetadataNode) tree);
|
||||
new XMLSerializer(System.out, "UTF-8").serialize(tree, false);
|
||||
}
|
||||
/*else*/
|
||||
if (metadata.isStandardMetadataFormatSupported()) {
|
||||
new XMLSerializer(System.out, "UTF-8").serialize(metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName), false);
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("image: " + image);
|
||||
|
||||
@ -2659,6 +2693,47 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
}
|
||||
}
|
||||
|
||||
// XMP Spec says "The field type should be UNDEFINED (7) or BYTE (1)"
|
||||
// Adobe Photoshop® TIFF Technical Notes says (for Image Source Data): "Type: UNDEFINED"
|
||||
private static final Set<String> BYTE_TO_UNDEFINED_NODES = new HashSet<>(asList(
|
||||
"700", // XMP
|
||||
"34377", // Photoshop Image Resources
|
||||
"37724" // Image Source Data
|
||||
));
|
||||
|
||||
private static void replaceBytesWithUndefined(IIOMetadataNode tree) {
|
||||
// The output of the TIFFUndefined tag is just much more readable (or easier to skip)
|
||||
|
||||
NodeList nodes = tree.getElementsByTagName("TIFFBytes");
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
IIOMetadataNode node = (IIOMetadataNode) nodes.item(i);
|
||||
|
||||
IIOMetadataNode parentNode = (IIOMetadataNode) node.getParentNode();
|
||||
|
||||
NodeList childNodes = node.getChildNodes();
|
||||
if (BYTE_TO_UNDEFINED_NODES.contains(parentNode.getAttribute("number")) && childNodes.getLength() > 16) {
|
||||
IIOMetadataNode undefined = new IIOMetadataNode("TIFFUndefined");
|
||||
StringBuilder values = new StringBuilder();
|
||||
|
||||
IIOMetadataNode child = (IIOMetadataNode) node.getFirstChild();
|
||||
while (child != null) {
|
||||
if (values.length() > 0) {
|
||||
values.append(", ");
|
||||
}
|
||||
|
||||
String value = child.getAttribute("value");
|
||||
values.append(value);
|
||||
|
||||
child = (IIOMetadataNode) child.getNextSibling();
|
||||
}
|
||||
|
||||
undefined.setAttribute("value", values.toString());
|
||||
|
||||
parentNode.replaceChild(undefined, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void showIt(BufferedImage image, String title) {
|
||||
ImageReaderBase.showIt(image, title);
|
||||
}
|
||||
|
@ -43,10 +43,8 @@ import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.color.ICC_ColorSpace;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.*;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
@ -108,6 +106,7 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
|
||||
new TestData(getClassLoaderResource("/tiff/scan-mono-iccgray.tif"), new Dimension(2408, 3436)), // B/W, PackBits w/gray ICC profile
|
||||
new TestData(getClassLoaderResource("/tiff/planar-striped-lzw.tif"), new Dimension(229, 229)), // RGB 8 bit/sample, planar, LZW compression
|
||||
new TestData(getClassLoaderResource("/tiff/colormap-with-extrasamples.tif"), new Dimension(10, 10)), // Palette, 8 bit/sample, 2 samples/pixel, extra samples, LZW
|
||||
new TestData(getClassLoaderResource("/tiff/indexed-unspecified-extrasamples.tif"), new Dimension(98, 106)), // Palette, 8 bit/sample, 2 samples/pixel, extra samples
|
||||
new TestData(getClassLoaderResource("/tiff/packbits-fillorder-2.tif"), new Dimension(3508, 2481)), // B/W, PackBits, FillOrder 2
|
||||
// CCITT
|
||||
new TestData(getClassLoaderResource("/tiff/ccitt/group3_1d.tif"), new Dimension(6, 4)), // B/W, CCITT T4 1D
|
||||
@ -596,6 +595,7 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
|
||||
@Test
|
||||
public void testAlphaRasterForMultipleExtraSamples() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
|
||||
try (ImageInputStream stream = ImageIO.createImageInputStream(getClassLoaderResource("/tiff/extra-channels.tif"))) {
|
||||
reader.setInput(stream);
|
||||
|
||||
@ -646,15 +646,14 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
|
||||
assertEquals(160, image.getWidth());
|
||||
assertEquals(227, image.getHeight());
|
||||
|
||||
// This TIFF does not contain a ICC profile, making the RGB result depend on the platforms "Generic CMYK" profile
|
||||
if (ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK) instanceof ICC_ColorSpace) {
|
||||
assertRGBEquals("Wrong RGB (0,0)", 0xff1E769D, image.getRGB(0, 0), 4);
|
||||
assertRGBEquals("Wrong RGB (159,226)", 0xff1E769D, image.getRGB(159, 226), 4);
|
||||
}
|
||||
else {
|
||||
assertRGBEquals("Wrong RGB (0,0)", 0xff2896d9, image.getRGB(0, 0), 4);
|
||||
assertRGBEquals("Wrong RGB (159,226)", 0xff2896d9, image.getRGB(159, 226), 4);
|
||||
}
|
||||
// This TIFF does not contain an ICC profile, making the RGB result depend on the platforms "Generic CMYK" profile
|
||||
ColorSpace genericCMYK = ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK);
|
||||
ComponentColorModel cmyk = new ComponentColorModel(genericCMYK, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
|
||||
// Input (0,0): -41, 104, 37, 1 (C, M, Y, K)
|
||||
int expected = cmyk.getRGB(new byte[]{-41, 104, 37, 1});
|
||||
|
||||
assertRGBEquals("Wrong RGB (0,0)", expected, image.getRGB(0, 0), 4);
|
||||
assertRGBEquals("Wrong RGB (159,226)", expected, image.getRGB(159, 226), 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user