Remove seeks on uncompressed tiffs to reenable streaming

This commit is contained in:
Oliver Schmidtmer 2016-01-28 00:31:10 +01:00
parent e145de01f3
commit e4f193400d
2 changed files with 24 additions and 23 deletions

View File

@ -158,6 +158,10 @@ public final class EXIFWriter extends MetadataWriter {
return WORD_LENGTH + computeDataSize(new IFD(directory)) + directory.size() * ENTRY_LENGTH; return WORD_LENGTH + computeDataSize(new IFD(directory)) + directory.size() * ENTRY_LENGTH;
} }
public long computeIFDOffsetSize(final Collection<Entry> directory) {
return computeDataSize(new IFD(directory)) + LONGWORD_LENGTH;
}
private long computeDataSize(final Directory directory) { private long computeDataSize(final Directory directory) {
long dataSize = 0; long dataSize = 0;

View File

@ -209,9 +209,8 @@ public final class TIFFImageWriter extends ImageWriterBase {
EXIFWriter exifWriter = new EXIFWriter(); EXIFWriter exifWriter = new EXIFWriter();
exifWriter.writeTIFFHeader(imageOutput); exifWriter.writeTIFFHeader(imageOutput);
long IFD0Pos = imageOutput.getStreamPosition(); long IFD0Pos = imageOutput.getStreamPosition();
imageOutput.writeInt(0); // IFD0 pointer, will be updated later
writePage(image, param, exifWriter, IFD0Pos); writePage(image, param, exifWriter, IFD0Pos);
imageOutput.writeInt(0); // EOF
imageOutput.flush(); imageOutput.flush();
} }
@ -363,24 +362,15 @@ public final class TIFFImageWriter extends ImageWriterBase {
long nextIFDPointer = -1; long nextIFDPointer = -1;
long stripOffset = -1; long stripOffset = -1;
long stripByteCount = 0; long stripByteCount = 0;
if (compression == TIFFBaseline.COMPRESSION_NONE) { if (compression == TIFFBaseline.COMPRESSION_NONE) {
// This implementation, allows semi-streaming-compatible uncompressed TIFFs long ifdOffset = exifWriter.computeIFDOffsetSize(entries.values());
long streamOffset = imageOutput.getStreamPosition() + exifWriter.computeIFDSize(entries.values()) + 4; // IFD + 4 byte EOF, (header, ifd0 + n images already written) long dataLength = renderedImage.getWidth() * renderedImage.getHeight() * numComponents;
long pointerPos = imageOutput.getStreamPosition() + dataLength + 4 + ifdOffset;
entries.remove(dummyStripByteCounts); imageOutput.writeInt((int) pointerPos);
entries.put(TIFF.TAG_STRIP_BYTE_COUNTS, new TIFFEntry(TIFF.TAG_STRIP_BYTE_COUNTS, }
renderedImage.getWidth() * renderedImage.getHeight() * numComponents)); else {
entries.remove(dummyStripOffsets); imageOutput.writeInt(0); // Update IFD Pointer later
entries.put(TIFF.TAG_STRIP_OFFSETS, new TIFFEntry(TIFF.TAG_STRIP_OFFSETS, streamOffset));
long idfOffset = exifWriter.writeIFD(entries.values(), imageOutput); // NOTE: Writer takes case of ordering tags
nextIFDPointer = imageOutput.getStreamPosition();
// Update IFD0 pointer
imageOutput.seek(lastIFDPointer);
imageOutput.writeInt((int) idfOffset);
imageOutput.seek(nextIFDPointer);
imageOutput.flush();
imageOutput.writeInt(0); // EOF
} }
stripOffset = imageOutput.getStreamPosition(); stripOffset = imageOutput.getStreamPosition();
@ -418,12 +408,20 @@ public final class TIFFImageWriter extends ImageWriterBase {
long idfOffset = exifWriter.writeIFD(entries.values(), imageOutput); // NOTE: Writer takes case of ordering tags long idfOffset = exifWriter.writeIFD(entries.values(), imageOutput); // NOTE: Writer takes case of ordering tags
nextIFDPointer = imageOutput.getStreamPosition(); nextIFDPointer = imageOutput.getStreamPosition();
// Update IFD0 pointer
imageOutput.seek(lastIFDPointer); imageOutput.seek(lastIFDPointer);
imageOutput.writeInt((int) idfOffset); imageOutput.writeInt((int) idfOffset);
imageOutput.seek(nextIFDPointer); imageOutput.seek(nextIFDPointer);
imageOutput.flush(); imageOutput.flush();
imageOutput.writeInt(0); // EOF }
else {
entries.remove(dummyStripOffsets);
entries.put(TIFF.TAG_STRIP_OFFSETS, new TIFFEntry(TIFF.TAG_STRIP_OFFSETS, stripOffset));
entries.remove(dummyStripByteCounts);
entries.put(TIFF.TAG_STRIP_BYTE_COUNTS, new TIFFEntry(TIFF.TAG_STRIP_BYTE_COUNTS, stripByteCount));
exifWriter.writeIFD(entries.values(), imageOutput); // NOTE: Writer takes case of ordering tags
nextIFDPointer = imageOutput.getStreamPosition();
imageOutput.flush();
} }
return nextIFDPointer; return nextIFDPointer;
@ -882,7 +880,6 @@ public final class TIFFImageWriter extends ImageWriterBase {
sequenceExifWriter = new EXIFWriter(); sequenceExifWriter = new EXIFWriter();
sequenceExifWriter.writeTIFFHeader(imageOutput); sequenceExifWriter.writeTIFFHeader(imageOutput);
sequenceLastIFDPos = imageOutput.getStreamPosition(); sequenceLastIFDPos = imageOutput.getStreamPosition();
imageOutput.writeInt(0); // IFD0
} }
@Override @Override
@ -898,7 +895,7 @@ public final class TIFFImageWriter extends ImageWriterBase {
if (!isWritingSequence) { if (!isWritingSequence) {
throw new IllegalStateException("prepareWriteSequence() must be called before endWriteSequence()!"); throw new IllegalStateException("prepareWriteSequence() must be called before endWriteSequence()!");
} }
imageOutput.writeInt(0); // EOF
isWritingSequence = false; isWritingSequence = false;
sequenceExifWriter = null; sequenceExifWriter = null;
sequenceLastIFDPos = -1; sequenceLastIFDPos = -1;