diff --git a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/ImageReaderBase.java b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/ImageReaderBase.java index 42179673..4abdd70e 100644 --- a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/ImageReaderBase.java +++ b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/ImageReaderBase.java @@ -99,9 +99,13 @@ public abstract class ImageReaderBase extends ImageReader { public void setInput(final Object input, final boolean seekForwardOnly, final boolean ignoreMetadata) { resetMembers(); super.setInput(input, seekForwardOnly, ignoreMetadata); + if (input instanceof ImageInputStream) { imageInput = (ImageInputStream) input; } + else { + imageInput = null; + } } @Override diff --git a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/ImageWriterBase.java b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/ImageWriterBase.java index 441ae50a..f6239068 100755 --- a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/ImageWriterBase.java +++ b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/ImageWriterBase.java @@ -83,6 +83,9 @@ public abstract class ImageWriterBase extends ImageWriter { if (output instanceof ImageOutputStream) { imageOutput = (ImageOutputStream) output; } + else { + imageOutput = null; + } } /** diff --git a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageWriterAbstractTestCase.java b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageWriterAbstractTestCase.java index fda37b87..e6fa78ea 100755 --- a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageWriterAbstractTestCase.java +++ b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageWriterAbstractTestCase.java @@ -36,9 +36,12 @@ import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.event.IIOWriteProgressListener; import javax.imageio.stream.ImageOutputStream; +import java.awt.*; +import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.List; import static org.junit.Assert.*; import static org.mockito.Matchers.anyInt; @@ -55,7 +58,32 @@ public abstract class ImageWriterAbstractTestCase { protected abstract ImageWriter createImageWriter(); - protected abstract RenderedImage getTestData(); + protected abstract List getTestData(); + + protected static BufferedImage drawSomething(final BufferedImage image) { + Graphics2D g = image.createGraphics(); + try { + int width = image.getWidth(); + int height = image.getHeight(); + + g.clearRect(0, 0, width, height); + g.setPaint(new LinearGradientPaint(0, 0, width, 0, new float[] {0.2f, 1}, new Color[] {new Color(0x0, true), Color.BLUE})); + g.fillRect(0, 0, width, height); + g.setPaint(new LinearGradientPaint(0, 0, 0, height, new float[] {0.2f, 1}, new Color[] {new Color(0x0, true), Color.RED})); + g.fillRect(0, 0, width, height); + g.setPaint(new LinearGradientPaint(0, 0, 0, height, new float[] {0, 1}, new Color[] {new Color(0x00ffffff, true), Color.WHITE})); + g.fill(new Polygon(new int[] {0, width, width}, new int[] {0, height, 0}, 3)); + } + finally { + g.dispose(); + } + + return image; + } + + protected final RenderedImage getTestData(final int index) { + return getTestData().get(index); + } @Test public void testSetOutput() throws IOException { @@ -76,21 +104,24 @@ public abstract class ImageWriterAbstractTestCase { @Test public void testWrite() throws IOException { ImageWriter writer = createImageWriter(); - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - ImageOutputStream stream = ImageIO.createImageOutputStream(buffer); - writer.setOutput(stream); - try { - writer.write(getTestData()); - } - catch (IOException e) { - fail(e.getMessage()); - } - finally { - stream.close(); // Force data to be written - } + for (RenderedImage testData : getTestData()) { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + ImageOutputStream stream = ImageIO.createImageOutputStream(buffer); + writer.setOutput(stream); - assertTrue("No image data written", buffer.size() > 0); + try { + writer.write(drawSomething((BufferedImage) testData)); + } + catch (IOException e) { + fail(e.getMessage()); + } + finally { + stream.close(); // Force data to be written + } + + assertTrue("No image data written", buffer.size() > 0); + } } @Test @@ -116,7 +147,7 @@ public abstract class ImageWriterAbstractTestCase { ImageWriter writer = createImageWriter(); try { - writer.write(getTestData()); + writer.write(getTestData(0)); } catch (IOException e) { fail(e.getMessage()); @@ -155,7 +186,7 @@ public abstract class ImageWriterAbstractTestCase { writer.addIIOWriteProgressListener(listener); try { - writer.write(getTestData()); + writer.write(getTestData(0)); } catch (IOException e) { fail("Could not write image"); @@ -183,7 +214,7 @@ public abstract class ImageWriterAbstractTestCase { writer.addIIOWriteProgressListener(listenerThree); try { - writer.write(getTestData()); + writer.write(getTestData(0)); } catch (IOException e) { fail("Could not write image"); @@ -228,7 +259,7 @@ public abstract class ImageWriterAbstractTestCase { writer.removeIIOWriteProgressListener(listener); try { - writer.write(getTestData()); + writer.write(getTestData(0)); } catch (IOException e) { fail("Could not write image"); @@ -253,7 +284,7 @@ public abstract class ImageWriterAbstractTestCase { writer.removeIIOWriteProgressListener(listener); try { - writer.write(getTestData()); + writer.write(getTestData(0)); } catch (IOException e) { fail("Could not write image"); @@ -283,7 +314,7 @@ public abstract class ImageWriterAbstractTestCase { writer.removeAllIIOWriteProgressListeners(); try { - writer.write(getTestData()); + writer.write(getTestData(0)); } catch (IOException e) { fail("Could not write image"); @@ -309,7 +340,7 @@ public abstract class ImageWriterAbstractTestCase { writer.removeAllIIOWriteProgressListeners(); try { - writer.write(getTestData()); + writer.write(getTestData(0)); } catch (IOException e) { fail("Could not write image"); diff --git a/imageio/imageio-iff/src/test/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageWriterTest.java b/imageio/imageio-iff/src/test/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageWriterTest.java index 6d01a607..97c6f838 100644 --- a/imageio/imageio-iff/src/test/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageWriterTest.java +++ b/imageio/imageio-iff/src/test/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageWriterTest.java @@ -28,11 +28,25 @@ package com.twelvemonkeys.imageio.plugins.iff; +import com.twelvemonkeys.image.MonochromeColorModel; import com.twelvemonkeys.imageio.util.ImageWriterAbstractTestCase; +import org.junit.Test; +import javax.imageio.ImageIO; import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; +import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; /** * JPEG2000ImageWriterTest @@ -50,7 +64,70 @@ public class IFFImageWriterTest extends ImageWriterAbstractTestCase { } @Override - protected RenderedImage getTestData() { - return new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); + protected List getTestData() { + return Arrays.asList( + new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB), + new BufferedImage(32, 20, BufferedImage.TYPE_INT_RGB), + new BufferedImage(32, 20, BufferedImage.TYPE_INT_BGR), + new BufferedImage(32, 20, BufferedImage.TYPE_3BYTE_BGR), + new BufferedImage(32, 20, BufferedImage.TYPE_4BYTE_ABGR), + new BufferedImage(32, 20, BufferedImage.TYPE_BYTE_GRAY), + new BufferedImage(32, 20, BufferedImage.TYPE_BYTE_INDEXED), + new BufferedImage(32, 20, BufferedImage.TYPE_BYTE_BINARY), + new BufferedImage(32, 20, BufferedImage.TYPE_BYTE_INDEXED, MonochromeColorModel.getInstance()) + ); + } + + @Test + public void testWriteReadCompare() throws IOException { + ImageWriter writer = createImageWriter(); + + List testData = getTestData(); + for (int i = 0; i < testData.size(); i++) { + RenderedImage image = testData.get(i); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + ImageOutputStream stream = ImageIO.createImageOutputStream(buffer); + writer.setOutput(stream); + + BufferedImage original = drawSomething((BufferedImage) image); + + try { + writer.write(original); + } + catch (IOException e) { + fail(e.getMessage()); + } + finally { + stream.close(); // Force data to be written + } + + assertTrue("No image data written", buffer.size() > 0); + + ImageInputStream input = ImageIO.createImageInputStream(new ByteArrayInputStream(buffer.toByteArray())); + BufferedImage written = ImageIO.read(input); + + assertNotNull(written); + assertEquals(original.getWidth(), written.getWidth()); + assertEquals(original.getHeight(), written.getHeight()); + + for (int y = 0; y < original.getHeight(); y++) { + for (int x = 0; x < original.getWidth(); x++) { + int originalRGB = original.getRGB(x, y); + int writtenRGB = written.getRGB(x, y); + + if (original.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_GRAY) { + // NOTE: For some reason, gray data seems to be one step off... + assertEquals("Test data " + i + " R(" + x + "," + y + ")", originalRGB & 0xff0000, writtenRGB & 0xff0000, 0x10000); + assertEquals("Test data " + i + " G(" + x + "," + y + ")", originalRGB & 0x00ff00, writtenRGB & 0x00ff00, 0x100); + assertEquals("Test data " + i + " B(" + x + "," + y + ")", originalRGB & 0x0000ff, writtenRGB & 0x0000ff, 0x1); + } + else { + assertEquals("Test data " + i + " R(" + x + "," + y + ")", originalRGB & 0xff0000, writtenRGB & 0xff0000); + assertEquals("Test data " + i + " G(" + x + "," + y + ")", originalRGB & 0x00ff00, writtenRGB & 0x00ff00); + assertEquals("Test data " + i + " B(" + x + "," + y + ")", originalRGB & 0x0000ff, writtenRGB & 0x0000ff); + } + } + } + } } } diff --git a/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriterTest.java b/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriterTest.java index d409b442..0fbe8bc0 100644 --- a/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriterTest.java +++ b/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriterTest.java @@ -36,6 +36,8 @@ import javax.imageio.spi.ImageWriterSpi; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.IOException; +import java.util.Arrays; +import java.util.List; /** * JPEGImageWriterTest @@ -63,7 +65,14 @@ public class JPEGImageWriterTest extends ImageWriterAbstractTestCase { } @Override - protected RenderedImage getTestData() { - return new BufferedImage(320, 200, BufferedImage.TYPE_3BYTE_BGR); + protected List getTestData() { + return Arrays.asList( + new BufferedImage(320, 200, BufferedImage.TYPE_3BYTE_BGR), + new BufferedImage(32, 20, BufferedImage.TYPE_INT_RGB), + new BufferedImage(32, 20, BufferedImage.TYPE_INT_BGR), + new BufferedImage(32, 20, BufferedImage.TYPE_INT_ARGB), + new BufferedImage(32, 20, BufferedImage.TYPE_4BYTE_ABGR), + new BufferedImage(32, 20, BufferedImage.TYPE_BYTE_GRAY) + ); } } diff --git a/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageWriter.java b/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageWriter.java index c1b40553..a4baa53c 100755 --- a/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageWriter.java +++ b/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageWriter.java @@ -198,6 +198,7 @@ public class PICTImageWriter extends ImageWriterBase { // Pixel type, 16 is allright for direct pixels imageOutput.writeShort(16); + // TODO: Support others? // Pixel size imageOutput.writeShort(32); @@ -257,20 +258,19 @@ public class PICTImageWriter extends ImageWriterBase { // Treat the scanline. for (int j = 0; j < w; j++) { if (model instanceof ComponentColorModel && model.getColorSpace().getType() == ColorSpace.TYPE_RGB) { - // TODO: Component order? + // NOTE: Assumes component order always (A)BGR // TODO: Alpha support - scanlineBytes[x + j] = pixels[off + i * scansize * components + components * j + 2]; - scanlineBytes[x + w + j] = pixels[off + i * scansize * components + components * j + 1]; - scanlineBytes[x + 2 * w + j] = pixels[off + i * scansize * components + components * j]; + scanlineBytes[x + j] = pixels[off + i * scansize * components + components * j + components - 1]; + scanlineBytes[x + w + j] = pixels[off + i * scansize * components + components * j + components - 2]; + scanlineBytes[x + 2 * w + j] = pixels[off + i * scansize * components + components * j + components - 3]; } else { int rgb = model.getRGB(pixels[off + i * scansize + j] & 0xFF); // Set red, green and blue components. - scanlineBytes[x + j] = (byte) ((rgb >> 16) & 0xFF); - scanlineBytes[x + w + j] = (byte) ((rgb >> 8) & 0xFF); - scanlineBytes[x + 2 * w + j] = (byte) (rgb & 0xFF); + scanlineBytes[x + j] = (byte) ((rgb >> 16) & 0xFF); + scanlineBytes[x + w + j] = (byte) ((rgb >> 8) & 0xFF); + scanlineBytes[x + 2 * w + j] = (byte) ((rgb ) & 0xFF); } - } // If we have a complete scanline, then pack it and write it out. @@ -288,7 +288,9 @@ public class PICTImageWriter extends ImageWriterBase { imageOutput.writeByte(bytes.size()); } - bytes.writeTo(IIOUtil.createStreamAdapter(imageOutput)); + OutputStream adapter = IIOUtil.createStreamAdapter(imageOutput); + bytes.writeTo(adapter); + adapter.flush(); scanWidthLeft = w; } @@ -313,9 +315,9 @@ public class PICTImageWriter extends ImageWriterBase { int rgb = model.getRGB(pixels[off + i * scansize + j]); // Set red, green and blue components. - scanlineBytes[x + j] = (byte) ((rgb >> 16) & 0xFF); - scanlineBytes[x + w + j] = (byte) ((rgb >> 8) & 0xFF); - scanlineBytes[x + 2 * w + j] = (byte) (rgb & 0xFF); + scanlineBytes[x + j] = (byte) ((rgb >> 16) & 0xFF); + scanlineBytes[x + w + j] = (byte) ((rgb >> 8) & 0xFF); + scanlineBytes[x + 2 * w + j] = (byte) ((rgb ) & 0xFF); } // If we have a complete scanline, then pack it and write it out. @@ -333,7 +335,9 @@ public class PICTImageWriter extends ImageWriterBase { imageOutput.writeByte(bytes.size()); } - bytes.writeTo(IIOUtil.createStreamAdapter(imageOutput)); + OutputStream adapter = IIOUtil.createStreamAdapter(imageOutput); + bytes.writeTo(adapter); + adapter.flush(); scanWidthLeft = w; } diff --git a/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageWriterTest.java b/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageWriterTest.java index dd965fd9..cbfa0315 100644 --- a/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageWriterTest.java +++ b/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageWriterTest.java @@ -29,10 +29,23 @@ package com.twelvemonkeys.imageio.plugins.pict; import com.twelvemonkeys.imageio.util.ImageWriterAbstractTestCase; +import org.junit.Test; +import javax.imageio.ImageIO; import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; +import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; /** * PICTImageWriterTest @@ -50,8 +63,69 @@ public class PICTImageWriterTest extends ImageWriterAbstractTestCase { } @Override - protected RenderedImage getTestData() { - // TODO: Alpha support - return new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); + protected List getTestData() { + return Arrays.asList( + new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB), + new BufferedImage(32, 20, BufferedImage.TYPE_INT_BGR), + new BufferedImage(32, 20, BufferedImage.TYPE_INT_ARGB), + new BufferedImage(30, 20, BufferedImage.TYPE_3BYTE_BGR), + new BufferedImage(30, 20, BufferedImage.TYPE_4BYTE_ABGR), + new BufferedImage(32, 20, BufferedImage.TYPE_BYTE_INDEXED), + new BufferedImage(32, 20, BufferedImage.TYPE_BYTE_GRAY) +// new BufferedImage(32, 20, BufferedImage.TYPE_BYTE_BINARY) // Packed does not work + ); + } + + @Test + public void testWriteReadCompare() throws IOException { + ImageWriter writer = createImageWriter(); + + List testData = getTestData(); + for (int i = 0; i < testData.size(); i++) { + RenderedImage image = testData.get(i); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + ImageOutputStream stream = ImageIO.createImageOutputStream(buffer); + writer.setOutput(stream); + + BufferedImage original = drawSomething((BufferedImage) image); + + try { + writer.write(original); + } + catch (IOException e) { + fail(e.getMessage()); + } + finally { + stream.close(); // Force data to be written + } + + assertTrue("No image data written", buffer.size() > 0); + + ImageInputStream input = ImageIO.createImageInputStream(new ByteArrayInputStream(buffer.toByteArray())); + BufferedImage written = ImageIO.read(input); + + assertNotNull(written); + assertEquals(original.getWidth(), written.getWidth()); + assertEquals(original.getHeight(), written.getHeight()); + + for (int y = 0; y < original.getHeight(); y++) { + for (int x = 0; x < original.getWidth(); x++) { + int originalRGB = original.getRGB(x, y); + int writtenRGB = written.getRGB(x, y); + + if (original.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_GRAY) { + // NOTE: For some reason, gray data seems to be one step off... + assertEquals("Test data " + i + " R(" + x + "," + y + ")", originalRGB & 0xff0000, writtenRGB & 0xff0000, 0x10000); + assertEquals("Test data " + i + " G(" + x + "," + y + ")", originalRGB & 0x00ff00, writtenRGB & 0x00ff00, 0x100); + assertEquals("Test data " + i + " B(" + x + "," + y + ")", originalRGB & 0x0000ff, writtenRGB & 0x0000ff, 0x1); + } + else { + assertEquals("Test data " + i + " R(" + x + "," + y + ")", originalRGB & 0xff0000, writtenRGB & 0xff0000); + assertEquals("Test data " + i + " G(" + x + "," + y + ")", originalRGB & 0x00ff00, writtenRGB & 0x00ff00); + assertEquals("Test data " + i + " B(" + x + "," + y + ")", originalRGB & 0x0000ff, writtenRGB & 0x0000ff); + } + } + } + } } }