diff --git a/src/main/java/edu/illinois/library/cantaloupe/image/Metadata.java b/src/main/java/edu/illinois/library/cantaloupe/image/Metadata.java index d744735c2..94e0d73fb 100644 --- a/src/main/java/edu/illinois/library/cantaloupe/image/Metadata.java +++ b/src/main/java/edu/illinois/library/cantaloupe/image/Metadata.java @@ -159,11 +159,16 @@ private void readOrientationFromEXIF() { switch (field.getDataType()) { case LONG: case SLONG: - orientation = Orientation.forEXIFOrientation(Math.toIntExact((long) value)); - break; case SHORT: case SSHORT: - orientation = Orientation.forEXIFOrientation((int) value); + // According to spec the orientation must be an unsigned short (16 bit) + // However, we have seen exif data in the wild with LONG and SLONG types + // Thus to be lenient we accept either and convert to int (github issue #548) + if (value instanceof Long) { + orientation = Orientation.forEXIFOrientation(Math.toIntExact((long) value)); + } else if (value instanceof Integer) { + orientation = Orientation.forEXIFOrientation((int) value); + } break; default: LOGGER.warn("readOrientationFromEXIF(): Unsupported Orientation data type: {}", diff --git a/src/test/java/edu/illinois/library/cantaloupe/image/MetadataTest.java b/src/test/java/edu/illinois/library/cantaloupe/image/MetadataTest.java index 92c69b590..2574d87ec 100644 --- a/src/test/java/edu/illinois/library/cantaloupe/image/MetadataTest.java +++ b/src/test/java/edu/illinois/library/cantaloupe/image/MetadataTest.java @@ -16,11 +16,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.nio.file.FileVisitOption; +import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.*; @@ -230,7 +233,21 @@ void testGetOrientationWithOnlyIllegalEXIFOrientation() throws Exception { } } - @Test + @Test + void testGetOrientationWithOnlyLONGEXIFOrientation() throws Exception { + // This image has exif Orientation stored as SLONG, causing a failure (github issue #548) + Path fixture = TestUtil.getImage("jpg-exif-long-orientation.jpg"); + ImageReader reader = new ImageReaderFactory() + .newImageReader(Format.get("jpg"), fixture); + try { + Metadata metadata = reader.getMetadata(0); + assertEquals(Orientation.ROTATE_0, metadata.getOrientation()); + } finally { + reader.dispose(); + } + } + + @Test void testGetOrientationWithOnlyXMPOrientation() throws Exception { Path fixture = TestUtil.getImage("jpg-xmp-orientation-90.jpg"); ImageReader reader = new ImageReaderFactory() diff --git a/src/test/java/edu/illinois/library/cantaloupe/image/exif/DirectoryTest.java b/src/test/java/edu/illinois/library/cantaloupe/image/exif/DirectoryTest.java index 9624a6c8a..6a740e2d6 100644 --- a/src/test/java/edu/illinois/library/cantaloupe/image/exif/DirectoryTest.java +++ b/src/test/java/edu/illinois/library/cantaloupe/image/exif/DirectoryTest.java @@ -366,7 +366,15 @@ void testGetValueWithoutMatchingValue() { assertNull(ifd.getValue(Tag.MAKE)); } - @Test + @Test + void testGetField() { + final Directory ifd = new Directory(TagSet.BASELINE_TIFF); + ifd.put(Tag.MAKE, DataType.ASCII, "Cats"); + Field field = ifd.getField(Tag.MAKE); + assertEquals(DataType.ASCII, field.getDataType()); + } + + @Test void testHashCodeWithEqualInstances() { final Directory subIFD1 = new Directory(TagSet.EXIF); subIFD1.put(Tag.EXPOSURE_TIME, DataType.RATIONAL, new Rational(1, 160)); diff --git a/src/test/resources/images/jpg-exif-long-orientation.jpg b/src/test/resources/images/jpg-exif-long-orientation.jpg new file mode 100755 index 000000000..8ad6fb145 Binary files /dev/null and b/src/test/resources/images/jpg-exif-long-orientation.jpg differ