diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFEntry.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFEntry.java index 3fcfadf8..fe51a31d 100644 --- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFEntry.java +++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFEntry.java @@ -38,13 +38,14 @@ import com.twelvemonkeys.imageio.metadata.AbstractEntry; * @version $Id: EXIFEntry.java,v 1.0 Nov 13, 2009 5:47:35 PM haraldk Exp$ */ final class EXIFEntry extends AbstractEntry { + // TODO: Expose as TIFFEntry final private short type; EXIFEntry(final int identifier, final Object value, final short type) { super(identifier, value); if (type < 1 || type >= TIFF.TYPE_NAMES.length) { - throw new IllegalArgumentException(String.format("Illegal EXIF type: %s", type)); + throw new IllegalArgumentException(String.format("Illegal TIFF type: %s", type)); } // TODO: Validate that type is applicable to value? @@ -114,6 +115,8 @@ final class EXIFEntry extends AbstractEntry { return "PlanarConfiguration"; case TIFF.TAG_RESOLUTION_UNIT: return "ResolutionUnit"; + case TIFF.TAG_PAGE_NAME: + return "PageName"; case TIFF.TAG_PAGE_NUMBER: return "PageNumber"; case TIFF.TAG_SOFTWARE: @@ -228,6 +231,8 @@ final class EXIFEntry extends AbstractEntry { return "DateTimeDigitized"; case EXIF.TAG_IMAGE_NUMBER: return "ImageNumber"; + case EXIF.TAG_MAKER_NOTE: + return "MakerNote"; case EXIF.TAG_USER_COMMENT: return "UserComment"; diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFWriter.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFWriter.java index 66892cb1..9f0881f5 100644 --- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFWriter.java +++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFWriter.java @@ -40,6 +40,7 @@ import java.io.IOException; import java.lang.reflect.Array; import java.nio.ByteOrder; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.*; /** @@ -248,9 +249,12 @@ public final class EXIFWriter extends MetadataWriter { switch (type) { case TIFF.TYPE_UNDEFINED: case TIFF.TYPE_BYTE: + case TIFF.TYPE_SBYTE: stream.write((byte[]) value); break; + case TIFF.TYPE_SHORT: + case TIFF.TYPE_SSHORT: short[] shorts; if (value instanceof short[]) { @@ -279,7 +283,9 @@ public final class EXIFWriter extends MetadataWriter { stream.writeShorts(shorts, 0, shorts.length); break; + case TIFF.TYPE_LONG: + case TIFF.TYPE_SLONG: int[] ints; if (value instanceof int[]) { @@ -298,17 +304,45 @@ public final class EXIFWriter extends MetadataWriter { } stream.writeInts(ints, 0, ints.length); - break; case TIFF.TYPE_RATIONAL: + case TIFF.TYPE_SRATIONAL: Rational[] rationals = (Rational[]) value; for (Rational rational : rationals) { stream.writeInt((int) rational.numerator()); stream.writeInt((int) rational.denominator()); } - // TODO: More types + break; + + case TIFF.TYPE_FLOAT: + float[] floats; + + if (value instanceof float[]) { + floats = (float[]) value; + } + else { + throw new IllegalArgumentException("Unsupported type for TIFF FLOAT: " + value.getClass()); + } + + stream.writeFloats(floats, 0, floats.length); + + break; + + case TIFF.TYPE_DOUBLE: + double[] doubles; + + if (value instanceof double[]) { + doubles = (double[]) value; + } + else { + throw new IllegalArgumentException("Unsupported type for TIFF FLOAT: " + value.getClass()); + } + + stream.writeDoubles(doubles, 0, doubles.length); + + break; default: throw new IllegalArgumentException("Unsupported TIFF type: " + type); @@ -319,27 +353,36 @@ public final class EXIFWriter extends MetadataWriter { // } else { switch (type) { - case TIFF.TYPE_UNDEFINED: case TIFF.TYPE_BYTE: - stream.writeByte((Integer) value); + case TIFF.TYPE_SBYTE: + case TIFF.TYPE_UNDEFINED: + stream.writeByte(((Number) value).intValue()); break; case TIFF.TYPE_ASCII: - byte[] bytes = ((String) value).getBytes(Charset.forName("UTF-8")); + byte[] bytes = ((String) value).getBytes(StandardCharsets.UTF_8); stream.write(bytes); stream.write(0); break; case TIFF.TYPE_SHORT: - stream.writeShort((Integer) value); + case TIFF.TYPE_SSHORT: + stream.writeShort(((Number) value).intValue()); break; case TIFF.TYPE_LONG: + case TIFF.TYPE_SLONG: stream.writeInt(((Number) value).intValue()); break; case TIFF.TYPE_RATIONAL: + case TIFF.TYPE_SRATIONAL: Rational rational = (Rational) value; stream.writeInt((int) rational.numerator()); stream.writeInt((int) rational.denominator()); break; - // TODO: More types + case TIFF.TYPE_FLOAT: + stream.writeFloat(((Number) value).floatValue()); + break; + case TIFF.TYPE_DOUBLE: + stream.writeDouble(((Number) value).doubleValue()); + break; default: throw new IllegalArgumentException("Unsupported TIFF type: " + type); @@ -356,11 +399,26 @@ public final class EXIFWriter extends MetadataWriter { } private short getType(final Entry entry) { + // TODO: What a MESS! Rewrite and expose EXIFEntry as TIFFEntry or so... + + // For internal entries use type directly if (entry instanceof EXIFEntry) { EXIFEntry exifEntry = (EXIFEntry) entry; return exifEntry.getType(); } + // For other entries, use name if it matches + String typeName = entry.getTypeName(); + + if (typeName != null) { + for (int i = 1; i < TIFF.TYPE_NAMES.length; i++) { + if (typeName.equals(TIFF.TYPE_NAMES[i])) { + return (short) i; + } + } + } + + // Otherwise, fall back to the native Java type Object value = Validate.notNull(entry.getValue()); boolean array = value.getClass().isArray(); diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/TIFF.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/TIFF.java index 606b0849..aeca1fd0 100644 --- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/TIFF.java +++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/TIFF.java @@ -95,6 +95,7 @@ public interface TIFF { null, null, "LONG8", "SLONG8", "IFD8" }; + /** Length of the corresponding type, in bytes. */ int[] TYPE_LENGTHS = { -1, 1, 1, 2, 4, 8, @@ -165,6 +166,7 @@ public interface TIFF { int TAG_IMAGE_DESCRIPTION = 270; int TAG_MAKE = 271; int TAG_MODEL = 272; + int TAG_PAGE_NAME = 285; int TAG_PAGE_NUMBER = 297; int TAG_SOFTWARE = 305; int TAG_ARTIST = 315;