mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 03:55:28 -04:00
Fixed NullPointerException due to missing PhotometricInterpretation, now uses fallback as we do when reading.
This commit is contained in:
parent
9d3f271867
commit
1f33afb5a1
@ -30,6 +30,22 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.tiff;
|
||||
|
||||
import static com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReader.guessPhotometricInterpretation;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import com.twelvemonkeys.imageio.AbstractMetadata;
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
@ -39,19 +55,6 @@ import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.TIFFEntry;
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import java.lang.reflect.Array;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* TIFFImageMetadata.
|
||||
*
|
||||
@ -354,8 +357,7 @@ public final class TIFFImageMetadata extends AbstractMetadata {
|
||||
IIOMetadataNode chroma = new IIOMetadataNode("Chroma");
|
||||
|
||||
// Handle ColorSpaceType (RGB/CMYK/YCbCr etc)...
|
||||
Entry photometricTag = ifd.getEntryById(TIFF.TAG_PHOTOMETRIC_INTERPRETATION);
|
||||
int photometricValue = getValueAsInt(photometricTag); // No default for this tag!
|
||||
int photometricValue = getPhotometricInterpretationWithFallback(); // No default for this tag!
|
||||
int numChannelsValue = getSamplesPerPixelWithFallback();
|
||||
|
||||
IIOMetadataNode colorSpaceType = new IIOMetadataNode("ColorSpaceType");
|
||||
@ -446,6 +448,13 @@ public final class TIFFImageMetadata extends AbstractMetadata {
|
||||
return chroma;
|
||||
}
|
||||
|
||||
private int getPhotometricInterpretationWithFallback() {
|
||||
Entry photometricTag = ifd.getEntryById(TIFF.TAG_PHOTOMETRIC_INTERPRETATION);
|
||||
|
||||
return photometricTag != null ? getValueAsInt(photometricTag)
|
||||
: guessPhotometricInterpretation(getCompression(), getSamplesPerPixelWithFallback(), ifd.getEntryById(TIFF.TAG_EXTRA_SAMPLES), ifd.getEntryById(TIFF.TAG_COLOR_MAP));
|
||||
}
|
||||
|
||||
private int getSamplesPerPixelWithFallback() {
|
||||
// SamplePerPixel defaults to 1, but we'll check BitsPerSample to be sure
|
||||
Entry samplesPerPixelTag = ifd.getEntryById(TIFF.TAG_SAMPLES_PER_PIXEL);
|
||||
@ -456,15 +465,19 @@ public final class TIFFImageMetadata extends AbstractMetadata {
|
||||
: bitsPerSampleTag != null ? bitsPerSampleTag.valueCount() : 1;
|
||||
}
|
||||
|
||||
private int getCompression() {
|
||||
Entry compressionTag = ifd.getEntryById(TIFF.TAG_COMPRESSION);
|
||||
return compressionTag == null
|
||||
? TIFFBaseline.COMPRESSION_NONE
|
||||
: getValueAsInt(compressionTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardCompressionNode() {
|
||||
IIOMetadataNode compression = new IIOMetadataNode("Compression");
|
||||
IIOMetadataNode compressionTypeName = addChildNode(compression, "CompressionTypeName", null);
|
||||
|
||||
Entry compressionTag = ifd.getEntryById(TIFF.TAG_COMPRESSION);
|
||||
int compressionValue = compressionTag == null
|
||||
? TIFFBaseline.COMPRESSION_NONE
|
||||
: getValueAsInt(compressionTag);
|
||||
int compressionValue = getCompression();
|
||||
|
||||
// Naming is identical to JAI ImageIO metadata as far as possible
|
||||
switch (compressionValue) {
|
||||
|
@ -712,40 +712,49 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
private int getPhotometricInterpretationWithFallback() throws IIOException {
|
||||
// PhotometricInterpretation is a required tag, but as it can be guessed this does a fallback that is similar to JAI ImageIO.
|
||||
int interpretation = getValueAsIntWithDefault(TIFF.TAG_PHOTOMETRIC_INTERPRETATION, "PhotometricInterpretation", -1);
|
||||
|
||||
if (interpretation == -1) {
|
||||
int compression = getValueAsIntWithDefault(TIFF.TAG_COMPRESSION, TIFFBaseline.COMPRESSION_NONE);
|
||||
int samplesPerPixel = getValueAsIntWithDefault(TIFF.TAG_SAMPLES_PER_PIXEL, 1);
|
||||
Entry extraSamplesEntry = currentIFD.getEntryById(TIFF.TAG_EXTRA_SAMPLES);
|
||||
int extraSamples = extraSamplesEntry == null ? 0 : extraSamplesEntry.valueCount();
|
||||
Entry extraSamples = currentIFD.getEntryById(TIFF.TAG_EXTRA_SAMPLES);
|
||||
Entry colorMap = currentIFD.getEntryById(TIFF.TAG_COLOR_MAP);
|
||||
|
||||
interpretation = guessPhotometricInterpretation(compression, samplesPerPixel, extraSamples, colorMap);
|
||||
|
||||
if (compression == TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE
|
||||
|| compression == TIFFExtension.COMPRESSION_CCITT_T4
|
||||
|| compression == TIFFExtension.COMPRESSION_CCITT_T6) {
|
||||
interpretation = TIFFBaseline.PHOTOMETRIC_WHITE_IS_ZERO;
|
||||
}
|
||||
else if (currentIFD.getEntryById(TIFF.TAG_COLOR_MAP) != null) {
|
||||
interpretation = TIFFBaseline.PHOTOMETRIC_PALETTE;
|
||||
}
|
||||
else if ((samplesPerPixel - extraSamples) == 3) {
|
||||
if (compression == TIFFExtension.COMPRESSION_JPEG
|
||||
|| compression == TIFFExtension.COMPRESSION_OLD_JPEG) {
|
||||
interpretation = TIFFExtension.PHOTOMETRIC_YCBCR;
|
||||
}
|
||||
else {
|
||||
interpretation = TIFFBaseline.PHOTOMETRIC_RGB;
|
||||
}
|
||||
}
|
||||
else if ((samplesPerPixel - extraSamples) == 4) {
|
||||
interpretation = TIFFExtension.PHOTOMETRIC_SEPARATED;
|
||||
}
|
||||
else {
|
||||
interpretation = TIFFBaseline.PHOTOMETRIC_BLACK_IS_ZERO;
|
||||
}
|
||||
processWarningOccurred("Missing PhotometricInterpretation, determining fallback: " + interpretation);
|
||||
}
|
||||
|
||||
return interpretation;
|
||||
}
|
||||
|
||||
static int guessPhotometricInterpretation(int compression, int samplesPerPixel, Entry extraSamples, Entry colorMap) {
|
||||
int extraSamplesCount = extraSamples == null ? 0 : extraSamples.valueCount();
|
||||
|
||||
if (compression == TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE
|
||||
|| compression == TIFFExtension.COMPRESSION_CCITT_T4
|
||||
|| compression == TIFFExtension.COMPRESSION_CCITT_T6) {
|
||||
return TIFFBaseline.PHOTOMETRIC_WHITE_IS_ZERO;
|
||||
}
|
||||
else if (colorMap != null) {
|
||||
return TIFFBaseline.PHOTOMETRIC_PALETTE;
|
||||
}
|
||||
else if ((samplesPerPixel - extraSamplesCount) == 3) {
|
||||
if (compression == TIFFExtension.COMPRESSION_JPEG
|
||||
|| compression == TIFFExtension.COMPRESSION_OLD_JPEG) {
|
||||
return TIFFExtension.PHOTOMETRIC_YCBCR;
|
||||
}
|
||||
else {
|
||||
return TIFFBaseline.PHOTOMETRIC_RGB;
|
||||
}
|
||||
}
|
||||
else if ((samplesPerPixel - extraSamplesCount) == 4) {
|
||||
return TIFFExtension.PHOTOMETRIC_SEPARATED;
|
||||
}
|
||||
else {
|
||||
return TIFFBaseline.PHOTOMETRIC_BLACK_IS_ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
private int getOpaqueSamplesPerPixel(final int photometricInterpretation) throws IIOException {
|
||||
switch (photometricInterpretation) {
|
||||
case TIFFBaseline.PHOTOMETRIC_WHITE_IS_ZERO:
|
||||
|
@ -29,19 +29,14 @@
|
||||
*/
|
||||
package com.twelvemonkeys.imageio.plugins.tiff;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.Rational;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.TIFFEntry;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.TIFFReader;
|
||||
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import static com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
@ -50,14 +45,20 @@ import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.Rational;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.TIFFEntry;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.TIFFReader;
|
||||
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
|
||||
/**
|
||||
* TIFFImageMetadataTest.
|
||||
@ -565,6 +566,16 @@ public class TIFFImageMetadataTest {
|
||||
assertNotNull(standardTree);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGuessMissingPhotometric() throws IOException {
|
||||
IIOMetadata metadata = createMetadata("/tiff/guessPhotometric/group4.tif");
|
||||
|
||||
// Test that we don't blow up with a NPE due to missing photometric
|
||||
IIOMetadataNode standardTree = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
|
||||
assertNotNull(standardTree);
|
||||
}
|
||||
|
||||
// TODO: Test that failed set leaves metadata unchanged
|
||||
|
||||
private void assertSingleNodeWithValue(final NodeList fields, final int tag, int type, final String... expectedValue) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user