diff --git a/bom/pom.xml b/bom/pom.xml
index a684765c..42a7ed3c 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -5,7 +5,7 @@
com.twelvemonkeys
twelvemonkeys
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
com.twelvemonkeys.bom
diff --git a/common/common-image/pom.xml b/common/common-image/pom.xml
index 55cfc26c..cdef6ab4 100644
--- a/common/common-image/pom.xml
+++ b/common/common-image/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.common
common
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
common-image
jar
diff --git a/common/common-io/pom.xml b/common/common-io/pom.xml
index b4d3207c..19f61ccc 100644
--- a/common/common-io/pom.xml
+++ b/common/common-io/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.common
common
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
common-io
jar
diff --git a/common/common-lang/pom.xml b/common/common-lang/pom.xml
index f3436902..79316441 100644
--- a/common/common-lang/pom.xml
+++ b/common/common-lang/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.common
common
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
common-lang
jar
diff --git a/common/pom.xml b/common/pom.xml
index b6b9f6f7..eb530041 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys
twelvemonkeys
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
com.twelvemonkeys.common
common
diff --git a/contrib/pom.xml b/contrib/pom.xml
index 9a73d3c6..f50aac23 100644
--- a/contrib/pom.xml
+++ b/contrib/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys
twelvemonkeys
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
com.twelvemonkeys.contrib
contrib
diff --git a/imageio/imageio-batik/pom.xml b/imageio/imageio-batik/pom.xml
index 1f31c074..39ca0cdb 100644
--- a/imageio/imageio-batik/pom.xml
+++ b/imageio/imageio-batik/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-batik
TwelveMonkeys :: ImageIO :: Batik Plugin
diff --git a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java
index 9f0e8b52..59a06967 100755
--- a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java
+++ b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java
@@ -120,6 +120,13 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest
super.testReadWithSourceRegionParamEqualImage();
}
+ @Test
+ @Ignore("Known issue: Subsampled reading not supported")
+ @Override
+ public void testReadWithSubsampleParamPixels() throws IOException {
+ super.testReadWithSubsampleParamPixels();
+ }
+
@Test
public void testRepeatedRead() throws IOException {
Dimension dim = new Dimension(100, 100);
diff --git a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/wmf/WMFImageReaderTest.java b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/wmf/WMFImageReaderTest.java
index 9220d115..b634b138 100755
--- a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/wmf/WMFImageReaderTest.java
+++ b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/wmf/WMFImageReaderTest.java
@@ -86,4 +86,11 @@ public class WMFImageReaderTest extends ImageReaderAbstractTest
public void testReadWithSourceRegionParamEqualImage() throws IOException {
super.testReadWithSourceRegionParamEqualImage();
}
+
+ @Test
+ @Ignore("Known issue: Subsampled reading not supported")
+ @Override
+ public void testReadWithSubsampleParamPixels() throws IOException {
+ super.testReadWithSubsampleParamPixels();
+ }
}
\ No newline at end of file
diff --git a/imageio/imageio-bmp/pom.xml b/imageio/imageio-bmp/pom.xml
index 8b6aa174..e4a24e22 100644
--- a/imageio/imageio-bmp/pom.xml
+++ b/imageio/imageio-bmp/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-bmp
TwelveMonkeys :: ImageIO :: BMP plugin
diff --git a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReader.java b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReader.java
index 6ff96a19..9151dce6 100755
--- a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReader.java
+++ b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReader.java
@@ -692,12 +692,14 @@ public final class BMPImageReader extends ImageReaderBase {
if (imageMetadata != null) {
new XMLSerializer(System.out, System.getProperty("file.encoding")).serialize(imageMetadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName), false);
}
- } catch (Throwable t) {
+ }
+ catch (Throwable t) {
if (args.length > 1) {
System.err.println("---");
System.err.println("---> " + t.getClass().getSimpleName() + ": " + t.getMessage() + " for " + arg);
System.err.println("---");
- } else {
+ }
+ else {
throwAs(RuntimeException.class, t);
}
}
diff --git a/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReaderTest.java b/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReaderTest.java
index 76a495b3..12646e9a 100755
--- a/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReaderTest.java
+++ b/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReaderTest.java
@@ -1,20 +1,19 @@
package com.twelvemonkeys.imageio.plugins.bmp;
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
+import org.junit.Ignore;
import org.junit.Test;
import org.mockito.InOrder;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import javax.imageio.IIOException;
-import javax.imageio.ImageIO;
-import javax.imageio.ImageReader;
-import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.*;
import javax.imageio.event.IIOReadProgressListener;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.spi.ImageReaderSpi;
import java.awt.*;
+import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.URISyntaxException;
@@ -174,6 +173,58 @@ public class BMPImageReaderTest extends ImageReaderAbstractTest
}
}
+ @Ignore("Known issue: Subsampled reading is currently broken")
+ @Test
+ public void testReadWithSubsampleParamPixelsIndexed8() throws IOException {
+ ImageReader reader = createReader();
+ TestData data = getTestData().get(0);
+ reader.setInput(data.getInputStream());
+
+ ImageReadParam param = reader.getDefaultReadParam();
+
+ BufferedImage image = null;
+ BufferedImage subsampled = null;
+ try {
+ image = reader.read(0, param);
+
+ param.setSourceSubsampling(2, 2, 0, 0);
+ subsampled = reader.read(0, param);
+ }
+ catch (IOException e) {
+ failBecause("Image could not be read", e);
+ }
+
+ assertSubsampledImageDataEquals("Subsampled image data does not match expected", image, subsampled, param);
+ }
+
+ // TODO: 1. Subsampling is currently broken, should fix it.
+ // 2. BMPs are (normally) stored bottom/up, meaning y subsampling offsets will differ from normal
+ // subsampling of the same data with an offset... Should we deal with this in the reader? Yes?
+ @Ignore("Known issue: Subsampled reading is currently broken")
+ @Test
+ @Override
+ public void testReadWithSubsampleParamPixels() throws IOException {
+ ImageReader reader = createReader();
+ TestData data = getTestData().get(19); // RGB 24
+ reader.setInput(data.getInputStream());
+
+ ImageReadParam param = reader.getDefaultReadParam();
+
+ BufferedImage image = null;
+ BufferedImage subsampled = null;
+ try {
+ image = reader.read(0, param);
+
+ param.setSourceSubsampling(2, 2, 0, 0);
+ subsampled = reader.read(0, param);
+ }
+ catch (IOException e) {
+ failBecause("Image could not be read", e);
+ }
+
+ assertSubsampledImageDataEquals("Subsampled image data does not match expected", image, subsampled, param);
+ }
+
@Test(expected = IIOException.class)
public void testReadCorruptCausesIIOException() throws IOException {
// See https://bugs.openjdk.java.net/browse/JDK-8066904
diff --git a/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/CURImageReaderTest.java b/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/CURImageReaderTest.java
index fe885d86..a40ba06d 100755
--- a/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/CURImageReaderTest.java
+++ b/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/CURImageReaderTest.java
@@ -119,4 +119,11 @@ public class CURImageReaderTest extends ImageReaderAbstractTest
public void testNotBadCaching() throws IOException {
super.testNotBadCaching();
}
+
+ @Test
+ @Ignore("Known issue: Subsampled reading currently not supported")
+ @Override
+ public void testReadWithSubsampleParamPixels() throws IOException {
+ super.testReadWithSubsampleParamPixels();
+ }
}
\ No newline at end of file
diff --git a/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/ICOImageReaderTest.java b/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/ICOImageReaderTest.java
index ed5a2adc..9c121287 100755
--- a/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/ICOImageReaderTest.java
+++ b/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/ICOImageReaderTest.java
@@ -76,4 +76,11 @@ public class ICOImageReaderTest extends ImageReaderAbstractTest
public void testNotBadCaching() throws IOException {
super.testNotBadCaching();
}
+
+ @Test
+ @Ignore("Known issue: Subsampled reading currently not supported")
+ @Override
+ public void testReadWithSubsampleParamPixels() throws IOException {
+ super.testReadWithSubsampleParamPixels();
+ }
}
\ No newline at end of file
diff --git a/imageio/imageio-clippath/pom.xml b/imageio/imageio-clippath/pom.xml
index 85d4852a..45ba89f4 100755
--- a/imageio/imageio-clippath/pom.xml
+++ b/imageio/imageio-clippath/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-clippath
TwelveMonkeys :: ImageIO :: Photoshop Path Support
diff --git a/imageio/imageio-core/pom.xml b/imageio/imageio-core/pom.xml
index 3c295d76..34e815db 100644
--- a/imageio/imageio-core/pom.xml
+++ b/imageio/imageio-core/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-core
TwelveMonkeys :: ImageIO :: Core
diff --git a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTest.java b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTest.java
index 2864f844..f002a0fb 100644
--- a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTest.java
+++ b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTest.java
@@ -28,7 +28,6 @@
package com.twelvemonkeys.imageio.util;
-import com.twelvemonkeys.image.ImageUtil;
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
import org.junit.Ignore;
import org.junit.Test;
@@ -46,6 +45,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.URL;
import java.util.ArrayList;
@@ -98,7 +98,7 @@ public abstract class ImageReaderAbstractTest {
return false;
}
- private static void failBecause(String message, Throwable exception) {
+ protected static void failBecause(String message, Throwable exception) {
AssertionError error = new AssertionError(message);
error.initCause(exception);
throw error;
@@ -471,7 +471,6 @@ public abstract class ImageReaderAbstractTest {
assertEquals("Read image has wrong height: ", (data.getDimension(0).height + 4) / 5, image.getHeight());
}
- @Ignore
@Test
public void testReadWithSubsampleParamPixels() throws IOException {
ImageReader reader = createReader();
@@ -479,28 +478,66 @@ public abstract class ImageReaderAbstractTest {
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
+ param.setSourceSubsampling(2, 2, 0, 0);
subsampled = reader.read(0, param);
}
catch (IOException e) {
failBecause("Image could not be read", e);
}
- BufferedImage expected = ImageUtil.toBuffered(IIOUtil.fakeSubsampling(image, param));
+ assertSubsampledImageDataEquals("Subsampled image data does not match expected", image, subsampled, 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);
+ // TODO: Subsample all test data
+ // TODO: Subsample with varying ratios and offsets
- assertImageDataEquals("Subsampled image data does not match expected", expected, subsampled);
+ protected final void assertSubsampledImageDataEquals(String message, BufferedImage expected, BufferedImage actual, ImageReadParam param) throws IOException {
+ assertNotNull("Expected image was null", expected);
+ assertNotNull("Actual image was null!", actual);
+
+ if (expected == actual) {
+ return;
+ }
+
+ int xOff = param.getSubsamplingXOffset();
+ int yOff = param.getSubsamplingYOffset();
+ int xSub = param.getSourceXSubsampling();
+ int ySub = param.getSourceYSubsampling();
+
+ assertEquals("Subsampled image has wrong width: ", (expected.getWidth() - xOff + xSub - 1) / xSub, actual.getWidth());
+ assertEquals("Subsampled image has wrong height: ", (expected.getHeight() - yOff + ySub - 1) / ySub, actual.getHeight());
+ assertEquals("Subsampled has different type", expected.getType(), actual.getType());
+
+ for (int y = 0; y < actual.getHeight(); y++) {
+ for (int x = 0; x < actual.getWidth(); x++) {
+ int expectedRGB = expected.getRGB(xOff + x * xSub, yOff + y * ySub);
+ int actualRGB = actual.getRGB(x, y);
+
+ try {
+ 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);
+ }
+ catch (AssertionError e) {
+ File tempExpected = File.createTempFile("junit-expected-", ".png");
+ System.err.println("tempExpected.getAbsolutePath(): " + tempExpected.getAbsolutePath());
+ ImageIO.write(expected, "PNG", tempExpected);
+ File tempActual = File.createTempFile("junit-actual-", ".png");
+ System.err.println("tempActual.getAbsolutePath(): " + tempActual.getAbsolutePath());
+ ImageIO.write(actual, "PNG", tempActual);
+
+
+ assertEquals(String.format("%s ARGB at (%d, %d)", message, x, y), String.format("#%08x", expectedRGB), String.format("#%08x", actualRGB));
+ }
+ }
+ }
}
protected final void assertImageDataEquals(String message, BufferedImage expected, BufferedImage actual) {
diff --git a/imageio/imageio-hdr/pom.xml b/imageio/imageio-hdr/pom.xml
index 20efae92..985c48f7 100644
--- a/imageio/imageio-hdr/pom.xml
+++ b/imageio/imageio-hdr/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-hdr
TwelveMonkeys :: ImageIO :: HDR plugin
diff --git a/imageio/imageio-icns/pom.xml b/imageio/imageio-icns/pom.xml
index 37937b29..9a76609e 100644
--- a/imageio/imageio-icns/pom.xml
+++ b/imageio/imageio-icns/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-icns
TwelveMonkeys :: ImageIO :: ICNS plugin
diff --git a/imageio/imageio-iff/pom.xml b/imageio/imageio-iff/pom.xml
index 1bac81f2..0c5176f1 100644
--- a/imageio/imageio-iff/pom.xml
+++ b/imageio/imageio-iff/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-iff
TwelveMonkeys :: ImageIO :: IFF plugin
diff --git a/imageio/imageio-jpeg/pom.xml b/imageio/imageio-jpeg/pom.xml
index 1a2c62e0..913c4426 100644
--- a/imageio/imageio-jpeg/pom.xml
+++ b/imageio/imageio-jpeg/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-jpeg
TwelveMonkeys :: ImageIO :: JPEG plugin
diff --git a/imageio/imageio-metadata/pom.xml b/imageio/imageio-metadata/pom.xml
index 40993b3f..659f5428 100644
--- a/imageio/imageio-metadata/pom.xml
+++ b/imageio/imageio-metadata/pom.xml
@@ -3,7 +3,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
4.0.0
imageio-metadata
diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFEntry.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFEntry.java
index 0c6f5403..9d88ef24 100644
--- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFEntry.java
+++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFEntry.java
@@ -102,7 +102,7 @@ final class EXIFEntry extends AbstractEntry {
case TIFF.TAG_ORIENTATION:
return "Orientation";
case TIFF.TAG_SAMPLES_PER_PIXEL:
- return "SamplesPerPixels";
+ return "SamplesPerPixel";
case TIFF.TAG_ROWS_PER_STRIP:
return "RowsPerStrip";
case TIFF.TAG_STRIP_BYTE_COUNTS:
diff --git a/imageio/imageio-pcx/pom.xml b/imageio/imageio-pcx/pom.xml
index 0f49aa20..f775b43d 100755
--- a/imageio/imageio-pcx/pom.xml
+++ b/imageio/imageio-pcx/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-pcx
TwelveMonkeys :: ImageIO :: PCX plugin
diff --git a/imageio/imageio-pdf/pom.xml b/imageio/imageio-pdf/pom.xml
index 9f19c32e..1ccf8f17 100644
--- a/imageio/imageio-pdf/pom.xml
+++ b/imageio/imageio-pdf/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-pdf
TwelveMonkeys :: ImageIO :: PDF plugin
diff --git a/imageio/imageio-pict/pom.xml b/imageio/imageio-pict/pom.xml
index 1b9afc34..758bff49 100644
--- a/imageio/imageio-pict/pom.xml
+++ b/imageio/imageio-pict/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-pict
TwelveMonkeys :: ImageIO :: PICT plugin
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 9c46904c..15078df2 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
@@ -3,6 +3,7 @@ package com.twelvemonkeys.imageio.plugins.pict;
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStreamSpi;
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
+import org.junit.Ignore;
import org.junit.Test;
import javax.imageio.spi.IIORegistry;
@@ -83,6 +84,13 @@ public class PICTImageReaderTest extends ImageReaderAbstractTest
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-pnm
TwelveMonkeys :: ImageIO :: PNM plugin
diff --git a/imageio/imageio-psd/pom.xml b/imageio/imageio-psd/pom.xml
index c58d19b4..9eb4a91d 100644
--- a/imageio/imageio-psd/pom.xml
+++ b/imageio/imageio-psd/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-psd
TwelveMonkeys :: ImageIO :: PSD plugin
diff --git a/imageio/imageio-reference/pom.xml b/imageio/imageio-reference/pom.xml
index 00899b72..94ad0bf7 100644
--- a/imageio/imageio-reference/pom.xml
+++ b/imageio/imageio-reference/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-reference
TwelveMonkeys :: ImageIO :: reference test cases
diff --git a/imageio/imageio-sgi/pom.xml b/imageio/imageio-sgi/pom.xml
index 0296d502..4fe7bb94 100755
--- a/imageio/imageio-sgi/pom.xml
+++ b/imageio/imageio-sgi/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-sgi
TwelveMonkeys :: ImageIO :: SGI plugin
diff --git a/imageio/imageio-tga/pom.xml b/imageio/imageio-tga/pom.xml
index 2683485a..9e1ead30 100755
--- a/imageio/imageio-tga/pom.xml
+++ b/imageio/imageio-tga/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-tga
TwelveMonkeys :: ImageIO :: TGA plugin
diff --git a/imageio/imageio-tga/src/main/java/com/twelvemonkeys/imageio/plugins/tga/TGAImageReader.java b/imageio/imageio-tga/src/main/java/com/twelvemonkeys/imageio/plugins/tga/TGAImageReader.java
index bceccb8b..b6340926 100755
--- a/imageio/imageio-tga/src/main/java/com/twelvemonkeys/imageio/plugins/tga/TGAImageReader.java
+++ b/imageio/imageio-tga/src/main/java/com/twelvemonkeys/imageio/plugins/tga/TGAImageReader.java
@@ -229,15 +229,16 @@ public final class TGAImageReader extends ImageReaderBase {
input.readFully(rowDataByte, 0, rowDataByte.length);
- if (srcChannel.getNumBands() == 4 && (header.getAttributeBits() == 0 || extensions != null && !extensions.hasAlpha())) {
+ int numBands = srcChannel.getNumBands();
+ if (numBands == 4 && (header.getAttributeBits() == 0 || extensions != null && !extensions.hasAlpha())) {
// Remove the alpha channel (make pixels opaque) if there are no "attribute bits" (alpha bits)
removeAlpha32(rowDataByte);
}
// Subsample horizontal
if (xSub != 1) {
- for (int x = 0; x < srcRegion.width / xSub; x++) {
- rowDataByte[srcRegion.x + x] = rowDataByte[srcRegion.x + x * xSub];
+ for (int x = srcRegion.x / xSub * numBands; x < ((srcRegion.x + srcRegion.width) / xSub) * numBands; x += numBands) {
+ System.arraycopy(rowDataByte, x * xSub, rowDataByte, x, numBands);
}
}
diff --git a/imageio/imageio-thumbsdb/pom.xml b/imageio/imageio-thumbsdb/pom.xml
index 7ade94f8..1a60813d 100644
--- a/imageio/imageio-thumbsdb/pom.xml
+++ b/imageio/imageio-thumbsdb/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-thumbsdb
TwelveMonkeys :: ImageIO :: Thumbs.db plugin
diff --git a/imageio/imageio-tiff/pom.xml b/imageio/imageio-tiff/pom.xml
index 11f66f34..7fc02cce 100644
--- a/imageio/imageio-tiff/pom.xml
+++ b/imageio/imageio-tiff/pom.xml
@@ -4,7 +4,7 @@
com.twelvemonkeys.imageio
imageio
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
imageio-tiff
TwelveMonkeys :: ImageIO :: TIFF plugin
diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java
index 8c80285e..5961f6e5 100755
--- a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java
+++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java
@@ -52,6 +52,7 @@ import com.twelvemonkeys.io.FastByteArrayOutputStream;
import com.twelvemonkeys.io.LittleEndianDataInputStream;
import com.twelvemonkeys.io.enc.DecoderStream;
import com.twelvemonkeys.io.enc.PackBitsDecoder;
+import com.twelvemonkeys.xml.XMLSerializer;
import org.w3c.dom.NodeList;
import javax.imageio.*;
@@ -454,7 +455,7 @@ public class TIFFImageReader extends ImageReaderBase {
return ImageTypeSpecifiers.createPacked(cs, 0xF000, 0xF00, 0xF0, 0xF, DataBuffer.TYPE_USHORT, isAlphaPremultiplied);
}
default:
- throw new IIOException(String.format("Unsupported SamplesPerPixels/BitsPerSample combination for RGB TIFF (expected 3/8, 4/8, 3/16 or 4/16): %d/%d", samplesPerPixel, bitsPerSample));
+ throw new IIOException(String.format("Unsupported SamplesPerPixel/BitsPerSample combination for RGB TIFF (expected 3/8, 4/8, 3/16 or 4/16): %d/%d", samplesPerPixel, bitsPerSample));
}
case TIFFBaseline.PHOTOMETRIC_PALETTE:
// Palette
@@ -517,7 +518,7 @@ public class TIFFImageReader extends ImageReaderBase {
default:
throw new IIOException(
- String.format("Unsupported SamplesPerPixels/BitsPerSample combination for Separated TIFF (expected 4/8, 4/16, 5/8 or 5/16): %d/%s", samplesPerPixel, bitsPerSample)
+ String.format("Unsupported SamplesPerPixel/BitsPerSample combination for Separated TIFF (expected 4/8, 4/16, 5/8 or 5/16): %d/%s", samplesPerPixel, bitsPerSample)
);
}
case TIFFExtension.PHOTOMETRIC_CIELAB:
@@ -777,7 +778,7 @@ public class TIFFImageReader extends ImageReaderBase {
// NOTE: We handle strips as tiles of tileWidth == width by tileHeight == rowsPerStrip
// Strips are top/down, tiles are left/right, top/down
int stripTileWidth = width;
- long rowsPerStrip = getValueAsLongWithDefault(TIFF.TAG_ROWS_PER_STRIP, (1L << 32) - 1);
+ long rowsPerStrip = getValueAsLongWithDefault(TIFF.TAG_ROWS_PER_STRIP, (long) Integer.MAX_VALUE);
int stripTileHeight = rowsPerStrip < height ? (int) rowsPerStrip : height;
long[] stripTileOffsets = getValueAsLongArray(TIFF.TAG_TILE_OFFSETS, "TileOffsets", false);
@@ -924,7 +925,7 @@ public class TIFFImageReader extends ImageReaderBase {
}
// Clip the stripTile rowRaster to not exceed the srcRegion
- clip.width = Math.min((colsInTile + xSub - 1) / xSub, srcRegion.width);
+ clip.width = Math.min(colsInTile, srcRegion.width);
Raster clippedRow = clipRowToRect(rowRaster, clip,
param != null ? param.getSourceBands() : null,
param != null ? param.getSourceXSubsampling() : 1);
@@ -992,7 +993,7 @@ public class TIFFImageReader extends ImageReaderBase {
// Read only tiles that lies within region
Rectangle tileRect = new Rectangle(col, row, colsInTile, rowsInTile);
- Rectangle intersection = tileRect.intersection( srcRegion );
+ Rectangle intersection = tileRect.intersection(srcRegion);
if (!intersection.isEmpty()) {
imageInput.seek(stripTileOffsets[i]);
@@ -1000,7 +1001,9 @@ public class TIFFImageReader extends ImageReaderBase {
try (ImageInputStream subStream = new SubImageInputStream(imageInput, length)) {
jpegReader.setInput(subStream);
- jpegParam.setSourceRegion(new Rectangle( intersection.x - col, intersection.y - row, intersection.width, intersection.height));
+ jpegParam.setSourceRegion(new Rectangle(intersection.x - col, intersection.y - row, intersection.width, intersection.height));
+ jpegParam.setSourceSubsampling(xSub, ySub, 0, 0);
+ Point offset = new Point((intersection.x - srcRegion.x) / xSub, (intersection.y - srcRegion.y) / ySub);
// TODO: If we have non-standard reference B/W or yCbCr coefficients,
// we might still have to do extra color space conversion...
@@ -1009,7 +1012,7 @@ public class TIFFImageReader extends ImageReaderBase {
}
if (!needsCSConversion) {
- jpegParam.setDestinationOffset(new Point(intersection.x - srcRegion.x, intersection.y - srcRegion.y));
+ jpegParam.setDestinationOffset(offset);
jpegParam.setDestination(destination);
jpegReader.read(0, jpegParam);
}
@@ -1018,7 +1021,7 @@ public class TIFFImageReader extends ImageReaderBase {
// We'll have to use readAsRaster and later apply color space conversion ourselves
Raster raster = jpegReader.readRaster(0, jpegParam);
normalizeColor(interpretation, ((DataBufferByte) raster.getDataBuffer()).getData());
- destination.getRaster().setDataElements(intersection.x - srcRegion.x, intersection.y - srcRegion.y, raster);
+ destination.getRaster().setDataElements(offset.x, offset.y, raster);
}
}
}
@@ -1140,12 +1143,14 @@ public class TIFFImageReader extends ImageReaderBase {
try (ImageInputStream stream = new SubImageInputStream(imageInput, length)) {
jpegReader.setInput(stream);
jpegParam.setSourceRegion(srcRegion);
+ jpegParam.setSourceSubsampling(xSub, ySub, 0, 0);
if (needsCSConversion == null) {
needsCSConversion = needsCSConversion(interpretation, jpegReader.getImageMetadata(0));
}
if (!needsCSConversion) {
+ // Single tile, no dest offset needed
jpegParam.setDestination(destination);
jpegReader.read(0, jpegParam);
}
@@ -1242,14 +1247,15 @@ public class TIFFImageReader extends ImageReaderBase {
)))) {
jpegReader.setInput(stream);
jpegParam.setSourceRegion(new Rectangle(0, 0, colsInTile, rowsInTile));
- jpegParam.setDestinationOffset(new Point(col - srcRegion.x, row - srcRegion.y));
- jpegParam.setDestination(destination);
+ jpegParam.setSourceSubsampling(xSub, ySub, 0, 0);
+ Point offset = new Point(col - srcRegion.x, row - srcRegion.y);
if (needsCSConversion == null) {
needsCSConversion = needsCSConversion(interpretation, jpegReader.getImageMetadata(0));
}
if (!needsCSConversion) {
+ jpegParam.setDestinationOffset(offset);
jpegParam.setDestination(destination);
jpegReader.read(0, jpegParam);
}
@@ -1258,7 +1264,7 @@ public class TIFFImageReader extends ImageReaderBase {
// We'll have to use readAsRaster and later apply color space conversion ourselves
Raster raster = jpegReader.readRaster(0, jpegParam);
normalizeColor(interpretation, ((DataBufferByte) raster.getDataBuffer()).getData());
- destination.getRaster().setDataElements(0, 0, raster);
+ destination.getRaster().setDataElements(offset.x, offset.y, raster);
}
}
}
@@ -1385,7 +1391,7 @@ public class TIFFImageReader extends ImageReaderBase {
out.writeShort(JPEG.SOI);
out.writeShort(JPEG.SOF0);
out.writeShort(2 + 6 + 3 * bands); // SOF0 len
- out.writeByte(8); // bits TODO: Consult bands/transfer type or BitsPerSample for 12/16 bits support
+ out.writeByte(8); // bits TODO: Consult raster/transfer type or BitsPerSample for 12/16 bits support
out.writeShort(stripTileHeight); // height
out.writeShort(stripTileWidth); // width
out.writeByte(bands); // Number of components
@@ -1447,7 +1453,7 @@ public class TIFFImageReader extends ImageReaderBase {
return raster;
}
- return raster.createChild(rect.x / xSub, 0, rect.width / xSub, 1, 0, 0, bands);
+ return raster.createChild((rect.x + xSub - 1) / xSub, 0, (rect.width + xSub - 1) / xSub, 1, 0, 0, bands);
}
private WritableRaster clipToRect(final WritableRaster raster, final Rectangle rect, final int[] bands) {
@@ -1497,12 +1503,12 @@ public class TIFFImageReader extends ImageReaderBase {
// Subsample horizontal
if (xSub != 1) {
- for (int x = srcRegion.x / xSub * numBands; x < ((srcRegion.x + srcRegion.width) / xSub) * numBands; x += numBands) {
+ for (int x = srcRegion.x / xSub * numBands; x < ((srcRegion.x + colsInTile) / xSub) * numBands; x += numBands) {
System.arraycopy(rowDataByte, x * xSub, rowDataByte, x, numBands);
}
}
- destChannel.setDataElements(startCol, (row - srcRegion.y) / ySub, srcChannel);
+ destChannel.setDataElements(startCol / xSub, (row - srcRegion.y) / ySub, srcChannel);
}
// Else skip data
}
@@ -1540,12 +1546,12 @@ public class TIFFImageReader extends ImageReaderBase {
// Subsample horizontal
if (xSub != 1) {
- for (int x = srcRegion.x / xSub * numBands; x < ((srcRegion.x + srcRegion.width) / xSub) * numBands; x += numBands) {
+ for (int x = srcRegion.x / xSub * numBands; x < ((srcRegion.x + colsInTile) / xSub) * numBands; x += numBands) {
System.arraycopy(rowDataShort, x * xSub, rowDataShort, x, numBands);
}
}
- destChannel.setDataElements(startCol, row - srcRegion.y, srcChannel);
+ destChannel.setDataElements(startCol / xSub, (row - srcRegion.y) / ySub, srcChannel);
// TODO: Possible speedup ~30%!:
// raster.setDataElements(startCol, row - srcRegion.y, colsInTile, 1, rowDataShort);
}
@@ -1577,12 +1583,12 @@ public class TIFFImageReader extends ImageReaderBase {
// Subsample horizontal
if (xSub != 1) {
- for (int x = srcRegion.x / xSub * numBands; x < ((srcRegion.x + srcRegion.width) / xSub) * numBands; x += numBands) {
+ for (int x = srcRegion.x / xSub * numBands; x < ((srcRegion.x + colsInTile) / xSub) * numBands; x += numBands) {
System.arraycopy(rowDataInt, x * xSub, rowDataInt, x, numBands);
}
}
- destChannel.setDataElements(startCol, row - srcRegion.y, srcChannel);
+ destChannel.setDataElements(startCol / xSub, (row - srcRegion.y) / ySub, srcChannel);
}
// Else skip data
}
@@ -1907,22 +1913,34 @@ public class TIFFImageReader extends ImageReaderBase {
case TIFFBaseline.COMPRESSION_PACKBITS:
return new DecoderStream(stream, new PackBitsDecoder(), 1024);
case TIFFExtension.COMPRESSION_LZW:
+ // NOTE: Needs large buffer for compatibility with certain encoders
return new DecoderStream(stream, LZWDecoder.create(LZWDecoder.isOldBitReversedStream(stream)), Math.max(width * bands, 4096));
case TIFFExtension.COMPRESSION_ZLIB:
- // TIFFphotoshop.pdf (aka TIFF specification, supplement 2) says ZLIB (8) and DEFLATE (32946) algorithms are identical
case TIFFExtension.COMPRESSION_DEFLATE:
+ // TIFF specification, supplement 2 says ZLIB (8) and DEFLATE (32946) algorithms are identical
return new InflaterInputStream(stream, new Inflater(), 1024);
case TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE:
- return new CCITTFaxDecoderStream(stream, width, compression, getValueAsIntWithDefault(TIFF.TAG_FILL_ORDER, 1),0L);
case TIFFExtension.COMPRESSION_CCITT_T4:
- return new CCITTFaxDecoderStream(stream, width, compression, getValueAsIntWithDefault(TIFF.TAG_FILL_ORDER, 1),getValueAsLongWithDefault(TIFF.TAG_GROUP3OPTIONS, 0L));
case TIFFExtension.COMPRESSION_CCITT_T6:
- return new CCITTFaxDecoderStream(stream, width, compression, getValueAsIntWithDefault(TIFF.TAG_FILL_ORDER, 1),getValueAsLongWithDefault(TIFF.TAG_GROUP4OPTIONS, 0L));
+ return new CCITTFaxDecoderStream(stream, width, compression, getValueAsIntWithDefault(TIFF.TAG_FILL_ORDER, 1), getCCITTOptions(compression));
default:
throw new IllegalArgumentException("Unsupported TIFF compression: " + compression);
}
}
+ private long getCCITTOptions(final int compression) throws IIOException {
+ switch (compression) {
+ case TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE:
+ return 0L;
+ case TIFFExtension.COMPRESSION_CCITT_T4:
+ return getValueAsLongWithDefault(TIFF.TAG_GROUP3OPTIONS, 0L);
+ case TIFFExtension.COMPRESSION_CCITT_T6:
+ return getValueAsLongWithDefault(TIFF.TAG_GROUP4OPTIONS, 0L);
+ default:
+ throw new IllegalArgumentException("No CCITT options for compression: " + compression);
+ }
+ }
+
private InputStream createUnpredictorStream(final int predictor, final int width, final int samplesPerPixel, final int bitsPerSample, final InputStream stream, final ByteOrder byteOrder) throws IOException {
switch (predictor) {
case TIFFBaseline.PREDICTOR_NONE:
@@ -2155,6 +2173,7 @@ public class TIFFImageReader extends ImageReaderBase {
// param.setSourceRegion(new Rectangle(3, 3, 9, 9));
// param.setDestinationOffset(new Point(50, 150));
// param.setSourceSubsampling(2, 2, 0, 0);
+// param.setSourceSubsampling(3, 3, 0, 0);
BufferedImage image = reader.read(imageNo, param);
System.err.println("Read time: " + (System.currentTimeMillis() - start) + " ms");
@@ -2171,6 +2190,20 @@ public class TIFFImageReader extends ImageReaderBase {
System.err.println("image: " + image);
+// int w = image.getWidth();
+// int h = image.getHeight();
+//
+// int newW = h;
+// int newH = w;
+//
+// AffineTransform xform = AffineTransform.getTranslateInstance((newW - w) / 2.0, (newH - h) / 2.0);
+// xform.concatenate(AffineTransform.getQuadrantRotateInstance(3, w / 2.0, h / 2.0));
+// AffineTransformOp op = new AffineTransformOp(xform, null);
+//
+// image = op.filter(image, null);
+//
+// System.err.println("image: " + image);
+//
// File tempFile = File.createTempFile("lzw-", ".bin");
// byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
// FileOutputStream stream = new FileOutputStream(tempFile);
diff --git a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java
index 35e7c171..08bbf63d 100644
--- a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java
+++ b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java
@@ -27,7 +27,6 @@ package com.twelvemonkeys.imageio.plugins.tiff;/*
*/
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
-import org.junit.Ignore;
import org.junit.Test;
import javax.imageio.ImageIO;
@@ -442,4 +441,74 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest
com.twelvemonkeys
twelvemonkeys
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
4.0.0
com.twelvemonkeys.imageio
diff --git a/pom.xml b/pom.xml
index cb1d24ad..db48b399 100755
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
com.twelvemonkeys
twelvemonkeys
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
pom
Twelvemonkeys
diff --git a/servlet/pom.xml b/servlet/pom.xml
index 2f2fc663..fdf7a8ff 100644
--- a/servlet/pom.xml
+++ b/servlet/pom.xml
@@ -3,7 +3,7 @@
com.twelvemonkeys
twelvemonkeys
- 3.3-SNAPSHOT
+ 3.4-SNAPSHOT
4.0.0