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;
}
public long computeIFDOffsetSize(final Collection<Entry> directory) {
return computeDataSize(new IFD(directory)) + LONGWORD_LENGTH;
}
private long computeDataSize(final Directory directory) {
long dataSize = 0;

View File

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