diff --git a/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderSpi.java b/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderSpi.java index 216e0a15..4945e3eb 100755 --- a/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderSpi.java +++ b/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderSpi.java @@ -60,6 +60,13 @@ public final class PICTImageReaderSpi extends ImageReaderSpiBase { } ImageInputStream stream = (ImageInputStream) pSource; + + // As PICT format don't have good magic and our method often gives false positives, + // so we'll need to check for other known formats (BMP, GIF, JPEG, PNG, PSD, TIFF) first + if (isOtherFormat(stream)) { + return false; + } + stream.mark(); try { @@ -68,13 +75,12 @@ public final class PICTImageReaderSpi extends ImageReaderSpiBase { return true; } else { - // Skip header 512 bytes for file-based streams - stream.reset(); - - // We need to set mark again, to make sure the reset call in + // We need to reset AND set mark again, to make sure the reset call in // the finally block will not consume existing marks + stream.reset(); stream.mark(); + // Skip header 512 bytes for file-based streams skipNullHeader(stream); } @@ -88,6 +94,60 @@ public final class PICTImageReaderSpi extends ImageReaderSpiBase { } } + // TODO: Candidate util method. + // Might need to be able to exclude some formats + // Might need to return the format matched... + static boolean isOtherFormat(final ImageInputStream stream) throws IOException { + stream.mark(); + + try { + byte[] signature = new byte[8]; + stream.readFully(signature); + + // BMP: off: 0, len: 2, magic: 'B', 'M' + // GIF: off: 0, len: 6, magic: 'G', 'I', 'F', '8', ('7' | '9'), 'a' (use only "GIF8"?) + // JPEG: off 0, len: 2, magic: 0xffd8 (SOI marker) + // PNG: off: 0, len: 8, magic: 0x89, 'P', 'N', 'G', 0x0d0a1a0a + // PSD: off: 0, len: 4, magic: '8', 'B', 'P', 'S' + // TIFF: off: 0, len: 4, magic: ('I', 'I', 0x00, (0x42 | 0x43)) | ('M', 'M', (0x42 | 0x43), 0x00) (43 is bigTiff) + if (signature[0] == 'B' && signature[1] == 'M') { + // BMP + return true; + } + if (signature[0] == 'G' && signature[1] == 'I' && signature[2] == 'F' && signature[3] == '8' + && (signature[4] == '7' || signature[4] == '9') && signature[5] == 'a') { + // GIF + return true; + } + if (signature[0] == (byte) 0xFF && signature[1] == (byte) 0xD8 && signature[2] == (byte) 0xFF) { + // JPEG + return true; + } + if (signature[0] == (byte) 0x89 && signature[1] == 'P' && signature[2] == 'N' && signature[3] == 'G' + && signature[4] == 0x0D && signature[5] == 0x0A && signature[6] == 0x1A && signature[7] == 0x0A) { + // PNG + return true; + } + if (signature[0] == '8' && signature[1] == 'B' && signature[2] == 'P' && signature[3] == 'S') { + // PSD + return true; + } + if ((signature[0] == 'I' && signature[1] == 'I' && (signature[2] == 42 || signature[2] == 43) && signature[3] == 0x00) + || signature[0] == 'M' && signature[1] == 'M' && signature[2] == 0x00 && (signature[3] == 42 || signature[3] == 43)) { + // TIFF/BigTIFF + return true; + } + } + catch (EOFException ignore) { + // Can't be any of the formats + } + finally { + stream.reset(); + } + + return false; + } + static void skipNullHeader(final ImageInputStream pStream) throws IOException { // NOTE: Only skip if FILE FORMAT, not needed for Mac OS DnD // Spec says "platform dependent", may not be all nulls.. @@ -102,10 +162,6 @@ public final class PICTImageReaderSpi extends ImageReaderSpiBase { // Sanity check bounding box int y1 = pStream.readUnsignedShort(); int x1 = pStream.readUnsignedShort(); - // TODO: Figure out if frame can ever start at negative bounds... - // if (x1 != 0 || y1 != 0) { - // return false; - // } int y2 = pStream.readUnsignedShort(); int x2 = pStream.readUnsignedShort(); diff --git a/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTest.java b/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTest.java index 4350db13..d9c65271 100644 --- a/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTest.java +++ b/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTest.java @@ -46,8 +46,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import static com.twelvemonkeys.imageio.plugins.pict.PICTImageReaderSpi.isOtherFormat; +import static org.junit.Assert.*; /** * ICOImageReaderTestCase @@ -116,6 +116,38 @@ public class PICTImageReaderTest extends ImageReaderAbstractTest