#403 Support for uncommon PSD resource magic: MeSa, PHUT, AgHg and DCSR

This commit is contained in:
Harald Kuhr 2018-01-06 21:07:15 +01:00
parent fb3c5f8440
commit c8a19418eb
7 changed files with 39 additions and 17 deletions

View File

@ -50,13 +50,13 @@ import java.awt.geom.Path2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static com.twelvemonkeys.lang.Validate.isTrue; import static com.twelvemonkeys.lang.Validate.isTrue;
import static com.twelvemonkeys.lang.Validate.notNull; import static com.twelvemonkeys.lang.Validate.notNull;
import static java.util.Collections.singletonList;
/** /**
* Support for various Adobe Photoshop Path related operations: * Support for various Adobe Photoshop Path related operations:
@ -96,7 +96,7 @@ public final class Paths {
int magic = readMagic(stream); int magic = readMagic(stream);
if (magic == PSD.RESOURCE_TYPE) { if (magic == PSD.RESOURCE_TYPE) {
// This is a PSD Image Resource BLock, we can parse directly // This is a PSD Image Resource Block, we can parse directly
return buildPathFromPhotoshopResources(stream); return buildPathFromPhotoshopResources(stream);
} }
else if (magic == PSD.SIGNATURE_8BPS) { else if (magic == PSD.SIGNATURE_8BPS) {
@ -117,8 +117,8 @@ public final class Paths {
} }
else if (magic >>> 16 == JPEG.SOI && (magic & 0xff00) == 0xff00) { else if (magic >>> 16 == JPEG.SOI && (magic & 0xff00) == 0xff00) {
// JPEG version // JPEG version
Map<Integer, java.util.List<String>> segmentIdentifiers = new LinkedHashMap<Integer, java.util.List<String>>(); Map<Integer, java.util.List<String>> segmentIdentifiers = new LinkedHashMap<>();
segmentIdentifiers.put(JPEG.APP13, Arrays.asList("Photoshop 3.0")); segmentIdentifiers.put(JPEG.APP13, singletonList("Photoshop 3.0"));
List<JPEGSegment> photoshop = JPEGSegmentUtil.readSegments(stream, segmentIdentifiers); List<JPEGSegment> photoshop = JPEGSegmentUtil.readSegments(stream, segmentIdentifiers);
@ -262,7 +262,7 @@ public final class Paths {
Desktop.getDesktop().open(tempFile); Desktop.getDesktop().open(tempFile);
Thread.sleep(3000l); Thread.sleep(3000L);
if (!tempFile.delete()) { if (!tempFile.delete()) {
System.err.printf("%s not deleted\n", tempFile); System.err.printf("%s not deleted\n", tempFile);

View File

@ -42,6 +42,13 @@ public interface PSD {
/** PSD image resource marker "8BIM". */ /** PSD image resource marker "8BIM". */
int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M'; int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M';
// http://fileformats.archiveteam.org/wiki/Photoshop_Image_Resources
// However, ExifTool says ImageReady is PHUT and PhotoDeluxe is MeSa... :-/
int RESOURCE_TYPE_IMAGEREADY = ('M' << 24) + ('e' << 16) + ('S' << 8) + 'a';
int RESOURCE_TYPE_PHOTODELUXE = ('P' << 24) + ('H' << 16) + ('U' << 8) + 'T';
int RESOURCE_TYPE_LIGHTROOM = ('A' << 24) + ('g' << 16) + ('H' << 8) + 'g';
int RESOURCE_TYPE_DCSR = ('D' << 24) + ('C' << 16) + ('S' << 8) + 'R';
/** IPTC image resource id. */ /** IPTC image resource id. */
int RES_IPTC_NAA = 0x0404; int RES_IPTC_NAA = 0x0404;

View File

@ -65,7 +65,15 @@ public final class PSDReader extends MetadataReader {
try { try {
int type = input.readInt(); int type = input.readInt();
if (type != PSD.RESOURCE_TYPE) { switch (type) {
case PSD.RESOURCE_TYPE_IMAGEREADY:
case PSD.RESOURCE_TYPE_PHOTODELUXE:
case PSD.RESOURCE_TYPE_LIGHTROOM:
case PSD.RESOURCE_TYPE_DCSR:
// TODO: Warning for these types!
case PSD.RESOURCE_TYPE:
break;
default:
throw new IIOException(String.format("Wrong image resource type, expected '8BIM': '%08x'", type)); throw new IIOException(String.format("Wrong image resource type, expected '8BIM': '%08x'", type));
} }

View File

@ -38,7 +38,7 @@ package com.twelvemonkeys.imageio.plugins.psd;
* @see <a href="http://www.adobe.com/devnet-apps/photoshop/fileformatashtml">Adobe Photoshop File Formats Specification</a> * @see <a href="http://www.adobe.com/devnet-apps/photoshop/fileformatashtml">Adobe Photoshop File Formats Specification</a>
* @see <a href="http://www.fileformat.info/format/psd/egff.htm">Adobe Photoshop File Format Summary<a> * @see <a href="http://www.fileformat.info/format/psd/egff.htm">Adobe Photoshop File Format Summary<a>
*/ */
interface PSD { interface PSD extends com.twelvemonkeys.imageio.metadata.psd.PSD {
/** PSD 2+ Native format (.PSD) identifier "8BPS" */ /** PSD 2+ Native format (.PSD) identifier "8BPS" */
int SIGNATURE_8BPS = ('8' << 24) + ('B' << 16) + ('P' << 8) + 'S'; int SIGNATURE_8BPS = ('8' << 24) + ('B' << 16) + ('P' << 8) + 'S';
@ -49,9 +49,7 @@ interface PSD {
int VERSION_PSD = 1; int VERSION_PSD = 1;
int VERSION_PSB = 2; int VERSION_PSB = 2;
/** PSD Resource type identifier "8BIM" */ int RESOURCE_TYPE_LONG = ('8' << 24) + ('B' << 16) + ('6' << 8) + '4';
int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M';
int RESOURCE_TYPE_LONG = ('8' << 24) + ('B' << 16) + ('6' << 8) + '4';;
// Blending modes // Blending modes
/** Pass through blending mode "pass"*/ /** Pass through blending mode "pass"*/

View File

@ -31,8 +31,8 @@ package com.twelvemonkeys.imageio.plugins.psd;
import com.twelvemonkeys.imageio.stream.SubImageInputStream; import com.twelvemonkeys.imageio.stream.SubImageInputStream;
import com.twelvemonkeys.lang.StringUtil; import com.twelvemonkeys.lang.StringUtil;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.IIOException; import javax.imageio.IIOException;
import javax.imageio.stream.ImageInputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -163,7 +163,15 @@ public class PSDImageResource {
public static PSDImageResource read(final ImageInputStream pInput) throws IOException { public static PSDImageResource read(final ImageInputStream pInput) throws IOException {
int type = pInput.readInt(); int type = pInput.readInt();
if (type != PSD.RESOURCE_TYPE) { switch (type) {
case com.twelvemonkeys.imageio.metadata.psd.PSD.RESOURCE_TYPE_IMAGEREADY:
case com.twelvemonkeys.imageio.metadata.psd.PSD.RESOURCE_TYPE_PHOTODELUXE:
case com.twelvemonkeys.imageio.metadata.psd.PSD.RESOURCE_TYPE_LIGHTROOM:
case com.twelvemonkeys.imageio.metadata.psd.PSD.RESOURCE_TYPE_DCSR:
// TODO: Warning for these types!
case com.twelvemonkeys.imageio.metadata.psd.PSD.RESOURCE_TYPE:
break;
default:
throw new IIOException(String.format("Wrong image resource type, expected '8BIM': '%s'", PSDUtil.intToStr(type))); throw new IIOException(String.format("Wrong image resource type, expected '8BIM': '%s'", PSDUtil.intToStr(type)));
} }

View File

@ -96,8 +96,9 @@ public class PSDImageReaderTest extends ImageReaderAbstractTest<PSDImageReader>
new TestData(getClassLoaderResource("/psd/masks2.psd"), new Dimension(640, 1136)), new TestData(getClassLoaderResource("/psd/masks2.psd"), new Dimension(640, 1136)),
// RGB, multiple alpha channels, no transparency // RGB, multiple alpha channels, no transparency
new TestData(getClassLoaderResource("/psd/rgb-multichannel-no-transparency.psd"), new Dimension(100, 100)), new TestData(getClassLoaderResource("/psd/rgb-multichannel-no-transparency.psd"), new Dimension(100, 100)),
new TestData(getClassLoaderResource("/psb/rgb-multichannel-no-transparency.psb"), new Dimension(100, 100)) new TestData(getClassLoaderResource("/psb/rgb-multichannel-no-transparency.psb"), new Dimension(100, 100)),
// TODO: Need uncompressed PSD // CMYK, uncompressed + contains some uncommon MeSa (instead of 8BIM) resource blocks
new TestData(getClassLoaderResource("/psd/fruit-cmyk-MeSa-resource.psd"), new Dimension(400, 191))
// TODO: Need more recent ZIP compressed PSD files from CS2/CS3+ // TODO: Need more recent ZIP compressed PSD files from CS2/CS3+
); );
} }