diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFF.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFF.java index 539a2e12..7c98b079 100644 --- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFF.java +++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFF.java @@ -41,6 +41,7 @@ public interface TIFF { short BYTE_ORDER_MARK_LITTLE_ENDIAN = ('I' << 8) | 'I'; int TIFF_MAGIC = 42; + int BIGTIFF_MAGIC = 43; short TYPE_BYTE = 1; short TYPE_ASCII = 2; @@ -56,6 +57,10 @@ public interface TIFF { short TYPE_FLOAT = 11; short TYPE_DOUBLE = 12; short TYPE_IFD = 13; + // BigTIFF + short TYPE_LONG8 = 16; + short TYPE_SLONG8 = 17; + short TYPE_IFD8 = 18; /* 1 = BYTE 8-bit unsigned integer. 2 = ASCII 8-bit byte that contains a 7-bit ASCII code; the last byte diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFEntry.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFEntry.java index 9e71055f..0577c8a1 100644 --- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFEntry.java +++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFEntry.java @@ -387,7 +387,7 @@ public final class TIFFEntry extends AbstractEntry { throw new UnsupportedOperationException(String.format("Method guessType not implemented for type %s", value.getClass())); } - static int getValueLength(final int pType, final int pCount) { + static long getValueLength(final int pType, final long pCount) { if (pType > 0 && pType < TIFF.TYPE_LENGTHS.length) { return TIFF.TYPE_LENGTHS[pType] * pCount; } diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFReader.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFReader.java index cda9f231..18ceaf34 100644 --- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFReader.java +++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFReader.java @@ -59,6 +59,8 @@ public final class TIFFReader extends MetadataReader { final static boolean DEBUG = "true".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.imageio.metadata.exif.debug")); static final Collection KNOWN_IFDS = Collections.unmodifiableCollection(Arrays.asList(TIFF.TAG_EXIF_IFD, TIFF.TAG_GPS_IFD, TIFF.TAG_INTEROP_IFD, TIFF.TAG_SUB_IFD)); + private boolean longOffsets; + private int offsetSize; @Override public Directory read(final ImageInputStream input) throws IOException { @@ -77,18 +79,41 @@ public final class TIFFReader extends MetadataReader { throw new IIOException(String.format("Invalid TIFF byte order mark '%s', expected: 'II' or 'MM'", StringUtil.decode(bom, 0, bom.length, "ASCII"))); } - // TODO: BigTiff uses version 43 instead of TIFF's 42, and header is slightly different, see + // BigTiff uses version 43 instead of TIFF's 42, and header is slightly different, see // http://www.awaresystems.be/imaging/tiff/bigtiff.html int magic = input.readUnsignedShort(); - if (magic != TIFF.TIFF_MAGIC) { - throw new IIOException(String.format("Wrong TIFF magic in EXIF data: %04x, expected: %04x", magic, TIFF.TIFF_MAGIC)); + if (magic == TIFF.TIFF_MAGIC) { + longOffsets = false; + offsetSize = 4; + } + else if (magic == TIFF.BIGTIFF_MAGIC) { + longOffsets = true; + offsetSize = 8; + + // Just validate we're ok + int offsetSize = input.readUnsignedShort(); + if (offsetSize != 8) { + throw new IIOException(String.format("Unexpected BigTIFF offset size: %04x, expected: %04x", offsetSize, 8)); + } + + int padding = input.readUnsignedShort(); + if (padding != 0) { + throw new IIOException(String.format("Unexpected BigTIFF padding: %04x, expected: %04x", padding, 0)); + } + } + else { + throw new IIOException(String.format("Wrong TIFF magic in input data: %04x, expected: %04x", magic, TIFF.TIFF_MAGIC)); } - long directoryOffset = input.readUnsignedInt(); + long directoryOffset = readOffset(input); return readDirectory(input, directoryOffset, true); } + private long readOffset(final ImageInputStream input) throws IOException { + return longOffsets ? input.readLong() : input.readUnsignedInt(); + } + // TODO: Consider re-writing so that the linked IFD parsing is done externally to the method protected Directory readDirectory(final ImageInputStream pInput, final long pOffset, final boolean readLinked) throws IOException { List ifds = new ArrayList<>(); @@ -97,14 +122,7 @@ public final class TIFFReader extends MetadataReader { pInput.seek(pOffset); long nextOffset = -1; - int entryCount; - try { - entryCount = pInput.readUnsignedShort(); - } - catch (EOFException e) { - // Treat EOF here as empty Sub-IFD - entryCount = 0; - } + long entryCount = readEntryCount(pInput); for (int i = 0; i < entryCount; i++) { try { @@ -122,7 +140,7 @@ public final class TIFFReader extends MetadataReader { if (readLinked) { if (nextOffset == -1) { try { - nextOffset = pInput.readUnsignedInt(); + nextOffset = readOffset(pInput); } catch (EOFException e) { // catch EOF here as missing EOF marker @@ -150,6 +168,16 @@ public final class TIFFReader extends MetadataReader { return new TIFFDirectory(ifds); } + private long readEntryCount(final ImageInputStream pInput) throws IOException { + try { + return longOffsets ? pInput.readLong() : pInput.readUnsignedShort(); + } + catch (EOFException e) { + // Treat EOF here as empty Sub-IFD + return 0; + } + } + // TODO: Might be better to leave this for client code, as it's tempting go really overboard and support any possible embedded format.. private void readSubdirectories(ImageInputStream input, List entries, List subIFDIds) throws IOException { if (subIFDIds == null || subIFDIds.isEmpty()) { @@ -215,31 +243,27 @@ public final class TIFFReader extends MetadataReader { offsets = (long[]) value; } else { - throw new IIOException(String.format("Unknown pointer type: %s", (value != null - ? value.getClass() - : null))); + throw new IIOException(String.format("Unknown pointer type: %s", value != null ? value.getClass() : null)); } return offsets; } private TIFFEntry readEntry(final ImageInputStream pInput) throws IOException { - // TODO: BigTiff entries are different int tagId = pInput.readUnsignedShort(); short type = pInput.readShort(); - - int count = pInput.readInt(); // Number of values + int count = readValueCount(pInput); // Number of values // It's probably a spec violation to have count 0, but we'll be lenient about it if (count < 0) { throw new IIOException(String.format("Illegal count %d for tag %s type %s @%08x", count, tagId, type, pInput.getStreamPosition())); } - if (type <= 0 || type > 13) { + if (!isValidType(type)) { pInput.skipBytes(4); // read Value // Invalid tag, this is just for debugging - long offset = pInput.getStreamPosition() - 12l; + long offset = pInput.getStreamPosition() - 12L; if (DEBUG) { System.err.printf("Bad EXIF data @%08x\n", pInput.getStreamPosition()); @@ -266,22 +290,37 @@ public final class TIFFReader extends MetadataReader { return null; } - int valueLength = getValueLength(type, count); + long valueLength = getValueLength(type, count); Object value; - // TODO: For BigTiff allow size > 4 && <= 8 in addition - if (valueLength > 0 && valueLength <= 4) { + if (valueLength > 0 && valueLength <= offsetSize) { value = readValueInLine(pInput, type, count); - pInput.skipBytes(4 - valueLength); + pInput.skipBytes(offsetSize - valueLength); } else { - long valueOffset = pInput.readUnsignedInt(); // This is the *value* iff the value size is <= 4 bytes + long valueOffset = readOffset(pInput); // This is the *value* iff the value size is <= 4 bytes value = readValueAt(pInput, valueOffset, type, count); } return new TIFFEntry(tagId, type, value); } + private boolean isValidType(final short type) { + return type > 0 && type < TIFF.TYPE_LENGTHS.length && TIFF.TYPE_LENGTHS[type] > 0; + } + + private int readValueCount(final ImageInputStream pInput) throws IOException { + return assertIntCount(longOffsets ? pInput.readLong() : pInput.readUnsignedInt()); + } + + private int assertIntCount(final long count) throws IOException { + if (count > Integer.MAX_VALUE) { + throw new IIOException(String.format("Unsupported TIFF value count value: %s > Integer.MAX_VALUE", count)); + } + + return (int) count; + } + private Object readValueAt(final ImageInputStream pInput, final long pOffset, final short pType, final int pCount) throws IOException { long pos = pInput.getStreamPosition(); try { @@ -423,16 +462,17 @@ public final class TIFFReader extends MetadataReader { return srationals; // BigTiff: - case 16: // LONG8 - case 17: // SLONG8 - case 18: // IFD8 + case TIFF.TYPE_LONG8: + case TIFF.TYPE_SLONG8: + case TIFF.TYPE_IFD8: // TODO: Assert BigTiff (version == 43) if (pCount == 1) { long val = pInput.readLong(); - if (pType != 17 && val < 0) { + if (pType != TIFF.TYPE_SLONG8 && val < 0) { throw new IIOException(String.format("Value > %s", Long.MAX_VALUE)); } + return val; } @@ -459,6 +499,17 @@ public final class TIFFReader extends MetadataReader { } public static void main(String[] args) throws IOException { +// if (true) { +// ImageInputStream stream = ImageIO.createImageInputStream(new File(args[0])); +// +// byte[] b = new byte[Math.min((int) stream.length(), 1024)]; +// stream.readFully(b); +// +// System.err.println(HexDump.dump(b)); +// +// return; +// } +// TIFFReader reader = new TIFFReader(); ImageInputStream stream = ImageIO.createImageInputStream(new File(args[0])); diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFWriter.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFWriter.java index f814379d..57e686e4 100644 --- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFWriter.java +++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/tiff/TIFFWriter.java @@ -163,15 +163,11 @@ public final class TIFFWriter extends MetadataWriter { return WORD_LENGTH + computeDataSize(new IFD(directory)) + directory.size() * ENTRY_LENGTH; } - public long computeIFDOffsetSize(final Collection directory) { - return computeDataSize(new IFD(directory)) + LONGWORD_LENGTH; - } - private long computeDataSize(final Directory directory) { long dataSize = 0; for (Entry entry : directory) { - int length = getValueLength(getType(entry), getCount(entry)); + long length = getValueLength(getType(entry), getCount(entry)); if (length < 0) { throw new IllegalArgumentException(String.format("Unknown size for entry %s", entry)); @@ -229,13 +225,13 @@ public final class TIFFWriter extends MetadataWriter { private long writeValue(final Entry entry, final long dataOffset, final ImageOutputStream stream) throws IOException { short type = getType(entry); - int valueLength = getValueLength(type, getCount(entry)); + long valueLength = getValueLength(type, getCount(entry)); if (valueLength <= LONGWORD_LENGTH) { writeValueInline(entry.getValue(), type, stream); // Pad - for (int i = valueLength; i < LONGWORD_LENGTH; i++) { + for (long i = valueLength; i < LONGWORD_LENGTH; i++) { stream.write(0); } diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/BigTIFFImageReaderSpi.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/BigTIFFImageReaderSpi.java new file mode 100644 index 00000000..d46564da --- /dev/null +++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/BigTIFFImageReaderSpi.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012, 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 "TwelveMonkeys" 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 OWNER 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.metadata.tiff.TIFF; +import com.twelvemonkeys.imageio.spi.ImageReaderSpiBase; + +import java.io.IOException; +import java.util.Locale; + +/** + * BigTIFFImageReaderSpi. + *

+ * This is a separate service provider for the BigTIFF format, to support + * special cases where one does not want BigTIFF support. + * + * @author Harald Kuhr + * @author last modified by $Author: haraldk$ + * @version $Id: BigTIFFImageReaderSpi.java,v 1.0 08.05.12 15:14 haraldk Exp$ + */ +public final class BigTIFFImageReaderSpi extends ImageReaderSpiBase { + /** + * Creates a {@code BigTIFFImageReaderSpi}. + */ + public BigTIFFImageReaderSpi() { + super(new BigTIFFProviderInfo()); + } + + public boolean canDecodeInput(final Object pSource) throws IOException { + return TIFFImageReaderSpi.canDecodeAs(pSource, TIFF.BIGTIFF_MAGIC); + } + + public TIFFImageReader createReaderInstance(final Object pExtension) { + return new TIFFImageReader(this); + } + + public String getDescription(final Locale pLocale) { + return "BigTIFF image reader"; + } +} diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/BigTIFFProviderInfo.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/BigTIFFProviderInfo.java new file mode 100644 index 00000000..94c9b9de --- /dev/null +++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/BigTIFFProviderInfo.java @@ -0,0 +1,29 @@ +package com.twelvemonkeys.imageio.plugins.tiff; + +import com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfo; + +/** + * BigTIFFProviderInfo. + * + * @author Harald Kuhr + * @author last modified by $Author: harald.kuhr$ + * @version $Id: BigTIFFProviderInfo.java,v 1.0 26/04/2017 harald.kuhr Exp$ + */ +final class BigTIFFProviderInfo extends ReaderWriterProviderInfo { + protected BigTIFFProviderInfo() { + super( + BigTIFFProviderInfo.class, + new String[] {"bigtiff", "BigTIFF", "BIGTIFF"}, + new String[] {"tif", "tiff", "btf", "tf8", "btiff"}, + new String[] { + "image/tiff", "image/x-tiff" + }, + "com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReader", + new String[] {"com.twelvemonkeys.imageio.plugins.tiff.BigTIFFImageReaderSpi"}, + null, + null, + 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 + ); + } +} diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java index dd661065..26c3af99 100755 --- a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java +++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java @@ -157,7 +157,7 @@ public final class TIFFImageReader extends ImageReaderBase { private CompoundDirectory IFDs; private Directory currentIFD; - TIFFImageReader(final TIFFImageReaderSpi provider) { + TIFFImageReader(final ImageReaderSpi provider) { super(provider); } diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderSpi.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderSpi.java index d763d2cf..e41be3cd 100644 --- a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderSpi.java +++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderSpi.java @@ -71,6 +71,10 @@ public final class TIFFImageReaderSpi extends ImageReaderSpiBase { } public boolean canDecodeInput(final Object pSource) throws IOException { + return canDecodeAs(pSource, TIFF.TIFF_MAGIC); + } + + static boolean canDecodeAs(final Object pSource, final int magic) throws IOException { if (!(pSource instanceof ImageInputStream)) { return false; } @@ -95,11 +99,7 @@ public final class TIFFImageReaderSpi extends ImageReaderSpiBase { return false; } - // TODO: BigTiff uses version 43 instead of TIFF's 42, and header is slightly different, see - // http://www.awaresystems.be/imaging/tiff/bigtiff.html - int magic = stream.readUnsignedShort(); - - return magic == TIFF.TIFF_MAGIC; + return stream.readUnsignedShort() == magic; } finally { stream.setByteOrder(originalOrder); diff --git a/imageio/imageio-tiff/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi b/imageio/imageio-tiff/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi index be0208a5..8f80ce50 100755 --- a/imageio/imageio-tiff/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi +++ b/imageio/imageio-tiff/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi @@ -1 +1,2 @@ com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi +com.twelvemonkeys.imageio.plugins.tiff.BigTIFFImageReaderSpi diff --git a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/BigTIFFImageReaderTest.java b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/BigTIFFImageReaderTest.java new file mode 100644 index 00000000..02c44101 --- /dev/null +++ b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/BigTIFFImageReaderTest.java @@ -0,0 +1,68 @@ +package com.twelvemonkeys.imageio.plugins.tiff; + +import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest; + +import javax.imageio.spi.ImageReaderSpi; +import java.awt.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * BigTIFFImageReaderTest. + * + * @author Harald Kuhr + * @author last modified by $Author: harald.kuhr$ + * @version $Id: BigTIFFImageReaderTest.java,v 1.0 26/04/2017 harald.kuhr Exp$ + */ +public class BigTIFFImageReaderTest extends ImageReaderAbstractTest { + private static final BigTIFFImageReaderSpi SPI = new BigTIFFImageReaderSpi(); + + @Override + protected List getTestData() { + return Arrays.asList( + new TestData(getClassLoaderResource("/bigtiff/BigTIFF.tif"), new Dimension(64, 64)), + new TestData(getClassLoaderResource("/bigtiff/BigTIFFMotorola.tif"), new Dimension(64, 64)), + new TestData(getClassLoaderResource("/bigtiff/BigTIFFLong.tif"), new Dimension(64, 64)), + new TestData(getClassLoaderResource("/bigtiff/BigTIFFLong8.tif"), new Dimension(64, 64)), + new TestData(getClassLoaderResource("/bigtiff/BigTIFFMotorolaLongStrips.tif"), new Dimension(64, 64)), + new TestData(getClassLoaderResource("/bigtiff/BigTIFFLong8Tiles.tif"), new Dimension(64, 64)), + new TestData(getClassLoaderResource("/bigtiff/BigTIFFSubIFD4.tif"), new Dimension(64, 64)), + new TestData(getClassLoaderResource("/bigtiff/BigTIFFSubIFD8.tif"), new Dimension(64, 64)) + ); + } + + @Override + protected ImageReaderSpi createProvider() { + return SPI; + } + + @Override + protected Class getReaderClass() { + return TIFFImageReader.class; + } + + @Override + protected TIFFImageReader createReader() { + return SPI.createReaderInstance(null); + } + + @Override + protected List getFormatNames() { + return Arrays.asList("bigtiff", "BigTIFF", "BIGTIFF"); + } + + @Override + protected List getSuffixes() { + return Arrays.asList("tif", "tiff", "btf", "tf8"); + } + + @Override + protected List getMIMETypes() { + return Collections.singletonList("image/tiff"); + } + + // TODO: Test that all BigTIFFs are decoded equal to the classic TIFF + + // TODO: Test metadata +} diff --git a/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFF.tif b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFF.tif new file mode 100755 index 00000000..8a0e5a24 Binary files /dev/null and b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFF.tif differ diff --git a/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFLong.tif b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFLong.tif new file mode 100755 index 00000000..1a321ef1 Binary files /dev/null and b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFLong.tif differ diff --git a/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFLong8.tif b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFLong8.tif new file mode 100755 index 00000000..d11d5f13 Binary files /dev/null and b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFLong8.tif differ diff --git a/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFLong8Tiles.tif b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFLong8Tiles.tif new file mode 100755 index 00000000..125bbb9f Binary files /dev/null and b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFLong8Tiles.tif differ diff --git a/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFMotorola.tif b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFMotorola.tif new file mode 100755 index 00000000..4699ecd7 Binary files /dev/null and b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFMotorola.tif differ diff --git a/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFMotorolaLongStrips.tif b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFMotorolaLongStrips.tif new file mode 100755 index 00000000..7111421a Binary files /dev/null and b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFMotorolaLongStrips.tif differ diff --git a/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFSamples.html b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFSamples.html new file mode 100755 index 00000000..c674e57b --- /dev/null +++ b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFSamples.html @@ -0,0 +1,239 @@ + + + + +

+ These images were created by AWare Systems. +

+

Index

+

+ Classic.tif
+ BigTIFF.tif
+ BigTIFFMotorola.tif
+ BigTIFFLong.tif
+ BigTIFFLong8.tif
+ BigTIFFMotorolaLongStrips.tif
+ BigTIFFLong8Tiles.tif
+ BigTIFFSubIFD4.tif
+ BigTIFFSubIFD8.tif
+

+

Classic.tif

+

+ Classic.tif is a basic Classic TIFF file. All files in this package have the same actual image content, + so this TIFF file serves as a reference. +

+

+ Format: Classic TIFF
+ Byte Order: Intel
+ Ifd Offset: 12302
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 8
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 64
+     StripByteCounts (1 Short): 12288
+

+

BigTIFF.tif

+

+ BigTIFF.tif ressembles Classic.tif as close as possible. Except that it's a BigTIFF, that is... +

+

+ Format: BigTIFF
+ Byte Order: Intel
+ Ifd Offset: 12304
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 16
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 64
+     StripByteCounts (1 Short): 12288
+

+

BigTIFFMotorola.tif

+

+ BigTIFFMotorola.tif reverses the byte order. +

+

+ Format: BigTIFF
+ Byte Order: Motorola
+ Ifd Offset: 12304
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 16
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 64
+     StripByteCounts (1 Short): 12288
+

+

BigTIFFLong.tif

+

+ All previous TIFFs specify DataType Short for StripOffsets and StripByteCounts tags. This BigTIFF instead specifies DataType Long, for these tags. +

+

+ Format: BigTIFF
+ Byte Order: Intel
+ Ifd Offset: 12304
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Long): 16
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 64
+     StripByteCounts (1 Long): 12288
+

+

BigTIFFLong8.tif

+

+ This next one specifies DataType Long8, for StripOffsets and StripByteCounts tags. +

+

+ Format: BigTIFF
+ Byte Order: Intel
+ Ifd Offset: 12304
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Long8): 16
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 64
+     StripByteCounts (1 Long8): 12288
+

+

BigTIFFMotorolaLongStrips.tif

+

+ This BigTIFF has Motorola byte order, plus, it's divided over two strips. StripOffsets and StripByteCounts tags have DataType Long, so their actual value fits inside the IFD. +

+

+ Format: BigTIFF
+ Byte Order: Motorola
+ Ifd Offset: 12304
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (2 Long): 16, 6160
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 32
+     StripByteCounts (2 Long): 6144, 6144
+

+

BigTIFFLong8Tiles.tif

+

+ BigTIFFLong8Tiles.tif is a tiled BigTIFF. TileOffsets and TileByteCounts tags specify DataType Long8. +

+

+ Format: BigTIFF
+ Byte Order: Intel
+ Ifd Offset: 12368
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     SamplesPerPixel (1 Short): 3
+     TileWidth (1 Short): 32
+     TileLength (1 Short): 32
+     TileOffsets (4 Long8): 16, 3088, 6160, 9232
+     TileByteCounts (4 Long8): 3072, 3072, 3072, 3072
+

+

BigTIFFSubIFD4.tif

+

+ This BigTIFF contains two pages, the second page showing almost the same image content as the first, except that the black square is white, and text color is black. + Both pages point to a downsample SubIFD, using SubIFDs DataType TIFF_IFD. +

+

+ Format: BigTIFF
+ Byte Order: Intel
+ Ifd Offset: 15572
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 3284
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 64
+     StripByteCounts (1 Short): 12288
+     SubIFDs (1 IFD): 3088
+ SubIfd Offset: 3088
+     NewSubFileType (1 Long): 1
+     ImageWidth (1 Short): 32
+     ImageLength (1 Short): 32
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 16
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 32
+     StripByteCounts (1 Short): 3072
+ Ifd Offset: 31324
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 19036
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 64
+     StripByteCounts (1 Short): 12288
+     SubIFDs (1 IFD): 18840
+ SubIfd Offset: 18840
+     NewSubFileType (1 Long): 1
+     ImageWidth (1 Short): 32
+     ImageLength (1 Short): 32
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 15768
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 32
+     StripByteCounts (1 Short): 3072
+

+

BigTIFFSubIFD8.tif

+

+ BigTIFFSubIFD4.tif is very much the same as BigTIFFSubIFD4.tif, except that the new DataType TIFF_IFD8 is used for the SubIFDs tag. +

+

+ Format: BigTIFF
+ Byte Order: Intel
+ Ifd Offset: 15572
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 3284
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 64
+     StripByteCounts (1 Short): 12288
+     SubIFDs (1 IFD8): 3088
+ SubIfd Offset: 3088
+     NewSubFileType (1 Long): 1
+     ImageWidth (1 Short): 32
+     ImageLength (1 Short): 32
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 16
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 32
+     StripByteCounts (1 Short): 3072
+ Ifd Offset: 31324
+     ImageWidth (1 Short): 64
+     ImageLength (1 Short): 64
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 19036
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 64
+     StripByteCounts (1 Short): 12288
+     SubIFDs (1 IFD8): 18840
+ SubIfd Offset: 18840
+     NewSubFileType (1 Long): 1
+     ImageWidth (1 Short): 32
+     ImageLength (1 Short): 32
+     BitsPerSample (3 Short): 8, 8, 8
+     PhotometricInterpretation (1 Short): RGB
+     StripOffsets (1 Short): 15768
+     SamplesPerPixel (1 Short): 3
+     RowsPerStrip (1 Short): 32
+     StripByteCounts (1 Short): 3072
+

+ + diff --git a/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFSubIFD4.tif b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFSubIFD4.tif new file mode 100755 index 00000000..9b30d42e Binary files /dev/null and b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFSubIFD4.tif differ diff --git a/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFSubIFD8.tif b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFSubIFD8.tif new file mode 100755 index 00000000..409953a2 Binary files /dev/null and b/imageio/imageio-tiff/src/test/resources/bigtiff/BigTIFFSubIFD8.tif differ diff --git a/imageio/imageio-tiff/src/test/resources/bigtiff/Classic.tif b/imageio/imageio-tiff/src/test/resources/bigtiff/Classic.tif new file mode 100755 index 00000000..844d1737 Binary files /dev/null and b/imageio/imageio-tiff/src/test/resources/bigtiff/Classic.tif differ