Support merging and splitting of tiled TIFF pages

This commit is contained in:
Oliver Schmidtmer 2017-06-13 16:55:55 +02:00
parent 3e43841e85
commit b30d454bf0

View File

@ -326,9 +326,6 @@ public final class TIFFUtilities {
} }
private List<Entry> writeDirectoryData(Directory IFD, ImageOutputStream outputStream) throws IOException { private List<Entry> writeDirectoryData(Directory IFD, ImageOutputStream outputStream) throws IOException {
//TODO support tiles
Validate.isTrue(IFD.getEntryById(TIFF.TAG_TILE_BYTE_COUNTS) == null, "Tiled TIFFs are not supported");
Validate.isTrue(IFD.getEntryById(TIFF.TAG_TILE_OFFSETS) == null, "Tiled TIFFs are not supported");
ArrayList<Entry> newIFD = new ArrayList<Entry>(); ArrayList<Entry> newIFD = new ArrayList<Entry>();
Iterator<Entry> it = IFD.iterator(); Iterator<Entry> it = IFD.iterator();
@ -346,13 +343,22 @@ public final class TIFFUtilities {
long[] offsets = new long[0]; long[] offsets = new long[0];
long[] byteCounts = new long[0]; long[] byteCounts = new long[0];
int[] newOffsets = new int[0]; int[] newOffsets = new int[0];
boolean useTiles = false;
Entry stripOffsetsEntry = IFD.getEntryById(TIFF.TAG_STRIP_OFFSETS); Entry stripOffsetsEntry = IFD.getEntryById(TIFF.TAG_STRIP_OFFSETS);
Entry stripByteCountsEntry = IFD.getEntryById(TIFF.TAG_STRIP_BYTE_COUNTS); Entry stripByteCountsEntry = IFD.getEntryById(TIFF.TAG_STRIP_BYTE_COUNTS);
if (stripOffsetsEntry != null && stripByteCountsEntry != null) { if (stripOffsetsEntry != null && stripByteCountsEntry != null) {
offsets = getValueAsLongArray(stripOffsetsEntry); offsets = getValueAsLongArray(stripOffsetsEntry);
byteCounts = getValueAsLongArray(stripByteCountsEntry); byteCounts = getValueAsLongArray(stripByteCountsEntry);
} }
else {
stripOffsetsEntry = IFD.getEntryById(TIFF.TAG_TILE_OFFSETS);
stripByteCountsEntry = IFD.getEntryById(TIFF.TAG_TILE_BYTE_COUNTS);
if (stripOffsetsEntry != null && stripByteCountsEntry != null) {
offsets = getValueAsLongArray(stripOffsetsEntry);
byteCounts = getValueAsLongArray(stripByteCountsEntry);
useTiles = true;
}
}
boolean rearrangedByteStrips = false; boolean rearrangedByteStrips = false;
Entry oldJpegData = IFD.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT); Entry oldJpegData = IFD.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT);
@ -376,9 +382,9 @@ public final class TIFFUtilities {
writeData(offsets, byteCounts, outputStream); writeData(offsets, byteCounts, outputStream);
newIFD.remove(stripOffsetsEntry); newIFD.remove(stripOffsetsEntry);
newIFD.add(new TIFFEntry(TIFF.TAG_STRIP_OFFSETS, newOffsets)); newIFD.add(new TIFFEntry(useTiles ? TIFF.TAG_TILE_OFFSETS : TIFF.TAG_STRIP_OFFSETS, newOffsets));
newIFD.remove(stripByteCountsEntry); newIFD.remove(stripByteCountsEntry);
newIFD.add(new TIFFEntry(TIFF.TAG_STRIP_BYTE_COUNTS, new int[]{ (int) (jpegByteCounts[0] + byteCounts[0])})); newIFD.add(new TIFFEntry(useTiles ? TIFF.TAG_TILE_BYTE_COUNTS : TIFF.TAG_STRIP_BYTE_COUNTS, new int[]{ (int) (jpegByteCounts[0] + byteCounts[0])}));
newIFD.remove(oldJpegData); newIFD.remove(oldJpegData);
newIFD.remove(oldJpegDataLength); newIFD.remove(oldJpegDataLength);
@ -426,9 +432,9 @@ public final class TIFFUtilities {
} }
newIFD.remove(stripOffsetsEntry); newIFD.remove(stripOffsetsEntry);
newIFD.add(new TIFFEntry(TIFF.TAG_STRIP_OFFSETS, newOffsets)); newIFD.add(new TIFFEntry(useTiles ? TIFF.TAG_TILE_OFFSETS : TIFF.TAG_STRIP_OFFSETS, newOffsets));
newIFD.remove(stripByteCountsEntry); newIFD.remove(stripByteCountsEntry);
newIFD.add(new TIFFEntry(TIFF.TAG_STRIP_BYTE_COUNTS, newByteCounts)); newIFD.add(new TIFFEntry(useTiles ? TIFF.TAG_TILE_BYTE_COUNTS : TIFF.TAG_STRIP_BYTE_COUNTS, newByteCounts));
newIFD.remove(oldJpegData); newIFD.remove(oldJpegData);
newIFD.remove(oldJpegDataLength); newIFD.remove(oldJpegDataLength);
@ -441,7 +447,7 @@ public final class TIFFUtilities {
newOffsets = writeData(offsets, byteCounts, outputStream); newOffsets = writeData(offsets, byteCounts, outputStream);
newIFD.remove(stripOffsetsEntry); newIFD.remove(stripOffsetsEntry);
newIFD.add(new TIFFEntry(TIFF.TAG_STRIP_OFFSETS, newOffsets)); newIFD.add(new TIFFEntry(useTiles ? TIFF.TAG_TILE_OFFSETS : TIFF.TAG_STRIP_OFFSETS, newOffsets));
} }
Validate.isTrue(oldJpegData == null || !newIFD.contains(oldJpegData), "Failed to transform old-style JPEG"); Validate.isTrue(oldJpegData == null || !newIFD.contains(oldJpegData), "Failed to transform old-style JPEG");