From 4e10fc019ea500c40c61a66e1214b49432a8f85b Mon Sep 17 00:00:00 2001 From: Harald Kuhr Date: Tue, 16 Feb 2021 20:51:08 +0100 Subject: [PATCH] #588 Clipping path from JPEG with multiple APP13 segments (cherry picked from commit 970f4f3a7ec9e6a2e046c9e8119d304a83505b9b) --- .../com/twelvemonkeys/imageio/path/Paths.java | 18 +++++++++++++----- .../imageio/metadata/jpeg/JPEGSegmentUtil.java | 2 ++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/imageio/imageio-clippath/src/main/java/com/twelvemonkeys/imageio/path/Paths.java b/imageio/imageio-clippath/src/main/java/com/twelvemonkeys/imageio/path/Paths.java index f8db298b..ba4a3adf 100755 --- a/imageio/imageio-clippath/src/main/java/com/twelvemonkeys/imageio/path/Paths.java +++ b/imageio/imageio-clippath/src/main/java/com/twelvemonkeys/imageio/path/Paths.java @@ -56,6 +56,8 @@ import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.SequenceInputStream; import java.nio.charset.StandardCharsets; import java.util.Iterator; import java.util.List; @@ -131,7 +133,13 @@ public final class Paths { List photoshop = JPEGSegmentUtil.readSegments(stream, segmentIdentifiers); if (!photoshop.isEmpty()) { - return readPathFromPhotoshopResources(new MemoryCacheImageInputStream(photoshop.get(0).data())); + InputStream data = null; + + for (JPEGSegment ps : photoshop) { + data = data == null ? ps.data() : new SequenceInputStream(data, ps.data()); + } + + return readPathFromPhotoshopResources(new MemoryCacheImageInputStream(data)); } } else if (magic >>> 16 == TIFF.BYTE_ORDER_MARK_BIG_ENDIAN && (magic & 0xffff) == TIFF.TIFF_MAGIC @@ -350,10 +358,10 @@ public final class Paths { IIOMetadataNode unknown = new IIOMetadataNode("unknown"); unknown.setAttribute("MarkerTag", Integer.toString(JPEG.APP13 & 0xFF)); - byte[] identfier = "Photoshop 3.0".getBytes(StandardCharsets.US_ASCII); - byte[] data = new byte[identfier.length + 1 + pathResource.length]; - System.arraycopy(identfier, 0, data, 0, identfier.length); - System.arraycopy(pathResource, 0, data, identfier.length + 1, pathResource.length); + byte[] identifier = "Photoshop 3.0".getBytes(StandardCharsets.US_ASCII); + byte[] data = new byte[identifier.length + 1 + pathResource.length]; + System.arraycopy(identifier, 0, data, 0, identifier.length); + System.arraycopy(pathResource, 0, data, identifier.length + 1, pathResource.length); unknown.setUserObject(data); diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/jpeg/JPEGSegmentUtil.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/jpeg/JPEGSegmentUtil.java index 92986ea9..a788d3d0 100644 --- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/jpeg/JPEGSegmentUtil.java +++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/jpeg/JPEGSegmentUtil.java @@ -348,6 +348,7 @@ public final class JPEGSegmentUtil { else if ("Photoshop 3.0".equals(segment.identifier())) { // TODO: The "Photoshop 3.0" segment contains several image resources, of which one might contain // IPTC metadata. Probably duplicated in the XMP though... + // TODO: Merge multiple APP13 segments to single resource block ImageInputStream stream = new ByteArrayImageInputStream(segment.data, segment.offset(), segment.length()); Directory psd = new PSDReader().read(stream); Entry iccEntry = psd.getEntryById(PSD.RES_ICC_PROFILE); @@ -359,6 +360,7 @@ public final class JPEGSegmentUtil { System.err.println(TIFFReader.HexDump.dump(segment.data)); } else if ("ICC_PROFILE".equals(segment.identifier())) { + // TODO: Merge multiple APP2 segments to single ICC Profile // Skip } else {