#617 BigTIFF write support.

This commit is contained in:
Harald Kuhr
2021-08-09 21:11:40 +02:00
parent 564778f415
commit 1ddab866fd
9 changed files with 674 additions and 60 deletions
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2021, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.imageio.spi.ImageWriterSpiBase;
import javax.imageio.ImageTypeSpecifier;
import java.util.Locale;
/**
* BigTIFFImageWriterSpi
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: BigTIFFImageWriterSpi.java,v 1.0 18.09.13 12:46 haraldk Exp$
*/
public final class BigTIFFImageWriterSpi extends ImageWriterSpiBase {
// TODO: Implement canEncodeImage better
public BigTIFFImageWriterSpi() {
super(new BigTIFFProviderInfo());
}
@Override
public boolean canEncodeImage(final ImageTypeSpecifier type) {
// TODO: Test bit depths compatibility
return true;
}
@Override
public TIFFImageWriter createWriterInstance(final Object extension) {
return new TIFFImageWriter(this);
}
@Override
public String getDescription(final Locale locale) {
return "BigTIFF image writer";
}
}
@@ -50,8 +50,8 @@ final class BigTIFFProviderInfo extends ReaderWriterProviderInfo {
},
"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReader",
new String[] {"com.twelvemonkeys.imageio.plugins.tiff.BigTIFFImageReaderSpi"},
null,
null,
"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriter",
new String[] {"com.twelvemonkeys.imageio.plugins.tiff.BigTIFFImageWriterSpi"},
false, TIFFStreamMetadata.SUN_NATIVE_STREAM_METADATA_FORMAT_NAME, "com.twelvemonkeys.imageio.plugins.tiff.TIFFStreamMetadataFormat", null, null,
true, TIFFMedataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME, "com.twelvemonkeys.imageio.plugins.tiff.TIFFMedataFormat", null, null
);
@@ -202,26 +202,26 @@ public final class TIFFImageWriter extends ImageWriterBase {
long streamPosition = imageOutput.getStreamPosition();
long ifdSize = tiffWriter.computeIFDSize(entries.values());
long stripOffset = streamPosition + 4 + ifdSize + 4;
long stripOffset = streamPosition + tiffWriter.offsetSize() + ifdSize + tiffWriter.offsetSize();
long stripByteCount = ((long) renderedImage.getWidth() * renderedImage.getHeight() * pixelSize + 7L) / 8L;
entries.put(TIFF.TAG_STRIP_OFFSETS, new TIFFEntry(TIFF.TAG_STRIP_OFFSETS, TIFF.TYPE_LONG, stripOffset));
entries.put(TIFF.TAG_STRIP_BYTE_COUNTS, new TIFFEntry(TIFF.TAG_STRIP_BYTE_COUNTS, TIFF.TYPE_LONG, stripByteCount));
long ifdPointer = tiffWriter.writeIFD(entries.values(), imageOutput); // NOTE: Writer takes case of ordering tags
long ifdPointer = tiffWriter.writeIFD(entries.values(), imageOutput); // NOTE: Writer takes care of ordering tags
nextIFDPointerOffset = imageOutput.getStreamPosition();
// If we have a previous IFD, update pointer
if (streamPosition > lastIFDPointerOffset) {
imageOutput.seek(lastIFDPointerOffset);
imageOutput.writeInt((int) ifdPointer);
tiffWriter.writeOffset(imageOutput, ifdPointer);
imageOutput.seek(nextIFDPointerOffset);
}
imageOutput.writeInt(0); // Update next IFD pointer later
tiffWriter.writeOffset(imageOutput, 0); // Update next IFD pointer later
}
else {
imageOutput.writeInt(0); // Update current IFD pointer later
tiffWriter.writeOffset(imageOutput, 0); // Update current IFD pointer later
}
long stripOffset = imageOutput.getStreamPosition();
@@ -260,7 +260,7 @@ public final class TIFFImageWriter extends ImageWriterBase {
entries.put(TIFF.TAG_STRIP_OFFSETS, new TIFFEntry(TIFF.TAG_STRIP_OFFSETS, TIFF.TYPE_LONG, stripOffset));
entries.put(TIFF.TAG_STRIP_BYTE_COUNTS, new TIFFEntry(TIFF.TAG_STRIP_BYTE_COUNTS, TIFF.TYPE_LONG, stripByteCount));
long ifdPointer = tiffWriter.writeIFD(entries.values(), imageOutput); // NOTE: Writer takes case of ordering tags
long ifdPointer = tiffWriter.writeIFD(entries.values(), imageOutput); // NOTE: Writer takes care of ordering tags
nextIFDPointerOffset = imageOutput.getStreamPosition();
@@ -268,10 +268,10 @@ public final class TIFFImageWriter extends ImageWriterBase {
// However, need to update here, because to the writeIFD method writes the pointer, but at the incorrect offset
// TODO: Refactor writeIFD to take an offset
imageOutput.seek(lastIFDPointerOffset);
imageOutput.writeInt((int) ifdPointer);
tiffWriter.writeOffset(imageOutput, ifdPointer);
imageOutput.seek(nextIFDPointerOffset);
imageOutput.writeInt(0); // Next IFD pointer updated later
tiffWriter.writeOffset(imageOutput, 0); // Next IFD pointer updated later
}
return nextIFDPointerOffset;
@@ -955,7 +955,7 @@ public final class TIFFImageWriter extends ImageWriterBase {
configureStreamByteOrder(streamMetadata, imageOutput);
writingSequence = true;
sequenceTIFFWriter = new TIFFWriter();
sequenceTIFFWriter = new TIFFWriter("bigtiff".equalsIgnoreCase(getFormatName()) ? 8 : 4);
sequenceTIFFWriter.writeTIFFHeader(imageOutput);
sequenceLastIFDPos = imageOutput.getStreamPosition();
}
@@ -1015,8 +1015,7 @@ public final class TIFFImageWriter extends ImageWriterBase {
BufferedImage original;
// BufferedImage original = ImageIO.read(file);
ImageInputStream inputStream = ImageIO.createImageInputStream(file);
try {
try (ImageInputStream inputStream = ImageIO.createImageInputStream(file)) {
Iterator<ImageReader> readers = ImageIO.getImageReaders(inputStream);
if (!readers.hasNext()) {
@@ -1046,9 +1045,6 @@ public final class TIFFImageWriter extends ImageWriterBase {
original = reader.read(0, param);
}
finally {
inputStream.close();
}
System.err.println("original: " + original);
@@ -1084,12 +1080,11 @@ public final class TIFFImageWriter extends ImageWriterBase {
// output.deleteOnExit();
System.err.println("output: " + output);
TIFFImageWriter writer = new TIFFImageWriter(null);
TIFFImageWriter writer = new TIFFImageWriter(new TIFFImageWriterSpi());
// ImageWriter writer = ImageIO.getImageWritersByFormatName("PNG").next();
// ImageWriter writer = ImageIO.getImageWritersByFormatName("BMP").next();
ImageOutputStream stream = ImageIO.createImageOutputStream(output);
try {
try (ImageOutputStream stream = ImageIO.createImageOutputStream(output)) {
writer.setOutput(stream);
ImageWriteParam param = writer.getDefaultWriteParam();
@@ -1107,9 +1102,6 @@ public final class TIFFImageWriter extends ImageWriterBase {
writer.write(null, new IIOImage(image, null, null), param);
System.err.println("Write time: " + (System.currentTimeMillis() - start) + " ms");
}
finally {
stream.close();
}
System.err.println("output.length: " + output.length());
@@ -1 +1,2 @@
com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriterSpi
com.twelvemonkeys.imageio.plugins.tiff.BigTIFFImageWriterSpi