diff --git a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java index cf15f1f0..9e0be9a2 100644 --- a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java +++ b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java @@ -28,6 +28,7 @@ package com.twelvemonkeys.imageio.util; +import com.twelvemonkeys.image.ImageUtil; import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi; import org.junit.Ignore; import org.junit.Test; @@ -45,9 +46,7 @@ import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; -import java.io.File; import java.io.IOException; -import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -75,29 +74,6 @@ public abstract class ImageReaderAbstractTestCase { protected abstract List getTestData(); - /** - * Convenience method to get a list of test files from the classpath. - * Currently only works for resources on the filesystem (not in jars or - * archives). - * - * @param pResourceInFolder a resource in the correct classpath folder. - * @return a list of files - */ - protected final List getInputsFromClasspath(final String pResourceInFolder) { - URL resource = getClass().getClassLoader().getResource(pResourceInFolder); - assertNotNull(resource); - File dir; - try { - dir = new File(resource.toURI()).getParentFile(); - } - catch (URISyntaxException e) { - throw new RuntimeException(e); - } - List files = Arrays.asList(dir.listFiles()); - assertFalse(files.isEmpty()); - return files; - } - protected abstract ImageReaderSpi createProvider(); protected abstract Class getReaderClass(); @@ -476,7 +452,7 @@ public abstract class ImageReaderAbstractTestCase { } @Test - public void testReadWithSubsampleParam() { + public void testReadWithSubsampleParamDimensions() { ImageReader reader = createReader(); TestData data = getTestData().get(0); reader.setInput(data.getInputStream()); @@ -493,8 +469,61 @@ public abstract class ImageReaderAbstractTestCase { } assertNotNull("Image was null!", image); - assertEquals("Read image has wrong width: ", (double) data.getDimension(0).width / 5.0, image.getWidth(), 1.0); - assertEquals("Read image has wrong height: ", (double) data.getDimension(0).height / 5.0, image.getHeight(), 1.0); + assertEquals("Read image has wrong width: ", (data.getDimension(0).width + 4) / 5, image.getWidth()); + assertEquals("Read image has wrong height: ", (data.getDimension(0).height + 4) / 5, image.getHeight()); + } + + @Ignore + @Test + public void testReadWithSubsampleParamPixels() throws IOException { + ImageReader reader = createReader(); + TestData data = getTestData().get(0); + reader.setInput(data.getInputStream()); + + ImageReadParam param = reader.getDefaultReadParam(); + param.setSourceRegion(new Rectangle(Math.min(100, reader.getWidth(0)), Math.min(100, reader.getHeight(0)))); + + BufferedImage image = null; + BufferedImage subsampled = null; + try { + image = reader.read(0, param); + param.setSourceSubsampling(2, 2, 1, 1); // Hmm.. Seems to be the offset the fake version (ReplicateScaleFilter) uses + + subsampled = reader.read(0, param); + } + catch (IOException e) { + failBecause("Image could not be read", e); + } + + BufferedImage expected = ImageUtil.toBuffered(IIOUtil.fakeSubsampling(image, param)); + +// JPanel panel = new JPanel(); +// panel.add(new JLabel("Expected", new BufferedImageIcon(expected, 300, 300), JLabel.CENTER)); +// panel.add(new JLabel("Actual", new BufferedImageIcon(subsampled, 300, 300), JLabel.CENTER)); +// JOptionPane.showConfirmDialog(null, panel); + + assertImageDataEquals("Subsampled image data does not match expected", expected, subsampled); + } + + protected final void assertImageDataEquals(String message, BufferedImage expected, BufferedImage actual) { + assertNotNull("Expected image was null", expected); + assertNotNull("Actual image was null!", actual); + + if (expected == actual) { + return; + } + + for (int y = 0; y < expected.getHeight(); y++) { + for (int x = 0; x < expected.getWidth(); x++) { + int expectedRGB = expected.getRGB(x, y); + int actualRGB = actual.getRGB(x, y); + + assertEquals(String.format("%s alpha at (%d, %d)", message, x, y), (expectedRGB >> 24) & 0xff, (actualRGB >> 24) & 0xff, 5); + assertEquals(String.format("%s red at (%d, %d)", message, x, y), (expectedRGB >> 16) & 0xff, (actualRGB >> 16) & 0xff, 5); + assertEquals(String.format("%s green at (%d, %d)", message, x, y), (expectedRGB >> 8) & 0xff, (actualRGB >> 8) & 0xff, 5); + assertEquals(String.format("%s blue at (%d, %d)", message, x, y), expectedRGB & 0xff, actualRGB & 0xff, 5); + } + } } @Test @@ -513,6 +542,7 @@ public abstract class ImageReaderAbstractTestCase { catch (IOException e) { failBecause("Image could not be read", e); } + assertNotNull("Image was null!", image); assertEquals("Read image has wrong width: " + image.getWidth(), 10, image.getWidth()); assertEquals("Read image has wrong height: " + image.getHeight(), 10, image.getHeight()); @@ -540,6 +570,7 @@ public abstract class ImageReaderAbstractTestCase { catch (IOException e) { failBecause("Image could not be read", e); } + assertNotNull("Image was null!", image); assertEquals("Read image has wrong width: " + image.getWidth(), 10, image.getWidth()); assertEquals("Read image has wrong height: " + image.getHeight(), 10, image.getHeight()); @@ -1352,7 +1383,7 @@ public abstract class ImageReaderAbstractTestCase { boolean removed = illegalTypes.remove(valid); // TODO: 4BYTE_ABGR (6) and 4BYTE_ABGR_PRE (7) is essentially the same type... - // !#$#�%$! ImageTypeSpecifier.equals is not well-defined + // #$@*%$! ImageTypeSpecifier.equals is not well-defined if (!removed) { for (Iterator iterator = illegalTypes.iterator(); iterator.hasNext();) { ImageTypeSpecifier illegalType = iterator.next(); diff --git a/imageio/imageio-icns/src/test/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageReaderTest.java b/imageio/imageio-icns/src/test/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageReaderTest.java index 527a0ba0..bd8acd6a 100644 --- a/imageio/imageio-icns/src/test/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageReaderTest.java +++ b/imageio/imageio-icns/src/test/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageReaderTest.java @@ -29,10 +29,13 @@ package com.twelvemonkeys.imageio.plugins.icns; import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase; +import org.junit.Ignore; +import org.junit.Test; import javax.imageio.ImageReader; import javax.imageio.spi.ImageReaderSpi; import java.awt.*; +import java.io.IOException; import java.util.Arrays; import java.util.List; @@ -61,7 +64,7 @@ public class ICNSImageReaderTest extends ImageReaderAbstractTestCase { new Dimension(32, 32), // 24 bit + 8 bit mask new Dimension(48, 48), // 24 bit + 8 bit mask new Dimension(128, 128), // 24 bit + 8 bit mask - new Dimension(256, 256), // JPEG 2000 ic08 + new Dimension(256, 256), // JPEG 2000 ic08 new Dimension(512, 512) // JPEG 2000 ic09 ), new TestData( @@ -69,7 +72,7 @@ public class ICNSImageReaderTest extends ImageReaderAbstractTestCase { new Dimension(16, 16), // 24 bit + 8 bit mask new Dimension(32, 32), // 24 bit + 8 bit mask new Dimension(128, 128), // 24 bit + 8 bit mask - new Dimension(256, 256), // JPEG 2000 ic08 + new Dimension(256, 256), // JPEG 2000 ic08 new Dimension(512, 512) // JPEG 2000 ic09 ), new TestData( @@ -128,4 +131,11 @@ public class ICNSImageReaderTest extends ImageReaderAbstractTestCase { protected List getMIMETypes() { return Arrays.asList("image/x-apple-icons"); } + + @Test + @Ignore("Known issue: Subsampled reading not supported") + @Override + public void testReadWithSubsampleParamPixels() throws IOException { + super.testReadWithSubsampleParamPixels(); + } } diff --git a/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageReader.java b/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageReader.java index 53f2fc8c..227f1199 100755 --- a/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageReader.java +++ b/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageReader.java @@ -613,12 +613,12 @@ public class IFFImageReader extends ImageReaderBase { } // Skip rows outside AOI - if (srcY < aoi.y || (srcY - aoi.y) % sourceYSubsampling != 0) { - continue; - } - else if (srcY >= (aoi.y + aoi.height)) { + if (srcY >= (aoi.y + aoi.height)) { return; } + else if (srcY < aoi.y || (srcY - aoi.y) % sourceYSubsampling != 0) { + continue; + } if (formType == IFF.TYPE_ILBM) { // NOTE: Using (channels - c - 1) instead of just c, @@ -639,19 +639,21 @@ public class IFFImageReader extends ImageReaderBase { } } - int dstY = (srcY - aoi.y) / sourceYSubsampling; - // TODO: Support conversion to INT (A)RGB rasters (maybe using ColorConvertOp?) - // TODO: Avoid createChild if no region? - if (sourceXSubsampling == 1) { - destination.setRect(0, dstY, sourceRow); + if (srcY >= aoi.y && (srcY - aoi.y) % sourceYSubsampling == 0) { + int dstY = (srcY - aoi.y) / sourceYSubsampling; + // TODO: Support conversion to INT (A)RGB rasters (maybe using ColorConvertOp?) + // TODO: Avoid createChild if no region? + if (sourceXSubsampling == 1) { + destination.setRect(0, dstY, sourceRow); // dataElements = raster.getDataElements(aoi.x, 0, aoi.width, 1, dataElements); // destination.setDataElements(offset.x, offset.y + (srcY - aoi.y) / sourceYSubsampling, aoi.width, 1, dataElements); - } - else { - for (int srcX = 0; srcX < sourceRow.getWidth(); srcX += sourceXSubsampling) { - dataElements = sourceRow.getDataElements(srcX, 0, dataElements); - int dstX = srcX / sourceXSubsampling; - destination.setDataElements(dstX, dstY, dataElements); + } + else { + for (int srcX = 0; srcX < sourceRow.getWidth(); srcX += sourceXSubsampling) { + dataElements = sourceRow.getDataElements(srcX, 0, dataElements); + int dstX = srcX / sourceXSubsampling; + destination.setDataElements(dstX, dstY, dataElements); + } } }