From 13a4646ae47ac3f4b17c40250c70413c218d3198 Mon Sep 17 00:00:00 2001 From: Harald Kuhr Date: Mon, 2 Apr 2012 14:25:28 +0200 Subject: [PATCH] Fixed a bug in the IFFImageWriter, caused by buffered data not being written to the stream. Adapter streams are now properly flushed/closed. Test clean-up. --- .../imageio/plugins/iff/IFFImageWriter.java | 12 ++- .../plugins/iff/IFFImageWriterTest.java | 82 ++++++++++++------- 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageWriter.java b/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageWriter.java index e91f64c8..bd3350d0 100755 --- a/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageWriter.java +++ b/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageWriter.java @@ -102,9 +102,15 @@ public class IFFImageWriter extends ImageWriterBase { imageOutput.writeInt(IFF.CHUNK_BODY); imageOutput.writeInt(pImageData.size()); - // NOTE: This is much faster than mOutput.write(pImageData.toByteArray()) + // NOTE: This is much faster than imageOutput.write(pImageData.toByteArray()) // as the data array is not duplicated - pImageData.writeTo(IIOUtil.createStreamAdapter(imageOutput)); + OutputStream adapter = IIOUtil.createStreamAdapter(imageOutput); + try { + pImageData.writeTo(adapter); + } + finally { + adapter.close(); + } if (pImageData.size() % 2 == 0) { imageOutput.writeByte(0); // PAD @@ -163,6 +169,8 @@ public class IFFImageWriter extends ImageWriterBase { } } + output.flush(); + processImageProgress(y * 100f / height); } 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 2ab79015..1cff8e2e 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,6 +28,7 @@ package com.twelvemonkeys.imageio.plugins.iff; +import com.twelvemonkeys.image.MonochromeColorModel; import com.twelvemonkeys.imageio.util.ImageWriterAbstractTestCase; import org.junit.Test; @@ -64,15 +65,15 @@ public class IFFImageWriterTest extends ImageWriterAbstractTestCase { @Override 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())*/ + new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB), + new BufferedImage(33, 20, BufferedImage.TYPE_BYTE_GRAY), + new BufferedImage(31, 23, BufferedImage.TYPE_BYTE_INDEXED), + new BufferedImage(30, 27, BufferedImage.TYPE_BYTE_BINARY), + new BufferedImage(29, 29, BufferedImage.TYPE_BYTE_INDEXED, MonochromeColorModel.getInstance()), + new BufferedImage(28, 31, BufferedImage.TYPE_INT_BGR), + new BufferedImage(27, 33, BufferedImage.TYPE_INT_RGB), + new BufferedImage(24, 37, BufferedImage.TYPE_3BYTE_BGR), + new BufferedImage(23, 41, BufferedImage.TYPE_4BYTE_ABGR) ); } @@ -109,29 +110,52 @@ public class IFFImageWriterTest extends ImageWriterAbstractTestCase { 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); - } - } - } + assertSameType(original, written); + assertSameData(original, written); } catch (IOException e) { - fail(i + " " + e); + AssertionError fail = new AssertionError("Failure writing test data " + i + " " + e); + fail.initCause(e); + throw fail; } } } + + private static void assertSameData(BufferedImage expected, BufferedImage actual) { + 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); + + if (expected.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_GRAY) { + // NOTE: For some reason, gray data seems to be one step off... + assertEquals("R(" + x + "," + y + ")", expectedRGB & 0xff0000, actualRGB & 0xff0000, 0x10000); + assertEquals("G(" + x + "," + y + ")", expectedRGB & 0x00ff00, actualRGB & 0x00ff00, 0x100); + assertEquals("B(" + x + "," + y + ")", expectedRGB & 0x0000ff, actualRGB & 0x0000ff, 0x1); + } + else { + assertEquals("R(" + x + "," + y + ")", expectedRGB & 0xff0000, actualRGB & 0xff0000); + assertEquals("G(" + x + "," + y + ")", expectedRGB & 0x00ff00, actualRGB & 0x00ff00); + assertEquals("B(" + x + "," + y + ")", expectedRGB & 0x0000ff, actualRGB & 0x0000ff); + } + } + } + } + + private static void assertSameType(BufferedImage expected, BufferedImage actual) { + if (expected.getType() != actual.getType()) { + if (expected.getType() == BufferedImage.TYPE_INT_RGB || expected.getType() == BufferedImage.TYPE_INT_BGR) { + assertEquals(BufferedImage.TYPE_3BYTE_BGR, actual.getType()); + } + else if (expected.getType() == BufferedImage.TYPE_INT_ARGB || expected.getType() == BufferedImage.TYPE_INT_ARGB_PRE) { + assertEquals(BufferedImage.TYPE_4BYTE_ABGR, actual.getType()); + } + else if (expected.getType() == BufferedImage.TYPE_BYTE_INDEXED && expected.getColorModel().getPixelSize() <= 16) { + assertEquals(BufferedImage.TYPE_BYTE_BINARY, actual.getType()); + } + + // NOTE: Actually, TYPE_GRAY may be converted to TYPE_BYTE_INDEXED with linear gray color-map, + // without being a problem (just a waste of time and space). + } + } }