diff --git a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/ICOImageWriter.java b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/ICOImageWriter.java index ea809460..b7f49d2e 100644 --- a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/ICOImageWriter.java +++ b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/ICOImageWriter.java @@ -32,6 +32,7 @@ package com.twelvemonkeys.imageio.plugins.bmp; import com.twelvemonkeys.imageio.stream.SubImageOutputStream; import com.twelvemonkeys.imageio.util.ProgressListenerBase; +import com.twelvemonkeys.imageio.util.SequenceSupport; import javax.imageio.IIOException; import javax.imageio.IIOImage; @@ -64,7 +65,7 @@ public final class ICOImageWriter extends DIBImageWriter { private static final int ICO_MAX_DIMENSION = 256; private static final int INITIAL_ENTRY_COUNT = 8; - private int sequenceIndex = -1; + private final SequenceSupport sequence = new SequenceSupport(); private ImageWriter pngDelegate; @@ -74,7 +75,7 @@ public final class ICOImageWriter extends DIBImageWriter { @Override protected void resetMembers() { - sequenceIndex = -1; + sequence.reset(); if (pngDelegate != null) { pngDelegate.dispose(); @@ -107,16 +108,12 @@ public final class ICOImageWriter extends DIBImageWriter { @Override public void prepareWriteSequence(final IIOMetadata streamMetadata) throws IOException { assertOutput(); - - if (sequenceIndex >= 0) { - throw new IllegalStateException("writeSequence already started"); - } + sequence.start(); writeICOHeader(); // Count: Needs to be updated for each new image imageOutput.writeShort(0); - sequenceIndex = 0; // TODO: Allow passing the initial size of the directory in the stream metadata? // - as this is much more efficient than growing... @@ -130,27 +127,19 @@ public final class ICOImageWriter extends DIBImageWriter { @Override public void endWriteSequence() { assertOutput(); - - if (sequenceIndex < 0) { - throw new IllegalStateException("prepareWriteSequence not called"); - } - - sequenceIndex = -1; + sequence.end(); } @Override public void writeToSequence(final IIOImage image, final ImageWriteParam param) throws IOException { assertOutput(); - - if (sequenceIndex < 0) { - throw new IllegalStateException("prepareWriteSequence not called"); - } + int imageIndex = sequence.advance(); if (image.hasRaster()) { throw new UnsupportedOperationException("Raster not supported"); } - if (sequenceIndex >= INITIAL_ENTRY_COUNT) { + if (imageIndex >= INITIAL_ENTRY_COUNT) { growIfNecessary(); } @@ -172,7 +161,7 @@ public final class ICOImageWriter extends DIBImageWriter { // Uncompressed, RLE4/RLE8 or PNG compressed boolean pngCompression = param != null && "BI_PNG".equals(param.getCompressionType()); - processImageStarted(sequenceIndex); + processImageStarted(imageIndex); if (pngCompression) { // NOTE: Embedding a PNG in a ICO is slightly different than a BMP with BI_PNG compression, @@ -198,17 +187,15 @@ public final class ICOImageWriter extends DIBImageWriter { // Update count imageOutput.seek(4); - imageOutput.writeShort(sequenceIndex + 1); + imageOutput.writeShort(imageIndex + 1); // Write entry - int entryPosition = 6 + sequenceIndex * ENTRY_SIZE; + int entryPosition = 6 + imageIndex * ENTRY_SIZE; imageOutput.seek(entryPosition); long size = nextPosition - imageOffset; writeEntry(width, height, colorModel, (int) size, (int) imageOffset); - sequenceIndex++; - imageOutput.seek(nextPosition); } @@ -265,7 +252,7 @@ public final class ICOImageWriter extends DIBImageWriter { pngDelegate.addIIOWriteWarningListener(new IIOWriteWarningListener() { @Override public void warningOccurred(ImageWriter source, int imageIndex, String warning) { - processWarningOccurred(sequenceIndex, warning); + processWarningOccurred(sequence.current(), warning); } }); } diff --git a/imageio/imageio-icns/src/main/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageWriter.java b/imageio/imageio-icns/src/main/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageWriter.java index be78fb08..552dc549 100644 --- a/imageio/imageio-icns/src/main/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageWriter.java +++ b/imageio/imageio-icns/src/main/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageWriter.java @@ -33,6 +33,7 @@ package com.twelvemonkeys.imageio.plugins.icns; import com.twelvemonkeys.imageio.ImageWriterBase; import com.twelvemonkeys.imageio.stream.SubImageOutputStream; import com.twelvemonkeys.imageio.util.ProgressListenerBase; +import com.twelvemonkeys.imageio.util.SequenceSupport; import javax.imageio.IIOException; import javax.imageio.IIOImage; @@ -55,7 +56,7 @@ import java.util.Iterator; */ public final class ICNSImageWriter extends ImageWriterBase { - private int sequenceIndex = -1; + private final SequenceSupport sequence = new SequenceSupport(); private ImageWriter pngDelegate; ICNSImageWriter(ImageWriterSpi provider) { @@ -64,7 +65,7 @@ public final class ICNSImageWriter extends ImageWriterBase { @Override protected void resetMembers() { - sequenceIndex = -1; + sequence.reset(); if (pngDelegate != null) { pngDelegate.dispose(); @@ -97,41 +98,29 @@ public final class ICNSImageWriter extends ImageWriterBase { @Override public void prepareWriteSequence(final IIOMetadata streamMetadata) throws IOException { assertOutput(); + sequence.start(); // TODO: Allow TOC resource to be passed as stream metadata? // - We only need number of icons to be written later // - The contents of the TOC could be updated while adding to the sequence - if (sequenceIndex >= 0) { - throw new IllegalStateException("writeSequence already started"); - } - writeICNSHeader(); - sequenceIndex = 0; } @SuppressWarnings("RedundantThrows") @Override public void endWriteSequence() throws IOException { assertOutput(); - - if (sequenceIndex < 0) { - throw new IllegalStateException("prepareWriteSequence not called"); - } + sequence.end(); // TODO: Now that we know the number of icon resources, we could move all data backwards // and write a TOC... But I don't think the benefit will outweigh the cost. - - sequenceIndex = -1; } @Override public void writeToSequence(final IIOImage image, final ImageWriteParam param) throws IOException { assertOutput(); - - if (sequenceIndex < 0) { - throw new IllegalStateException("prepareWriteSequence not called"); - } + int imageIndex = sequence.advance(); if (image.hasRaster()) { throw new UnsupportedOperationException("image has a Raster"); @@ -148,7 +137,7 @@ public final class ICNSImageWriter extends ImageWriterBase { imageOutput.writeInt(IconResource.typeFromImage(image.getRenderedImage(), "PNG")); imageOutput.writeInt(0); // Size, update later - processImageStarted(sequenceIndex); + processImageStarted(imageIndex); // Write icon in PNG format ImageWriter writer = getPNGDelegate(); @@ -208,7 +197,7 @@ public final class ICNSImageWriter extends ImageWriterBase { pngDelegate.addIIOWriteWarningListener(new IIOWriteWarningListener() { @Override public void warningOccurred(ImageWriter source, int imageIndex, String warning) { - processWarningOccurred(sequenceIndex, warning); + processWarningOccurred(sequence.current(), warning); } }); } 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 8ee862cc..d474e3f5 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 @@ -42,6 +42,7 @@ import com.twelvemonkeys.imageio.stream.SubImageOutputStream; import com.twelvemonkeys.imageio.util.IIOUtil; import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers; import com.twelvemonkeys.imageio.util.ProgressListenerBase; +import com.twelvemonkeys.imageio.util.SequenceSupport; import com.twelvemonkeys.io.enc.EncoderStream; import com.twelvemonkeys.io.enc.PackBitsEncoder; import com.twelvemonkeys.lang.Validate; @@ -110,12 +111,7 @@ public final class TIFFImageWriter extends ImageWriterBase { // Support storing multiple images in one stream (multi-page TIFF) // Support more of the ImageIO metadata (ie. compression from metadata, etc) - /** - * Flag for active sequence writing - */ - private boolean writingSequence = false; - - private int sequenceIndex = 0; + private final SequenceSupport sequence = new SequenceSupport(); /** * Metadata writer for sequence writing @@ -751,7 +747,7 @@ public final class TIFFImageWriter extends ImageWriterBase { ifd = ((TIFFImageMetadata) inData).getIFD(); } else { - TIFFImageMetadata outData = new TIFFImageMetadata(Collections.emptySet()); + TIFFImageMetadata outData = new TIFFImageMetadata(Collections.emptySet()); try { if (Arrays.asList(inData.getMetadataFormatNames()).contains(SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME)) { @@ -766,7 +762,7 @@ public final class TIFFImageWriter extends ImageWriterBase { } } catch (IIOInvalidTreeException e) { - processWarningOccurred(sequenceIndex, "Could not convert image meta data: " + e.getMessage()); + processWarningOccurred(sequence.current(), "Could not convert image meta data: " + e.getMessage()); } ifd = outData.getIFD(); @@ -966,14 +962,11 @@ public final class TIFFImageWriter extends ImageWriterBase { @Override public void prepareWriteSequence(final IIOMetadata streamMetadata) throws IOException { - if (writingSequence) { - throw new IllegalStateException("sequence writing has already been started!"); - } + sequence.start(); assertOutput(); configureStreamByteOrder(streamMetadata, imageOutput); - writingSequence = true; sequenceTIFFWriter = new TIFFWriter(isBigTIFF() ? 8 : 4); sequenceTIFFWriter.writeTIFFHeader(imageOutput); sequenceLastIFDPos = imageOutput.getStreamPosition(); @@ -985,26 +978,20 @@ public final class TIFFImageWriter extends ImageWriterBase { @Override public void writeToSequence(final IIOImage image, final ImageWriteParam param) throws IOException { - if (!writingSequence) { - throw new IllegalStateException("prepareWriteSequence() must be called before writeToSequence()!"); - } + int sequenceIndex = sequence.advance(); if (sequenceIndex > 0) { imageOutput.flushBefore(sequenceLastIFDPos); imageOutput.seek(imageOutput.length()); } - sequenceLastIFDPos = writePage(sequenceIndex++, image, param, sequenceTIFFWriter, sequenceLastIFDPos); + sequenceLastIFDPos = writePage(sequenceIndex, image, param, sequenceTIFFWriter, sequenceLastIFDPos); } @Override public void endWriteSequence() throws IOException { - if (!writingSequence) { - throw new IllegalStateException("prepareWriteSequence() must be called before endWriteSequence()!"); - } + sequence.end(); - writingSequence = false; - sequenceIndex = 0; sequenceTIFFWriter = null; sequenceLastIFDPos = -1; imageOutput.flush(); @@ -1014,8 +1001,7 @@ public final class TIFFImageWriter extends ImageWriterBase { protected void resetMembers() { super.resetMembers(); - writingSequence = false; - sequenceIndex = 0; + sequence.reset(); sequenceTIFFWriter = null; sequenceLastIFDPos = -1; }