diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageWriter.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageWriter.java index 7279716b..21d66ba9 100644 --- a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageWriter.java +++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageWriter.java @@ -947,9 +947,9 @@ public final class TIFFImageWriter extends ImageWriterBase { throw new IllegalStateException("prepareWriteSequence() must be called before writeToSequence()!"); } - if (sequenceLastIFDPos > 0) { - imageOutput.seek(imageOutput.length()); + if (sequenceIndex > 0) { imageOutput.flushBefore(sequenceLastIFDPos); + imageOutput.seek(imageOutput.length()); } sequenceLastIFDPos = writePage(sequenceIndex++, image, param, sequenceTIFFWriter, sequenceLastIFDPos); diff --git a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageWriterTest.java b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageWriterTest.java index 9ea62f9f..8770f474 100644 --- a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageWriterTest.java +++ b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageWriterTest.java @@ -45,14 +45,14 @@ import javax.imageio.event.IIOWriteProgressListener; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataFormatImpl; import javax.imageio.metadata.IIOMetadataNode; +import javax.imageio.stream.FileCacheImageOutputStream; +import javax.imageio.stream.FileImageOutputStream; import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageOutputStream; import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; +import java.io.*; import java.net.URL; import java.nio.ByteOrder; import java.util.ArrayList; @@ -337,6 +337,101 @@ public class TIFFImageWriterTest extends ImageWriterAbstractTestCase { } } + private void assertWriteSequence(Class iosClass, String... compression) throws IOException { + BufferedImage image = new BufferedImage(13, 13, BufferedImage.TYPE_BYTE_GRAY); + + Graphics2D g2d = image.createGraphics(); + try { + g2d.setColor(Color.WHITE); + g2d.fillRect(image.getWidth() / 4, image.getHeight() / 4, image.getWidth() / 2, image.getHeight() / 2); + } + finally { + g2d.dispose(); + } + + boolean isFileDirect = iosClass == FileImageOutputStream.class; + Object destination = isFileDirect + ? File.createTempFile("temp-", ".tif") + : new ByteArrayOutputStream(1024); + + ImageWriter writer = createImageWriter(); + try (ImageOutputStream output = isFileDirect + ? new FileImageOutputStream((File) destination) + : new FileCacheImageOutputStream((OutputStream) destination, ImageIO.getCacheDirectory())) { + writer.setOutput(output); + + ImageWriteParam params = writer.getDefaultWriteParam(); + params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + + try { + writer.prepareWriteSequence(null); + + for (String compressionType : compression) { + params.setCompressionType(compressionType); + writer.writeToSequence(new IIOImage(image, null, null), params); + } + + writer.endWriteSequence(); + } + catch (IOException e) { + fail(e.getMessage()); + } + } + + try (ImageInputStream input = ImageIO.createImageInputStream(isFileDirect + ? destination + : new ByteArrayInputStream(((ByteArrayOutputStream) destination).toByteArray()))) { + ImageReader reader = ImageIO.getImageReaders(input).next(); + reader.setInput(input); + + assertEquals("wrong image count", compression.length, reader.getNumImages(true)); + + for (int i = 0; i < reader.getNumImages(true); i++) { + assertImageEquals("image " + i + " differs", image, reader.read(i), 5); // Allow room for JPEG compression + } + } + } + + @Test + public void testWriteSequenceFileImageOutputStreamUncompressed() throws IOException { + assertWriteSequence(FileImageOutputStream.class, "None", "None"); + } + + @Test + public void testWriteSequenceFileImageOutputCompressed() throws IOException { + assertWriteSequence(FileImageOutputStream.class, "LZW", "Deflate"); + } + + @Test + public void testWriteSequenceFileImageOutputStreamUncompressedCompressed() throws IOException { + assertWriteSequence(FileImageOutputStream.class, "None", "LZW", "None"); + } + + @Test + public void testWriteSequenceFileImageOutputStreamCompressedUncompressed() throws IOException { + assertWriteSequence(FileImageOutputStream.class, "Deflate", "None", "Deflate"); + } + + @Test + public void testWriteSequenceFileCacheImageOutputStreamUncompressed() throws IOException { + assertWriteSequence(FileCacheImageOutputStream.class, "None", "None"); + } + + @Test + public void testWriteSequenceFileCacheImageOutputStreamCompressed() throws IOException { + assertWriteSequence(FileCacheImageOutputStream.class, "Deflate", "LZW"); + } + + @Test + public void testWriteSequenceFileCacheImageOutputStreamCompressedUncompressed() throws IOException { + assertWriteSequence(FileCacheImageOutputStream.class, "LZW", "None", "LZW"); + } + + @Test + public void testWriteSequenceFileCacheImageOutputStreamUncompressedCompressed() throws IOException { + assertWriteSequence(FileCacheImageOutputStream.class, "None", "Deflate", "None"); + } + @Test public void testWriteSequence() throws IOException { BufferedImage[] images = new BufferedImage[] { @@ -409,16 +504,7 @@ public class TIFFImageWriterTest extends ImageWriterAbstractTestCase { assertEquals("wrong image count", images.length, reader.getNumImages(true)); for (int i = 0; i < reader.getNumImages(true); i++) { - BufferedImage image = reader.read(i); - - assertEquals(images[i].getWidth(), image.getWidth()); - assertEquals(images[i].getHeight(), image.getHeight()); - - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - assertRGBEquals("RGB differ for image " + i + " (" + x + "," + y + ")", images[i].getRGB(x, y), image.getRGB(x, y), 5); // Allow room for JPEG compression - } - } + assertImageEquals("image " + i + " differs", images[i], reader.read(i), 5); // Allow room for JPEG compression } } }