From 79ca02c8b0661c1a050590a7af704cac0c7ce47b Mon Sep 17 00:00:00 2001 From: Harald Kuhr Date: Tue, 8 Sep 2009 12:59:12 +0200 Subject: [PATCH] Added test for PICTImageReader to makes sure JPEGs or other images with PICT magic are recognized. Better Exception handling. --- .../util/ImageReaderAbstractTestCase.java | 4 +-- .../imageio/plugins/pict/PICTImageReader.java | 26 ++++++++++++------ .../plugins/pict/PICTImageReaderTestCase.java | 12 +++++++- .../resources/jpeg/R-7439-1151526181.jpeg | Bin 0 -> 31740 bytes 4 files changed, 30 insertions(+), 12 deletions(-) mode change 100755 => 100644 twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java mode change 100755 => 100644 twelvemonkeys-imageio/pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReader.java mode change 100755 => 100644 twelvemonkeys-imageio/pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTestCase.java create mode 100644 twelvemonkeys-imageio/pict/src/test/resources/jpeg/R-7439-1151526181.jpeg diff --git a/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java b/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java old mode 100755 new mode 100644 index 7a446284..84909fe7 --- a/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java +++ b/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java @@ -204,7 +204,7 @@ public abstract class ImageReaderAbstractTestCase extends reader.setInput(null); } - public void testRead() throws IOException { + public void testRead() { ImageReader reader = createReader(); for (TestData data : getTestData()) { // TODO: Is it required to call reset before setInput? @@ -1283,7 +1283,7 @@ public abstract class ImageReaderAbstractTestCase extends return getClass().getResource(pName); } - static final protected class TestData { + static final protected class TestData { private final Object mInput; private final List mSizes; private final List mImages; diff --git a/twelvemonkeys-imageio/pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReader.java b/twelvemonkeys-imageio/pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReader.java old mode 100755 new mode 100644 index a05c775d..b146d450 --- a/twelvemonkeys-imageio/pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReader.java +++ b/twelvemonkeys-imageio/pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReader.java @@ -191,7 +191,7 @@ public class PICTImageReader extends ImageReaderBase { // Get frame at 72 dpi // NOTE: These are not pixel sizes! - // Need sto be multiplied with hRes/screenResolution and vRes/screenResolution + // Need to be multiplied with hRes/screenResolution and vRes/screenResolution int y = pStream.readUnsignedShort(); int x = pStream.readUnsignedShort(); int h = pStream.readUnsignedShort(); @@ -1664,10 +1664,18 @@ public class PICTImageReader extends ImageReaderBase { throw e; } catch (EOFException e) { - throw new IIOException("Error in PICT format: Unexpected end of File", e); + String pos; + try { + pos = String.format("position %d", mImageInput.getStreamPosition()); + } + catch (IOException ignore) { + pos = "unknown position"; + } + + throw new IIOException(String.format("Error in PICT format: Unexpected end of File at %s", pos), e); } catch (IOException e) { - throw new IIOException("Error in PICT format: " + e.getMessage(), e); + throw new IIOException(String.format("Error in PICT format: %s", e.getMessage()), e); } } @@ -2528,7 +2536,7 @@ public class PICTImageReader extends ImageReaderBase { /* * Read a long comment from the stream. */ - private void readLongComment(DataInput pStream) throws IOException { + private void readLongComment(final DataInput pStream) throws IOException { // Comment kind and data byte count pStream.readShort(); @@ -2604,12 +2612,12 @@ public class PICTImageReader extends ImageReaderBase { // TODO: Might need to clear background g.setTransform(AffineTransform.getScaleInstance(mScreenImageXRatio, mScreenImageYRatio)); - try { +// try { drawOnto(g); - } - catch (IOException e) { - e.printStackTrace(); - } +// } +// catch (IOException e) { +// e.printStackTrace(); +// } } finally { g.dispose(); diff --git a/twelvemonkeys-imageio/pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTestCase.java b/twelvemonkeys-imageio/pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTestCase.java old mode 100755 new mode 100644 index ec2ad5f7..8a02dea1 --- a/twelvemonkeys-imageio/pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTestCase.java +++ b/twelvemonkeys-imageio/pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTestCase.java @@ -4,6 +4,7 @@ import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase; import javax.imageio.spi.ImageReaderSpi; import java.awt.*; +import java.io.IOException; import java.util.Arrays; import java.util.List; @@ -18,7 +19,7 @@ public class PICTImageReaderTestCase extends ImageReaderAbstractTestCase getTestData() { return Arrays.asList( new TestData(getClassLoaderResource("/pict/test.pct"), new Dimension(300, 200)), @@ -57,4 +58,13 @@ public class PICTImageReaderTestCase extends ImageReaderAbstractTestCase getMIMETypes() { return Arrays.asList("image/pict", "image/x-pict"); } + + public void testProviderNotMatchJPEG() throws IOException { + // This JPEG contains PICT magic bytes at locations a PICT would normally have them. + // We should not claim to be able read it. + assertFalse(sProvider.canDecodeInput(new TestData( + getClassLoaderResource("/jpeg/R-7439-1151526181.jpeg"), + new Dimension(386, 396) + ))); + } } \ No newline at end of file diff --git a/twelvemonkeys-imageio/pict/src/test/resources/jpeg/R-7439-1151526181.jpeg b/twelvemonkeys-imageio/pict/src/test/resources/jpeg/R-7439-1151526181.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..a20a5899f999f130b1de12541efdc80358942b7b GIT binary patch literal 31740 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