diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSD.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSD.java
old mode 100644
new mode 100755
index 94e8edac..f0a28401
--- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSD.java
+++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSD.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,9 @@ package com.twelvemonkeys.imageio.metadata.psd;
* @version $Id: PSD.java,v 1.0 24.01.12 16:51 haraldk Exp$
*/
public interface PSD {
- static final int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M';
+ /** PSD image resource marker "8BIM". */
+ int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M';
- static final int RES_IPTC_NAA = 0x0404;
+ /** IPTC image resource id. */
+ int RES_IPTC_NAA = 0x0404;
}
diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSDReader.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSDReader.java
old mode 100644
new mode 100755
index a9c9cb92..f6e67a46
--- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSDReader.java
+++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSDReader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -136,6 +136,10 @@ public final class PSDReader extends MetadataReader {
pInput.readFully(data);
}
+ public final int id() {
+ return id;
+ }
+
public final byte[] data() {
return data;
}
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/AbstractMetadata.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/AbstractMetadata.java
index 4859fa96..c5f3a528 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/AbstractMetadata.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/AbstractMetadata.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import org.w3c.dom.Node;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/ICCProfile.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/ICCProfile.java
index 83f7ca32..0112c645 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/ICCProfile.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/ICCProfile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@ import java.io.InputStream;
* @author last modified by $Author: haraldk$
* @version $Id: ICCProfile.java,v 1.0 May 20, 2008 6:24:10 PM haraldk Exp$
*/
-class ICCProfile extends PSDImageResource {
+final class ICCProfile extends PSDImageResource {
private ICC_Profile profile;
ICCProfile(final short pId, final ImageInputStream pInput) throws IOException {
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSD.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSD.java
index 04f8c678..8c676663 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSD.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSD.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,15 +35,20 @@ package com.twelvemonkeys.imageio.plugins.psd;
* @author last modified by $Author: haraldk$
* @version $Id: PSD.java,v 1.0 Apr 29, 2008 4:47:47 PM haraldk Exp$
*
+ * @see Adobe Photoshop File Formats Specification
* @see http://www.fileformat.info/format/psd/egff.htm
*/
interface PSD {
/** PSD 2+ Native format (.PSD) identifier "8BPS" */
int SIGNATURE_8BPS = ('8' << 24) + ('B' << 16) + ('P' << 8) + 'S';
+ // TODO: Is this ever used??! Spec says (and sample files uses) 8BPS + version == 2 for PSB...
/** PSD 5+ Large Document Format (.PSB) identifier "8BPB" */
int SIGNATURE_8BPB = ('8' << 24) + ('B' << 16) + ('P' << 8) + 'B';
+ int VERSION_PSD = 1;
+ int VERSION_PSB = 2;
+
/** PSD Resource type identifier "8BIM" */
int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M';
@@ -105,7 +110,7 @@ interface PSD {
// Color Modes
/** Bitmap (monochrome) */
- short COLOR_MODE_MONOCHROME = 0;
+ short COLOR_MODE_BITMAP = 0;
/** Gray-scale */
short COLOR_MODE_GRAYSCALE = 1;
@@ -541,4 +546,13 @@ interface PSD {
*/
int RES_PRINT_FLAGS_INFORMATION = 0x2710;
+ int RES_PATH_INFO_MAX = 0x0bb6;
+ int RES_PATH_INFO_MIN = 0x07d0;
+
+ /** Plug-In resource(s). Resources added by a plug-in. See the plug-in API found in the SDK documentation */
+ int RES_PLUGIN_MIN = 0x0fa0;
+
+ /** Plug-In resource(s). Resources added by a plug-in. See the plug-in API found in the SDK documentation */
+ int RES_PLUGIN_MAX = 0x1387;
+
}
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDAlphaChannelInfo.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDAlphaChannelInfo.java
index 64067411..2d3ec3f6 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDAlphaChannelInfo.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDAlphaChannelInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,7 @@ import java.util.List;
* @author last modified by $Author: haraldk$
* @version $Id: PSDAlphaChannelInfo.java,v 1.0 May 2, 2008 5:33:40 PM haraldk Exp$
*/
-class PSDAlphaChannelInfo extends PSDImageResource {
+final class PSDAlphaChannelInfo extends PSDImageResource {
List names;
public PSDAlphaChannelInfo(short pId, final ImageInputStream pInput) throws IOException {
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDChannelInfo.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDChannelInfo.java
index 603c3cf5..99f4518d 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDChannelInfo.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDChannelInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@ package com.twelvemonkeys.imageio.plugins.psd;
* @author last modified by $Author: haraldk$
* @version $Id: PSDChannelInfo.java,v 1.0 May 6, 2008 2:46:23 PM haraldk Exp$
*/
-class PSDChannelInfo {
+final class PSDChannelInfo {
final short channelId;
final long length;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDChannelSourceDestinationRange.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDChannelSourceDestinationRange.java
index b58574ac..3bff3bba 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDChannelSourceDestinationRange.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDChannelSourceDestinationRange.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@ import java.io.IOException;
* @author last modified by $Author: haraldk$
* @version $Id: PSDChannelSourceDestinationRange.java,v 1.0 May 6, 2008 5:14:13 PM haraldk Exp$
*/
-class PSDChannelSourceDestinationRange {
+final class PSDChannelSourceDestinationRange {
private String channel;
private short sourceBlack;
private short sourceWhite;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDColorData.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDColorData.java
old mode 100644
new mode 100755
index 3b120af8..b3f71c20
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDColorData.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDColorData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,7 +43,7 @@ import java.io.IOException;
* @author last modified by $Author: haraldk$
* @version $Id: PSDColorData.java,v 1.0 Apr 29, 2008 5:33:01 PM haraldk Exp$
*/
-class PSDColorData {
+final class PSDColorData {
final byte[] colors;
private IndexColorModel colorModel;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDDisplayInfo.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDDisplayInfo.java
index 037f2a9a..c8b1eb51 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDDisplayInfo.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDDisplayInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@ import java.io.IOException;
* @author last modified by $Author: haraldk$
* @version $Id: PSDResolutionInfo.java,v 1.0 May 2, 2008 3:58:19 PM haraldk Exp$
*/
-class PSDDisplayInfo extends PSDImageResource {
+final class PSDDisplayInfo extends PSDImageResource {
// TODO: Size of this struct should be 14.. Does not compute... Something bogus here
// ColorSpace definitions:
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDEXIF1Data.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDEXIF1Data.java
index f765c22e..8f314a04 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDEXIF1Data.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDEXIF1Data.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import com.twelvemonkeys.imageio.metadata.Directory;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDGlobalLayerMask.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDGlobalLayerMask.java
index 0c75b981..68366faf 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDGlobalLayerMask.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDGlobalLayerMask.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,8 +38,8 @@ import java.io.IOException;
* @author last modified by $Author: haraldk$
* @version $Id: PSDGlobalLayerMask.java,v 1.0 May 8, 2008 5:33:48 PM haraldk Exp$
*/
-class PSDGlobalLayerMask {
- final int colorSpace;
+final class PSDGlobalLayerMask {
+ final int colorSpace;
final int color1;
final int color2;
final int color3;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDGridAndGuideInfo.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDGridAndGuideInfo.java
index 96e47616..02c72047 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDGridAndGuideInfo.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDGridAndGuideInfo.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import javax.imageio.stream.ImageInputStream;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDHeader.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDHeader.java
old mode 100644
new mode 100755
index b12e594a..7278f3f5
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDHeader.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDHeader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,8 +28,9 @@
package com.twelvemonkeys.imageio.plugins.psd;
-import javax.imageio.stream.ImageInputStream;
import javax.imageio.IIOException;
+
+import java.io.DataInput;
import java.io.IOException;
/**
@@ -39,19 +40,21 @@ import java.io.IOException;
* @author last modified by $Author: haraldk$
* @version $Id: PSDHeader.java,v 1.0 Apr 29, 2008 5:18:22 PM haraldk Exp$
*/
-class PSDHeader {
-// The header is 26 bytes in length and is structured as follows:
+final class PSDHeader {
+ static final int PSD_MAX_SIZE = 30000;
+ static final int PSB_MAX_SIZE = 300000;
+ // The header is 26 bytes in length and is structured as follows:
//
// typedef struct _PSD_HEADER
// {
// BYTE Signature[4]; /* File ID "8BPS" */
-// WORD Version; /* Version number, always 1 */
+// WORD Version; /* Version number, always 1. 2 for PSB */
// BYTE Reserved[6]; /* Reserved, must be zeroed */
-// WORD Channels; /* Number of color channels (1-24) including alpha
+// WORD Channels; /* Number of color channels (1-56) including alpha
// channels */
-// LONG Rows; /* Height of image in pixels (1-30000) */
-// LONG Columns; /* Width of image in pixels (1-30000) */
-// WORD Depth; /* Number of bits per channel (1, 8, and 16) */
+// LONG Rows; /* Height of image in pixels (1-30000/1-300000 for PSB) */
+// LONG Columns; /* Width of image in pixels (1-30000/1-300000 for PSB) */
+// WORD Depth; /* Number of bits per channel (1, 8, 16 or 32) */
// WORD Mode; /* Color mode */
// } PSD_HEADER;
@@ -60,8 +63,9 @@ class PSDHeader {
final int height;
final short bits;
final short mode;
+ final boolean largeFormat;
- PSDHeader(final ImageInputStream pInput) throws IOException {
+ PSDHeader(final DataInput pInput) throws IOException {
int signature = pInput.readInt();
if (signature != PSD.SIGNATURE_8BPS) {
throw new IIOException("Not a PSD document, expected signature \"8BPS\": \"" + PSDUtil.intToStr(signature) + "\" (0x" + Integer.toHexString(signature) + ")");
@@ -70,67 +74,105 @@ class PSDHeader {
int version = pInput.readUnsignedShort();
switch (version) {
- case 1:
+ case PSD.VERSION_PSD:
+ largeFormat = false;
+ break;
+ case PSD.VERSION_PSB:
+ largeFormat = true;
break;
- case 2:
- throw new IIOException("Photoshop Large Document Format (PSB) not supported yet.");
default:
throw new IIOException(String.format("Unknown PSD version, expected 1 or 2: 0x%08x", version));
}
byte[] reserved = new byte[6];
- pInput.readFully(reserved);
+ pInput.readFully(reserved); // We don't really care
channels = pInput.readShort();
+ if (channels <= 0) {
+ throw new IIOException(String.format("Unsupported number of channels: %d", channels));
+ }
+
height = pInput.readInt(); // Rows
width = pInput.readInt(); // Columns
+
bits = pInput.readShort();
+
+ switch (bits) {
+ case 1:
+ case 8:
+ case 16:
+ case 32:
+ break;
+ default:
+ throw new IIOException(String.format("Unsupported bit depth for PSD: %d bits", bits));
+ }
+
mode = pInput.readShort();
+
+ switch (mode) {
+ case PSD.COLOR_MODE_BITMAP:
+ case PSD.COLOR_MODE_GRAYSCALE:
+ case PSD.COLOR_MODE_INDEXED:
+ case PSD.COLOR_MODE_RGB:
+ case PSD.COLOR_MODE_CMYK:
+ case PSD.COLOR_MODE_MULTICHANNEL:
+ case PSD.COLOR_MODE_DUOTONE:
+ case PSD.COLOR_MODE_LAB:
+ break;
+ default:
+ throw new IIOException(String.format("Unsupported mode depth for PSD: %d", mode));
+ }
}
@Override
public String toString() {
- StringBuilder builder = new StringBuilder(getClass().getSimpleName());
- builder.append("[Channels: ");
- builder.append(channels);
- builder.append(", width: ");
- builder.append(width);
- builder.append(", height: ");
- builder.append(height);
- builder.append(", depth: ");
- builder.append(bits);
- builder.append(", mode: ");
- builder.append(mode);
- switch (mode) {
- case PSD.COLOR_MODE_MONOCHROME:
- builder.append(" (Monochrome)");
- break;
- case PSD.COLOR_MODE_GRAYSCALE:
- builder.append(" (Grayscale)");
- break;
- case PSD.COLOR_MODE_INDEXED:
- builder.append(" (Indexed)");
- break;
- case PSD.COLOR_MODE_RGB:
- builder.append(" (RGB)");
- break;
- case PSD.COLOR_MODE_CMYK:
- builder.append(" (CMYK)");
- break;
- case PSD.COLOR_MODE_MULTICHANNEL:
- builder.append(" (Multi channel)");
- break;
- case PSD.COLOR_MODE_DUOTONE:
- builder.append(" (Duotone)");
- break;
- case PSD.COLOR_MODE_LAB:
- builder.append(" (Lab color)");
- break;
- default:
- builder.append(" (Unkown mode)");
- }
- builder.append("]");
+ return new StringBuilder(getClass().getSimpleName())
+ .append("[version: ")
+ .append(largeFormat ? "2" : "1")
+ .append(", channels: ")
+ .append(channels)
+ .append(", width: ")
+ .append(width)
+ .append(", height: ")
+ .append(height)
+ .append(", depth: ")
+ .append(bits)
+ .append(", mode: ")
+ .append(mode)
+ .append(" (")
+ .append(modeAsString())
+ .append(")]")
+ .toString();
+ }
- return builder.toString();
+ int getMaxSize() {
+ return largeFormat ? PSB_MAX_SIZE : PSD_MAX_SIZE;
+ }
+
+ boolean hasValidDimensions() {
+ return width <= getMaxSize() && height <= getMaxSize();
+ }
+
+ private String modeAsString() {
+ switch (mode) {
+ case PSD.COLOR_MODE_BITMAP:
+ return "Monochrome";
+ case PSD.COLOR_MODE_GRAYSCALE:
+ return "Grayscale";
+ case PSD.COLOR_MODE_INDEXED:
+ return "Indexed";
+ case PSD.COLOR_MODE_RGB:
+ return "RGB";
+ case PSD.COLOR_MODE_CMYK:
+ return "CMYK";
+ case PSD.COLOR_MODE_MULTICHANNEL:
+ return "Multi channel";
+ case PSD.COLOR_MODE_DUOTONE:
+ return "Duotone";
+ case PSD.COLOR_MODE_LAB:
+ return "Lab color";
+ default:
+ return "Unkown mode";
+ }
}
}
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDIPTCData.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDIPTCData.java
index 066d04cf..367ee46b 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDIPTCData.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDIPTCData.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import com.twelvemonkeys.imageio.metadata.Directory;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReader.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReader.java
old mode 100644
new mode 100755
index c3a588b3..a452dac7
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReader.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,15 +32,12 @@ import com.twelvemonkeys.image.ImageUtil;
import com.twelvemonkeys.imageio.ImageReaderBase;
import com.twelvemonkeys.imageio.color.ColorSpaces;
import com.twelvemonkeys.imageio.util.IndexedImageTypeSpecifier;
-import com.twelvemonkeys.xml.XMLSerializer;
-import org.w3c.dom.Node;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
-import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
@@ -70,12 +67,12 @@ import java.util.List;
// See http://www.codeproject.com/KB/graphics/PSDParser.aspx
// See http://www.adobeforums.com/webx?14@@.3bc381dc/0
// Done: Allow reading the extra alpha channels (index after composite data)
-public class PSDImageReader extends ImageReaderBase {
+public final class PSDImageReader extends ImageReaderBase {
private PSDHeader header;
private ICC_ColorSpace colorSpace;
- protected PSDMetadata metadata;
+ private PSDMetadata metadata;
- protected PSDImageReader(final ImageReaderSpi originatingProvider) {
+ PSDImageReader(final ImageReaderSpi originatingProvider) {
super(originatingProvider);
}
@@ -108,10 +105,7 @@ public class PSDImageReader extends ImageReaderBase {
}
private int getLayerWidth(int layerIndex) throws IOException {
- if (metadata == null || metadata.layerInfo == null) {
- readImageResources(false);
- readLayerAndMaskInfo(true);
- }
+ readLayerAndMaskInfo(true);
PSDLayerInfo layerInfo = metadata.layerInfo.get(layerIndex);
@@ -119,10 +113,7 @@ public class PSDImageReader extends ImageReaderBase {
}
private int getLayerHeight(int layerIndex) throws IOException {
- if (metadata == null || metadata.layerInfo == null) {
- readImageResources(false);
- readLayerAndMaskInfo(true);
- }
+ readLayerAndMaskInfo(true);
PSDLayerInfo layerInfo = metadata.layerInfo.get(layerIndex);
@@ -136,14 +127,10 @@ public class PSDImageReader extends ImageReaderBase {
private ImageTypeSpecifier getRawImageTypeInternal(final int imageIndex) throws IOException {
checkBounds(imageIndex);
- readHeader();
// Image index above 0, means a layer
if (imageIndex > 0) {
- if (metadata == null || metadata.layerInfo == null) {
- readImageResources(false);
- readLayerAndMaskInfo(true);
- }
+ readLayerAndMaskInfo(true);
return getRawImageTypeForLayer(imageIndex - 1);
}
@@ -154,46 +141,56 @@ public class PSDImageReader extends ImageReaderBase {
private ImageTypeSpecifier getRawImageTypeForCompositeLayer() throws IOException {
ColorSpace cs;
+
switch (header.mode) {
- case PSD.COLOR_MODE_MONOCHROME:
+ case PSD.COLOR_MODE_BITMAP:
if (header.channels == 1 && header.bits == 1) {
return ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
}
- throw new IIOException(
- String.format("Unsupported channel count/bit depth for Monochrome PSD: %d channels/%d bits", header.channels, header.bits)
- );
+ throw new IIOException(String.format("Unsupported channel count/bit depth for Monochrome PSD: %d channels/%d bits", header.channels, header.bits));
case PSD.COLOR_MODE_INDEXED:
- // TODO: 16 bit indexed?! Does it exist?
if (header.channels == 1 && header.bits == 8) {
return IndexedImageTypeSpecifier.createFromIndexColorModel(metadata.colorData.getIndexColorModel());
}
- throw new IIOException(
- String.format("Unsupported channel count/bit depth for Indexed Color PSD: %d channels/%d bits", header.channels, header.bits)
- );
+ throw new IIOException(String.format("Unsupported channel count/bit depth for Indexed Color PSD: %d channels/%d bits", header.channels, header.bits));
case PSD.COLOR_MODE_DUOTONE:
// NOTE: Duotone (whatever that is) should be treated as gray scale
// Fall-through
case PSD.COLOR_MODE_GRAYSCALE:
+ cs = getEmbeddedColorSpace();
+ if (cs == null) {
+ cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
+ }
+
if (header.channels == 1 && header.bits == 8) {
return ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY);
}
+ else if (header.channels == 2 && header.bits == 8) {
+ return ImageTypeSpecifier.createBanded(cs, new int[] {0, 1}, new int[] {0, 0}, DataBuffer.TYPE_BYTE, true, false);
+ }
else if (header.channels == 1 && header.bits == 16) {
return ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_USHORT_GRAY);
}
+ else if (header.channels == 2 && header.bits == 16) {
+ return ImageTypeSpecifier.createBanded(cs, new int[] {0, 1}, new int[] {0, 0}, DataBuffer.TYPE_USHORT, true, false);
+ }
+ else if (header.channels == 1 && header.bits == 32) {
+ return ImageTypeSpecifier.createBanded(cs, new int[] {0}, new int[] {0}, DataBuffer.TYPE_INT, false, false);
+ }
+ else if (header.channels == 2 && header.bits == 32) {
+ return ImageTypeSpecifier.createBanded(cs, new int[] {0, 1}, new int[] {0, 0}, DataBuffer.TYPE_INT, true, false);
+ }
- throw new IIOException(
- String.format("Unsupported channel count/bit depth for Gray Scale PSD: %d channels/%d bits", header.channels, header.bits)
- );
+ throw new IIOException(String.format("Unsupported channel count/bit depth for Gray Scale PSD: %d channels/%d bits", header.channels, header.bits));
case PSD.COLOR_MODE_RGB:
cs = getEmbeddedColorSpace();
if (cs == null) {
- // TODO: Should probably be Adobe RGB (1998), not sRGB. Or..? Can't find any spec saying either...
- cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); // ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998); ?
+ cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
}
if (header.channels == 3 && header.bits == 8) {
@@ -208,10 +205,14 @@ public class PSDImageReader extends ImageReaderBase {
else if (header.channels >= 4 && header.bits == 16) {
return ImageTypeSpecifier.createBanded(cs, new int[] {0, 1, 2, 3}, new int[] {0, 0, 0, 0}, DataBuffer.TYPE_USHORT, true, false);
}
+ else if (header.channels == 3 && header.bits == 32) {
+ return ImageTypeSpecifier.createBanded(cs, new int[] {0, 1, 2}, new int[] {0, 0, 0}, DataBuffer.TYPE_INT, false, false);
+ }
+ else if (header.channels >= 4 && header.bits == 32) {
+ return ImageTypeSpecifier.createBanded(cs, new int[] {0, 1, 2, 3}, new int[] {0, 0, 0, 0}, DataBuffer.TYPE_INT, true, false);
+ }
- throw new IIOException(
- String.format("Unsupported channel count/bit depth for RGB PSD: %d channels/%d bits", header.channels, header.bits)
- );
+ throw new IIOException(String.format("Unsupported channel count/bit depth for RGB PSD: %d channels/%d bits", header.channels, header.bits));
case PSD.COLOR_MODE_CMYK:
cs = getEmbeddedColorSpace();
@@ -231,10 +232,14 @@ public class PSDImageReader extends ImageReaderBase {
else if (header.channels == 5 && header.bits == 16) {
return ImageTypeSpecifier.createBanded(cs, new int[] {0, 1, 2, 3, 4}, new int[] {0, 0, 0, 0, 0}, DataBuffer.TYPE_USHORT, true, false);
}
+ else if (header.channels == 4 && header.bits == 32) {
+ return ImageTypeSpecifier.createBanded(cs, new int[] {0, 1, 2, 3}, new int[] {0, 0, 0, 0}, DataBuffer.TYPE_INT, false, false);
+ }
+ else if (header.channels == 5 && header.bits == 32) {
+ return ImageTypeSpecifier.createBanded(cs, new int[] {0, 1, 2, 3, 4}, new int[] {0, 0, 0, 0, 0}, DataBuffer.TYPE_INT, true, false);
+ }
- throw new IIOException(
- String.format("Unsupported channel count/bit depth for CMYK PSD: %d channels/%d bits", header.channels, header.bits)
- );
+ throw new IIOException(String.format("Unsupported channel count/bit depth for CMYK PSD: %d channels/%d bits", header.channels, header.bits));
case PSD.COLOR_MODE_MULTICHANNEL:
// TODO: Implement
@@ -242,9 +247,7 @@ public class PSDImageReader extends ImageReaderBase {
// TODO: Implement
// TODO: If there's a color profile embedded, it should be easy, otherwise we're out of luck...
default:
- throw new IIOException(
- String.format("Unsupported PSD MODE: %s (%d channels/%d bits)", header.mode, header.channels, header.bits)
- );
+ throw new IIOException(String.format("Unsupported PSD MODE: %s (%d channels/%d bits)", header.mode, header.channels, header.bits));
}
}
@@ -330,8 +333,6 @@ public class PSDImageReader extends ImageReaderBase {
private ColorSpace getEmbeddedColorSpace() throws IOException {
readImageResources(true);
- // TODO: Skip this, requires storing some stream offsets
- readLayerAndMaskInfo(false);
if (colorSpace == null) {
ICC_Profile profile = null;
@@ -351,27 +352,12 @@ public class PSDImageReader extends ImageReaderBase {
public BufferedImage read(final int imageIndex, final ImageReadParam param) throws IOException {
checkBounds(imageIndex);
- readHeader();
-
- readImageResources(false);
-// readLayerAndMaskInfo(false);
- readLayerAndMaskInfo(imageIndex > 0);
-
// TODO: What about the extra alpha channels possibly present? Read as gray scale as extra images?
// Layer hacks... For now, any index above 0 is considered to be a layer...
// TODO: Support layer in index 0, if "has real merged data" flag is false?
// TODO: Param support in layer code (more duping/cleanup..)
if (imageIndex > 0) {
-// ImageTypeSpecifier compositeType = getRawImageTypeForCompositeLayer();
-// ImageTypeSpecifier imageType = getImageTypes(0).next();
-
-// int layerIndex = imageIndex - 1;
-
-// PSDLayerInfo layerInfo = metadata.layerInfo.get(layerIndex);
-//
-// imageInput.seek(findLayerStartPos(layerIndex));
-// return readLayerData(layerIndex, layerInfo, compositeType, imageType, param);
return readLayerData(imageIndex - 1, param);
}
@@ -421,13 +407,11 @@ public class PSDImageReader extends ImageReaderBase {
ySub = param.getSourceYSubsampling();
}
- processImageStarted(imageIndex);
-
- int[] byteCounts = null;
+ imageInput.seek(metadata.imageDataStart);
int compression = imageInput.readShort();
- // TODO: Need to make sure compression is set in metadata, even without reading the image data!
metadata.compression = compression;
+ int[] byteCounts = null;
switch (compression) {
case PSD.COMPRESSION_NONE:
break;
@@ -435,14 +419,12 @@ public class PSDImageReader extends ImageReaderBase {
// NOTE: Byte counts will allow us to easily skip rows before AOI
byteCounts = new int[header.channels * header.height];
for (int i = 0; i < byteCounts.length; i++) {
- byteCounts[i] = imageInput.readUnsignedShort();
+ byteCounts[i] = header.largeFormat ? imageInput.readInt() : imageInput.readUnsignedShort();
}
break;
case PSD.COMPRESSION_ZIP:
- // TODO: Could probably use the ZIPDecoder (DeflateDecoder) here..
case PSD.COMPRESSION_ZIP_PREDICTION:
- // TODO: Look at TIFF prediction reading
- // Could be same as PNG prediction? Read up...
+ // TODO: Could probably use the ZIPDecoder (DeflateDecoder) here.. Look at TIFF prediction reading
throw new IIOException("PSD with ZIP compression not supported");
default:
throw new IIOException(
@@ -453,6 +435,8 @@ public class PSDImageReader extends ImageReaderBase {
);
}
+ processImageStarted(imageIndex);
+
// What we read here is the "composite layer" of the PSD file
readImageData(image, rawType.getColorModel(), source, dest, xSub, ySub, byteCounts, compression);
@@ -512,8 +496,12 @@ public class PSDImageReader extends ImageReaderBase {
short[] row16 = ((DataBufferUShort) rowRaster.getDataBuffer()).getData();
read16bitChannel(c, header.channels, raster.getDataBuffer(), interleavedBands, bandOffset, pSourceCM, row16, pSource, pDest, pXSub, pYSub, header.width, header.height, pByteCounts, c * header.height, pCompression == PSD.COMPRESSION_RLE);
break;
+ case 32:
+ int[] row32 = ((DataBufferInt) rowRaster.getDataBuffer()).getData();
+ read32bitChannel(c, header.channels, raster.getDataBuffer(), interleavedBands, bandOffset, pSourceCM, row32, pSource, pDest, pXSub, pYSub, header.width, header.height, pByteCounts, c * header.height, pCompression == PSD.COMPRESSION_RLE);
+ break;
default:
- throw new IIOException(String.format("Unknown PSD bit depth: %s", header.bits));
+ throw new IIOException(String.format("Unsupported PSD bit depth: %s", header.bits));
}
if (abortRequested()) {
@@ -531,6 +519,67 @@ public class PSDImageReader extends ImageReaderBase {
processImageProgress(100f * channel / channelCount + 100f * y / (height * channelCount));
}
+ private void read32bitChannel(final int pChannel, final int pChannelCount,
+ final DataBuffer pData, final int pBands, final int pBandOffset,
+ final ColorModel pSourceColorModel,
+ final int[] pRow,
+ final Rectangle pSource, final Rectangle pDest,
+ final int pXSub, final int pYSub,
+ final int pChannelWidth, final int pChannelHeight,
+ final int[] pRowByteCounts, final int pRowOffset,
+ final boolean pRLECompressed) throws IOException {
+
+ final boolean isCMYK = pSourceColorModel.getColorSpace().getType() == ColorSpace.TYPE_CMYK;
+ final int colorComponents = pSourceColorModel.getColorSpace().getNumComponents();
+ final boolean banded = pData.getNumBanks() > 1;
+
+ for (int y = 0; y < pChannelHeight; y++) {
+ // NOTE: Length is in *16 bit values* (shorts)
+ int length = 2 * (pRLECompressed ? pRowByteCounts[pRowOffset + y] : pChannelWidth);
+
+ // TODO: Sometimes need to read the line y == source.y + source.height...
+ // Read entire line, if within source region and sampling
+ if (y >= pSource.y && y < pSource.y + pSource.height && y % pYSub == 0) {
+ if (pRLECompressed) {
+ DataInputStream input = PSDUtil.createPackBitsStream(imageInput, length);
+ try {
+ for (int x = 0; x < pChannelWidth; x++) {
+ pRow[x] = input.readInt();
+ }
+ }
+ finally {
+ input.close();
+ }
+ }
+ else {
+ imageInput.readFully(pRow, 0, pChannelWidth);
+ }
+
+ // TODO: Destination offset...??
+ // Copy line sub sampled into real data
+ int offset = (y - pSource.y) / pYSub * pDest.width * pBands + pBandOffset;
+ for (int x = 0; x < pDest.width; x++) {
+ int value = pRow[pSource.x + x * pXSub];
+
+ // CMYK values are stored inverted, but alpha is not
+ if (isCMYK && pChannel < colorComponents) {
+ value = 0xffffffff - value;
+ }
+
+ pData.setElem(banded ? pChannel : 0, offset + x * pBands, value);
+ }
+ }
+ else {
+ imageInput.skipBytes(length);
+ }
+
+ if (abortRequested()) {
+ break;
+ }
+ processImageProgressForChannel(pChannel, pChannelCount, y, pChannelHeight);
+ }
+ }
+
private void read16bitChannel(final int pChannel, final int pChannelCount,
final DataBuffer pData, final int pBands, final int pBandOffset,
final ColorModel pSourceColorModel,
@@ -731,7 +780,7 @@ public class PSDImageReader extends ImageReaderBase {
private void decomposeAlpha(final ColorModel pModel, final DataBuffer pBuffer,
final int pWidth, final int pHeight, final int pChannels) {
- // TODO: Is the document background always white!?
+ // NOTE: It seems that the document background always white..?!
// TODO: What about CMYK + alpha?
if (pModel.hasAlpha() && pModel.getColorSpace().getType() == ColorSpace.TYPE_RGB) {
@@ -791,9 +840,16 @@ public class PSDImageReader extends ImageReaderBase {
private void readHeader() throws IOException {
assertInput();
+
if (header == null) {
header = new PSDHeader(imageInput);
+ if (!header.hasValidDimensions()) {
+ processWarningOccurred(String.format("Dimensions exceed maximum allowed for %s: %dx%d (max %dx%d)",
+ header.largeFormat ? "PSB" : "PSD",
+ header.width, header.height, header.getMaxSize(), header.getMaxSize()));
+ }
+
metadata = new PSDMetadata();
metadata.header = header;
@@ -818,6 +874,8 @@ public class PSDImageReader extends ImageReaderBase {
imageInput.skipBytes(length);
}
+ metadata.imageResourcesStart = imageInput.getStreamPosition();
+
// Don't need the header again
imageInput.flushBefore(imageInput.getStreamPosition());
}
@@ -826,85 +884,104 @@ public class PSDImageReader extends ImageReaderBase {
// TODO: Flags or list of interesting resources to parse
// TODO: Obey ignoreMetadata
private void readImageResources(final boolean pParseData) throws IOException {
- // TODO: Avoid unnecessary stream repositioning
- long pos = imageInput.getFlushedPosition();
- imageInput.seek(pos);
+ readHeader();
- long length = imageInput.readUnsignedInt();
+ if (pParseData || metadata.layerAndMaskInfoStart == 0) {
+ imageInput.seek(metadata.imageResourcesStart);
- if (pParseData && length > 0) {
- if (metadata.imageResources == null) {
- metadata.imageResources = new ArrayList();
- long expectedEnd = imageInput.getStreamPosition() + length;
+ long imageResourcesLength = imageInput.readUnsignedInt();
- while (imageInput.getStreamPosition() < expectedEnd) {
- // TODO: Have PSDImageResources defer actual parsing? (Just store stream offsets)
- PSDImageResource resource = PSDImageResource.read(imageInput);
- metadata.imageResources.add(resource);
+ if (pParseData && imageResourcesLength > 0) {
+ if (metadata.imageResources == null) {
+ metadata.imageResources = new ArrayList();
+ long expectedEnd = imageInput.getStreamPosition() + imageResourcesLength;
+
+ while (imageInput.getStreamPosition() < expectedEnd) {
+ PSDImageResource resource = PSDImageResource.read(imageInput);
+ metadata.imageResources.add(resource);
+ }
+
+ if (imageInput.getStreamPosition() != expectedEnd) {
+ throw new IIOException("Corrupt PSD document"); // ..or maybe just a bug in the reader.. ;-)
+ }
}
- if (imageInput.getStreamPosition() != expectedEnd) {
- throw new IIOException("Corrupt PSD document"); // ..or maybe just a bug in the reader.. ;-)
- }
+ // TODO: We should now be able to flush input
+// imageInput.flushBefore(metadata.imageResourcesStart + imageResourcesLength + 4);
}
- }
- imageInput.seek(pos + length + 4);
+ metadata.layerAndMaskInfoStart = metadata.imageResourcesStart + imageResourcesLength + 4; // + 4 for the length field itself
+ }
}
// TODO: Flags or list of interesting resources to parse
// TODO: Obey ignoreMetadata
private void readLayerAndMaskInfo(final boolean pParseData) throws IOException {
- // TODO: Make sure we are positioned correctly
- // TODO: Avoid unnecessary stream repositioning
- long length = imageInput.readUnsignedInt();
- if (pParseData && length > 0) {
- long pos = imageInput.getStreamPosition();
+ readImageResources(false);
- long read;
- if (metadata.layerInfo == null) {
- long layerInfoLength = imageInput.readUnsignedInt();
+ if (pParseData || metadata.imageDataStart == 0) {
+ imageInput.seek(metadata.layerAndMaskInfoStart);
- /*
- "Layer count. If it is a negative number, its absolute value is the number of
- layers and the first alpha channel contains the transparency data for the
- merged result."
- */
- // TODO: Figure out what the last part of that sentence means in practice...
- int layers = imageInput.readShort();
+ long layerAndMaskInfoLength = header.largeFormat ? imageInput.readLong() : imageInput.readUnsignedInt();
- PSDLayerInfo[] layerInfos = new PSDLayerInfo[Math.abs(layers)];
- for (int i = 0; i < layerInfos.length; i++) {
- layerInfos[i] = new PSDLayerInfo(imageInput);
+ // NOTE: The spec says that if this section is empty, the length should be 0.
+ // Yet I have a PSB file that has size 12, and both contained lengths set to 0 (which
+ // is alo not as per spec, as layer count should be included if there's a layer info
+ // block, so minimum size should be either 0 or 14 (or 16 if multiple of 4 for PSB))...
+
+ if (pParseData && layerAndMaskInfoLength > 0) {
+ long pos = imageInput.getStreamPosition();
+
+ if (metadata.layerInfo == null) {
+ long layerInfoLength = header.largeFormat ? imageInput.readLong() : imageInput.readUnsignedInt();
+
+ if (layerInfoLength > 0) {
+ /*
+ "Layer count. If it is a negative number, its absolute value is the number of
+ layers and the first alpha channel contains the transparency data for the
+ merged result."
+ */
+ int layerCount = imageInput.readShort();
+
+ PSDLayerInfo[] layerInfos = new PSDLayerInfo[Math.abs(layerCount)];
+ for (int i = 0; i < layerInfos.length; i++) {
+ layerInfos[i] = new PSDLayerInfo(header.largeFormat, imageInput);
+ }
+ metadata.layerInfo = Arrays.asList(layerInfos);
+ metadata.layersStart = imageInput.getStreamPosition();
+
+ long read = imageInput.getStreamPosition() - pos;
+
+ long diff = layerInfoLength - (read - (header.largeFormat ? 8 : 4)); // - 4 for the layerInfoLength field itself
+
+ imageInput.skipBytes(diff);
+ } else {
+ metadata.layerInfo = Collections.emptyList();
+ }
+
+ // Global LayerMaskInfo (18 bytes or more..?)
+ // 4 (length), 2 (colorSpace), 8 (4 * 2 byte color components), 2 (opacity %), 1 (kind), variable (pad)
+ long layerMaskInfoLength = imageInput.readUnsignedInt(); // NOTE: Not long for PSB!
+
+ if (layerMaskInfoLength > 0) {
+ metadata.globalLayerMask = new PSDGlobalLayerMask(imageInput);
+ }
+
+ // TODO: Parse "Additional layer information"
+
+ // TODO: We should now be able to flush input
+// imageInput.seek(metadata.layerAndMaskInfoStart + layerAndMaskInfoLength + (header.largeFormat ? 8 : 4));
+// imageInput.flushBefore(metadata.layerAndMaskInfoStart + layerAndMaskInfoLength + (header.largeFormat ? 8 : 4));
}
- metadata.layerInfo = Arrays.asList(layerInfos);
- metadata.layersStart = imageInput.getStreamPosition();
- read = imageInput.getStreamPosition() - pos;
-
- long diff = layerInfoLength - (read - 4); // - 4 for the layerInfoLength field itself
- // System.out.println("diff: " + diff);
- imageInput.skipBytes(diff);
-
- // TODO: Global LayerMaskInfo (18 bytes or more..?)
- // 4 (length), 2 (colorSpace), 8 (4 * 2 byte color components), 2 (opacity %), 1 (kind), variable (pad)
- long layerMaskInfoLength = imageInput.readUnsignedInt();
- // System.out.println("GlobalLayerMaskInfo length: " + layerMaskInfoLength);
- if (layerMaskInfoLength > 0) {
- metadata.globalLayerMask = new PSDGlobalLayerMask(imageInput);
-// System.err.println("globalLayerMask: " + metadata.globalLayerMask);
- }
+// read = imageInput.getStreamPosition() - pos;
+//
+// long toSkip = layerAndMaskInfoLength - read;
+// System.out.println("toSkip: " + toSkip);
+// imageInput.skipBytes(toSkip);
}
- read = imageInput.getStreamPosition() - pos;
-
- long toSkip = length - read;
-// System.out.println("toSkip: " + toSkip);
- imageInput.skipBytes(toSkip);
- }
- else {
- // Skip entire layer and mask section
- imageInput.skipBytes(length);
+ metadata.imageDataStart = metadata.layerAndMaskInfoStart + layerAndMaskInfoLength + (header.largeFormat ? 8 : 4);
}
}
@@ -949,19 +1026,22 @@ public class PSDImageReader extends ImageReaderBase {
final boolean banded = raster.getDataBuffer().getNumBanks() > 1;
final int interleavedBands = banded ? 1 : raster.getNumBands();
+ // TODO: progress for layers!
+ // TODO: Consider creating a method in PSDLayerInfo that can tell how many channels we really want to decode
for (PSDChannelInfo channelInfo : layerInfo.channelInfo) {
int compression = imageInput.readUnsignedShort();
// Skip layer if we can't read it
- // channelId == -2 means "user supplied layer mask", whatever that is...
- if (width <= 0 || height <= 0 || channelInfo.channelId == -2 ||
- (compression != PSD.COMPRESSION_NONE && compression != PSD.COMPRESSION_RLE)) {
+ // channelId
+ // -1 = transparency mask; -2 = user supplied layer mask, -3 = real user supplied layer mask (when both a user mask and a vector mask are present)
+ if (width <= 0 || height <= 0 || channelInfo.channelId < -1 ||
+ (compression != PSD.COMPRESSION_NONE && compression != PSD.COMPRESSION_RLE)) { // TODO: ZIP Compressions!
imageInput.skipBytes(channelInfo.length - 2);
}
else {
// 0 = red, 1 = green, etc
- // -1 = transparency mask; -2 = user supplied layer mask
- int c = channelInfo.channelId == -1 ? layerInfo.channelInfo.length - 1 : channelInfo.channelId;
+ // -1 = transparency mask; -2 = user supplied layer mask, -3 = real user supplied layer mask (when both a user mask and a vector mask are present)
+ int c = channelInfo.channelId == -1 ? rowRaster.getNumBands() - 1 : channelInfo.channelId;
// NOTE: For layers, byte counts are written per channel, while for the composite data
// byte counts are written for all channels before the image data.
@@ -975,10 +1055,10 @@ public class PSDImageReader extends ImageReaderBase {
case PSD.COMPRESSION_RLE:
// If RLE, the the image data starts with the byte counts
// for all the scan lines in the channel (LayerBottom-LayerTop), with
- // each count stored as a two*byte value.
+ // each count stored as a two*byte (four for PSB) value.
byteCounts = new int[layerInfo.bottom - layerInfo.top];
for (int i = 0; i < byteCounts.length; i++) {
- byteCounts[i] = imageInput.readUnsignedShort();
+ byteCounts[i] = header.largeFormat ? imageInput.readInt() : imageInput.readUnsignedShort();
}
break;
@@ -998,11 +1078,18 @@ public class PSDImageReader extends ImageReaderBase {
break;
case 8:
byte[] row8 = ((DataBufferByte) rowRaster.getDataBuffer()).getData();
- read8bitChannel(c, imageType.getNumBands(), raster.getDataBuffer(), interleavedBands, bandOffset, sourceCM, row8, area, area, xsub, ysub, width, height, byteCounts, 0, compression == PSD.COMPRESSION_RLE);
+ read8bitChannel(c, imageType.getNumBands(), raster.getDataBuffer(), interleavedBands, bandOffset, sourceCM, row8, area, area, xsub,
+ ysub, width, height, byteCounts, 0, compression == PSD.COMPRESSION_RLE);
break;
case 16:
short[] row16 = ((DataBufferUShort) rowRaster.getDataBuffer()).getData();
- read16bitChannel(c, imageType.getNumBands(), raster.getDataBuffer(), interleavedBands, bandOffset, sourceCM, row16, area, area, xsub, ysub, width, height, byteCounts, 0, compression == PSD.COMPRESSION_RLE);
+ read16bitChannel(c, imageType.getNumBands(), raster.getDataBuffer(), interleavedBands, bandOffset, sourceCM, row16, area, area, xsub,
+ ysub, width, height, byteCounts, 0, compression == PSD.COMPRESSION_RLE);
+ break;
+ case 32:
+ int[] row32 = ((DataBufferInt) rowRaster.getDataBuffer()).getData();
+ read32bitChannel(c, imageType.getNumBands(), raster.getDataBuffer(), interleavedBands, bandOffset, sourceCM, row32, area, area, xsub,
+ ysub, width, height, byteCounts, 0, compression == PSD.COMPRESSION_RLE);
break;
default:
throw new IIOException(String.format("Unknown PSD bit depth: %s", header.bits));
@@ -1024,16 +1111,16 @@ public class PSDImageReader extends ImageReaderBase {
// If layer has more channels than composite data, it's normally extra alpha...
if (layerInfo.channelInfo.length > compositeType.getNumBands()) {
- // ...but, it could also be just the user mask...
- boolean userMask = false;
+ // ...but, it could also be just one of the user masks...
+ int newBandNum = 0;
+
for (PSDChannelInfo channelInfo : layerInfo.channelInfo) {
- if (channelInfo.channelId == -2) {
- userMask = true;
- break;
+ // -2 = user supplied layer mask, -3 real user supplied layer mask (when both a user mask and a vector mask are present)
+ if (channelInfo.channelId >= -1) {
+ newBandNum++;
}
}
- int newBandNum = layerInfo.channelInfo.length - (userMask ? 1 : 0);
// If there really is more channels, then create new imageTypeSpec
if (newBandNum > compositeType.getNumBands()) {
@@ -1056,30 +1143,28 @@ public class PSDImageReader extends ImageReaderBase {
/// Layer support
+ @Override protected void checkBounds(final int index) throws IOException {
+ // Avoid parsing layer stuff, if we just want to read the composite data
+ if (index == 0) {
+ assertInput();
+ readLayerAndMaskInfo(false);
+ }
+ else {
+ super.checkBounds(index);
+ }
+ }
+
@Override
public int getNumImages(boolean allowSearch) throws IOException {
// NOTE: Spec says this method should throw IllegalStateException if allowSearch && isSeekForwardOnly()
// But that makes no sense for a format (like PSD) that does not need to search, right?
- readHeader();
- readImageResources(false);
- readLayerAndMaskInfo(true); // TODO: Consider quicker reading of just the number of layers.
+ readLayerAndMaskInfo(true);
return metadata.layerInfo != null ? metadata.layerInfo.size() + 1 : 1; // TODO: Only plus one, if "has real merged data"?
}
- // TODO: For now, leave as Metadata
-
- /*
-
- // ?
- Point getOffset(int pImageIndex) throws IOException;
- // Return 0, 0 for index 0, otherwise use layer offset
-
- */
-
/// Metadata support
- // TODO
@Override
public IIOMetadata getStreamMetadata() throws IOException {
@@ -1090,20 +1175,15 @@ public class PSDImageReader extends ImageReaderBase {
@Override
public IIOMetadata getImageMetadata(final int imageIndex) throws IOException {
- // TODO: Implement
checkBounds(imageIndex);
- readHeader();
readImageResources(true);
readLayerAndMaskInfo(true);
- // TODO: Need to make sure compression is set in metadata, even without reading the image data!
+ // NOTE: Need to make sure compression is set in metadata, even without reading the image data!
+ imageInput.seek(metadata.imageDataStart);
metadata.compression = imageInput.readShort();
-// metadata.header = header;
-// metadata.colorData = colorData;
-// metadata.imageResources = imageResources;
-
return metadata; // TODO: clone if we change to mutable metadata
}
@@ -1129,8 +1209,6 @@ public class PSDImageReader extends ImageReaderBase {
if (metadata.imageResources == null) {
// TODO: Need flag here, to specify what resources to read...
readImageResources(true);
- // TODO: Skip this, requires storing some stream offsets
- readLayerAndMaskInfo(false);
}
for (PSDImageResource resource : metadata.imageResources) {
@@ -1236,84 +1314,89 @@ public class PSDImageReader extends ImageReaderBase {
PSDImageReader imageReader = new PSDImageReader(null);
- File file = new File(pArgs[idx]);
- ImageInputStream stream = ImageIO.createImageInputStream(file);
- imageReader.setInput(stream);
+ for (; idx < pArgs.length; idx++) {
+ File file = new File(pArgs[idx]);
+ System.out.println();
+ System.out.println("file: " + file.getAbsolutePath());
- imageReader.readHeader();
-// System.out.println("imageReader.header: " + imageReader.header);
+ ImageInputStream stream = ImageIO.createImageInputStream(file);
+ imageReader.setInput(stream);
+ imageReader.readHeader();
+ System.out.println("imageReader.header: " + imageReader.header);
- imageReader.readImageResources(true);
- System.out.println("imageReader.imageResources: " + imageReader.metadata.imageResources);
- System.out.println();
+ imageReader.readImageResources(true);
+ System.out.println("imageReader.imageResources: " + imageReader.metadata.imageResources);
+ System.out.println();
- imageReader.readLayerAndMaskInfo(true);
- System.out.println("imageReader.layerInfo: " + imageReader.metadata.layerInfo);
-// System.out.println("imageReader.globalLayerMask: " + imageReader.globalLayerMask);
- System.out.println();
+ imageReader.readLayerAndMaskInfo(true);
+ System.out.println("imageReader.layerInfo: " + imageReader.metadata.layerInfo);
+/*
+ // System.out.println("imageReader.globalLayerMask: " + imageReader.globalLayerMask);
+ System.out.println();
- IIOMetadata metadata = imageReader.getImageMetadata(0);
- Node node;
- XMLSerializer serializer;
+ IIOMetadata metadata = imageReader.getImageMetadata(0);
+ Node node;
+ XMLSerializer serializer;
- node = metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
- serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
- serializer.serialize(node, true);
- System.out.println();
+ node = metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
+ serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
+ serializer.serialize(node, true);
+ System.out.println();
- node = metadata.getAsTree(PSDMetadata.NATIVE_METADATA_FORMAT_NAME);
-// serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
- serializer.serialize(node, true);
-
- if (readThumbnails && imageReader.hasThumbnails(0)) {
- int thumbnails = imageReader.getNumThumbnails(0);
- for (int i = 0; i < thumbnails; i++) {
- showIt(imageReader.readThumbnail(0, i), String.format("Thumbnail %d", i));
+ node = metadata.getAsTree(PSDMetadata.NATIVE_METADATA_FORMAT_NAME);
+ // serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
+ serializer.serialize(node, true);
+*/
+ if (readThumbnails && imageReader.hasThumbnails(0)) {
+ int thumbnails = imageReader.getNumThumbnails(0);
+ for (int i = 0; i < thumbnails; i++) {
+ showIt(imageReader.readThumbnail(0, i), String.format("Thumbnail %d", i));
+ }
}
- }
- long start = System.currentTimeMillis();
+ long start = System.currentTimeMillis();
- ImageReadParam param = imageReader.getDefaultReadParam();
+ ImageReadParam param = imageReader.getDefaultReadParam();
- if (sourceRegion != null) {
- param.setSourceRegion(sourceRegion);
- }
-
- if (subsampleFactor > 1) {
- param.setSourceSubsampling(subsampleFactor, subsampleFactor, 0, 0);
- }
-
-// param.setDestinationType(imageReader.getRawImageType(0));
-
- BufferedImage image = imageReader.read(0, param);
- System.out.println("read time: " + (System.currentTimeMillis() - start));
- System.out.println("image: " + image);
-
- if (image.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
- try {
- ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null);
- GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
- image = op.filter(image, gc.createCompatibleImage(image.getWidth(), image.getHeight(), image.getTransparency()));
+ if (sourceRegion != null) {
+ param.setSourceRegion(sourceRegion);
}
- catch (Exception e) {
- e.printStackTrace();
- image = ImageUtil.accelerate(image);
+
+ if (subsampleFactor > 1) {
+ param.setSourceSubsampling(subsampleFactor, subsampleFactor, 0, 0);
}
- System.out.println("conversion time: " + (System.currentTimeMillis() - start));
+
+ // param.setDestinationType(imageReader.getRawImageType(0));
+
+ BufferedImage image = imageReader.read(0, param);
+ System.out.println("read time: " + (System.currentTimeMillis() - start));
System.out.println("image: " + image);
- }
- showIt(image, file.getName());
+ if (image.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
+ try {
+ ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null);
+ GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
+ image = op.filter(image, gc.createCompatibleImage(image.getWidth(), image.getHeight(), image.getTransparency()));
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ image = ImageUtil.accelerate(image);
+ }
+ System.out.println("conversion time: " + (System.currentTimeMillis() - start));
+ System.out.println("image: " + image);
+ }
- if (readLayers) {
- int images = imageReader.getNumImages(true);
- for (int i = 1; i < images; i++) {
- start = System.currentTimeMillis();
- BufferedImage layer = imageReader.read(i);
- System.out.println("layer read time: " + (System.currentTimeMillis() - start));
- System.err.println("layer: " + layer);
- showIt(layer, "layer " + i);
+ showIt(image, file.getName());
+
+ if (readLayers) {
+ int images = imageReader.getNumImages(true);
+ for (int i = 1; i < images; i++) {
+ start = System.currentTimeMillis();
+ BufferedImage layer = imageReader.read(i);
+ System.out.println("layer read time: " + (System.currentTimeMillis() - start));
+ System.err.println("layer: " + layer);
+ showIt(layer, "layer " + i);
+ }
}
}
}
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderSpi.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderSpi.java
index 16267b70..831d08dc 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderSpi.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderSpi.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,7 @@ import java.util.Locale;
* @author last modified by $Author: haraldk$
* @version $Id: PSDImageReaderSpi.java,v 1.0 Apr 29, 2008 4:49:03 PM haraldk Exp$
*/
-public class PSDImageReaderSpi extends ImageReaderSpi {
+final public class PSDImageReaderSpi extends ImageReaderSpi {
/**
* Creates a {@code PSDImageReaderSpi}.
@@ -57,18 +57,18 @@ public class PSDImageReaderSpi extends ImageReaderSpi {
super(
providerInfo.getVendorName(),
providerInfo.getVersion(),
- new String[]{"psd", "PSD"},
- new String[]{"psd"},
- new String[]{
+ new String[] {"psd", "PSD"},
+ new String[] {"psd"},
+ new String[] {
"image/vnd.adobe.photoshop", // Official, IANA registered
- "application/vnd.adobe.photoshop", // Used in XMP
- "image/x-psd",
- "application/x-photoshop",
+ "application/vnd.adobe.photoshop", // Used in XMP
+ "image/x-psd",
+ "application/x-photoshop",
"image/x-photoshop"
},
"com.twelvemkonkeys.imageio.plugins.psd.PSDImageReader",
new Class[] {ImageInputStream.class},
-// new String[]{"com.twelvemkonkeys.imageio.plugins.psd.PSDImageWriterSpi"},
+// new String[] {"com.twelvemkonkeys.imageio.plugins.psd.PSDImageWriterSpi"},
null,
true, // supports standard stream metadata
null, null, // native stream format name and class
@@ -87,9 +87,23 @@ public class PSDImageReaderSpi extends ImageReaderSpi {
ImageInputStream stream = (ImageInputStream) pSource;
stream.mark();
+
try {
- return stream.readInt() == PSD.SIGNATURE_8BPS;
- // TODO: Test more of the header, see PSDImageReader#readHeader
+ if (stream.readInt() == PSD.SIGNATURE_8BPS) {
+ int version = stream.readUnsignedShort();
+
+ switch (version) {
+ case PSD.VERSION_PSD:
+ case PSD.VERSION_PSB:
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
}
finally {
stream.reset();
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageResource.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageResource.java
old mode 100644
new mode 100755
index 3ea653f1..c3ba9809
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageResource.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageResource.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -110,7 +110,7 @@ public class PSDImageResource {
builder.append("[ID: 0x");
builder.append(Integer.toHexString(id));
- if (name != null && name.trim().length() != 0) {
+ if (name != null && !name.trim().isEmpty()) {
builder.append(", name: \"");
builder.append(name);
builder.append("\"");
@@ -139,6 +139,13 @@ public class PSDImageResource {
case PSD.RES_PRINT_FLAGS_INFORMATION:
return null;
default:
+ if (pId >= PSD.RES_PATH_INFO_MIN && pId <= PSD.RES_PATH_INFO_MAX) {
+ return "PathInformationResource";
+ }
+ if (pId >= PSD.RES_PLUGIN_MIN && pId <= PSD.RES_PLUGIN_MAX) {
+ return "PluginResource";
+ }
+
try {
for (Field field : PSD.class.getDeclaredFields()) {
if (field.getName().startsWith("RES_") && field.getInt(null) == pId) {
@@ -149,7 +156,7 @@ public class PSDImageResource {
}
catch (IllegalAccessException ignore) {
}
-
+
return "UnknownResource";
}
}
@@ -160,9 +167,9 @@ public class PSDImageResource {
throw new IIOException(String.format("Wrong image resource type, expected '8BIM': '%s'", PSDUtil.intToStr(type)));
}
- // TODO: Process more of the resource stuff, most important are IPTC, EXIF and XMP data,
- // version info, and thumbnail for thumbnail-support.
+ // TODO: Have PSDImageResources defer actual parsing? (Just store stream offsets)
short id = pInput.readShort();
+
switch (id) {
case PSD.RES_RESOLUTION_INFO:
return new PSDResolutionInfo(id, pInput);
@@ -196,9 +203,8 @@ public class PSDImageResource {
case PSD.RES_PRINT_FLAGS_INFORMATION:
return new PSDPrintFlagsInformation(id, pInput);
default:
- if (id >= 0x07d0 && id <= 0x0bb6) {
- // TODO: Parse saved path information
- return new PSDImageResource(id, pInput);
+ if (id >= PSD.RES_PATH_INFO_MIN && id <= PSD.RES_PATH_INFO_MAX) {
+ return new PSDPathResource(id, pInput);
}
else {
return new PSDImageResource(id, pInput);
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerBlendMode.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerBlendMode.java
index f18b6071..e6035e69 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerBlendMode.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerBlendMode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@ import java.io.IOException;
* @author last modified by $Author: haraldk$
* @version $Id: PSDLayerBlendMode.java,v 1.0 May 8, 2008 4:34:35 PM haraldk Exp$
*/
-class PSDLayerBlendMode {
+final class PSDLayerBlendMode {
final int blendMode;
final int opacity; // 0-255
final int clipping; // 0: base, 1: non-base
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerInfo.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerInfo.java
index b9e2f07e..5b50196b 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerInfo.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,7 @@ import java.util.Arrays;
* @author last modified by $Author: haraldk$
* @version $Id: PSDLayerInfo.java,v 1.0 Apr 29, 2008 6:01:12 PM haraldk Exp$
*/
-class PSDLayerInfo {
+final class PSDLayerInfo {
final int top;
final int left;
final int bottom;
@@ -52,7 +52,7 @@ class PSDLayerInfo {
final PSDChannelSourceDestinationRange[] ranges;
final String layerName;
- PSDLayerInfo(ImageInputStream pInput) throws IOException {
+ PSDLayerInfo(final boolean largeFormat, final ImageInputStream pInput) throws IOException {
top = pInput.readInt();
left = pInput.readInt();
bottom = pInput.readInt();
@@ -63,7 +63,7 @@ class PSDLayerInfo {
channelInfo = new PSDChannelInfo[channels];
for (int i = 0; i < channels; i++) {
short channelId = pInput.readShort();
- long length = pInput.readUnsignedInt();
+ long length = largeFormat ? pInput.readLong() : pInput.readUnsignedInt();
channelInfo[i] = new PSDChannelInfo(channelId, length);
}
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerMaskData.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerMaskData.java
index 16a4bd83..55782e8c 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerMaskData.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDLayerMaskData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@ import java.io.IOException;
* @author last modified by $Author: haraldk$
* @version $Id: PSDLayerMaskData.java,v 1.0 May 6, 2008 5:15:05 PM haraldk Exp$
*/
-class PSDLayerMaskData {
+final class PSDLayerMaskData {
private int top;
private int left;
private int bottom;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadata.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadata.java
old mode 100644
new mode 100755
index 4bbb542c..1f6bbffd
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadata.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadata.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import com.twelvemonkeys.imageio.metadata.Directory;
@@ -35,7 +63,11 @@ public final class PSDMetadata extends AbstractMetadata {
List imageResources;
PSDGlobalLayerMask globalLayerMask;
List layerInfo;
+
+ long imageResourcesStart;
+ long layerAndMaskInfoStart;
long layersStart;
+ long imageDataStart;
static final String[] COLOR_MODES = {
"MONOCHROME", "GRAYSCALE", "INDEXED", "RGB", "CMYK", null, null, "MULTICHANNEL", "DUOTONE", "LAB"
@@ -85,17 +117,17 @@ public final class PSDMetadata extends AbstractMetadata {
}
private Node createHeaderNode() {
- IIOMetadataNode header = new IIOMetadataNode("Header");
+ IIOMetadataNode headerNode = new IIOMetadataNode("Header");
- header.setAttribute("type", "PSD");
- header.setAttribute("version", "1");
- header.setAttribute("channels", Integer.toString(this.header.channels));
- header.setAttribute("height", Integer.toString(this.header.height));
- header.setAttribute("width", Integer.toString(this.header.width));
- header.setAttribute("bits", Integer.toString(this.header.bits));
- header.setAttribute("mode", COLOR_MODES[this.header.mode]);
+ headerNode.setAttribute("type", "PSD");
+ headerNode.setAttribute("version", header.largeFormat ? "2" : "1");
+ headerNode.setAttribute("channels", Integer.toString(header.channels));
+ headerNode.setAttribute("height", Integer.toString(header.height));
+ headerNode.setAttribute("width", Integer.toString(header.width));
+ headerNode.setAttribute("bits", Integer.toString(header.bits));
+ headerNode.setAttribute("mode", COLOR_MODES[header.mode]);
- return header;
+ return headerNode;
}
private Node createImageResourcesNode() {
@@ -112,18 +144,6 @@ public final class PSDMetadata extends AbstractMetadata {
// TODO: Format spec
node = new IIOMetadataNode("ICCProfile");
node.setAttribute("colorSpaceType", JAVA_CS[profile.getProfile().getColorSpaceType()]);
-//
-// FastByteArrayOutputStream data = new FastByteArrayOutputStream(0);
-// EncoderStream base64 = new EncoderStream(data, new Base64Encoder(), true);
-//
-// try {
-// base64.write(profile.getProfile().getData());
-// }
-// catch (IOException ignore) {
-// }
-//
-// byte[] bytes = data.toByteArray();
-// node.setAttribute("data", StringUtil.decode(bytes, 0, bytes.length, "ASCII"));
node.setUserObject(profile.getProfile());
}
else if (imageResource instanceof PSDAlphaChannelInfo) {
@@ -347,13 +367,12 @@ public final class PSDMetadata extends AbstractMetadata {
@Override
protected IIOMetadataNode getStandardChromaNode() {
- IIOMetadataNode chroma_node = new IIOMetadataNode("Chroma");
- IIOMetadataNode node; // scratch node
+ IIOMetadataNode chroma = new IIOMetadataNode("Chroma");
- node = new IIOMetadataNode("ColorSpaceType");
+ IIOMetadataNode colorSpaceType = new IIOMetadataNode("ColorSpaceType");
String cs;
switch (header.mode) {
- case PSD.COLOR_MODE_MONOCHROME:
+ case PSD.COLOR_MODE_BITMAP:
case PSD.COLOR_MODE_GRAYSCALE:
case PSD.COLOR_MODE_DUOTONE: // Rationale: Spec says treat as gray...
cs = "GRAY";
@@ -374,25 +393,24 @@ public final class PSDMetadata extends AbstractMetadata {
default:
throw new AssertionError("Unreachable");
}
- node.setAttribute("name", cs);
- chroma_node.appendChild(node);
+ colorSpaceType.setAttribute("name", cs);
+ chroma.appendChild(colorSpaceType);
// TODO: Channels might be 5 for RGB + A + Mask... Probably not correct
- node = new IIOMetadataNode("NumChannels");
- node.setAttribute("value", Integer.toString(header.channels));
- chroma_node.appendChild(node);
+ IIOMetadataNode numChannels = new IIOMetadataNode("NumChannels");
+ numChannels.setAttribute("value", Integer.toString(header.channels));
+ chroma.appendChild(numChannels);
- // TODO: Check if this is correct with bitmap (monchrome)
- node = new IIOMetadataNode("BlackIsZero");
- node.setAttribute("value", "true");
- chroma_node.appendChild(node);
+ IIOMetadataNode blackIsZero = new IIOMetadataNode("BlackIsZero");
+ blackIsZero.setAttribute("value", "true");
+ chroma.appendChild(blackIsZero);
if (header.mode == PSD.COLOR_MODE_INDEXED) {
- node = createPaletteNode();
- chroma_node.appendChild(node);
+ IIOMetadataNode paletteNode = createPaletteNode();
+ chroma.appendChild(paletteNode);
}
- // TODO: Hardcode background color to white?
+ // TODO: Use
// if (bKGD_present) {
// if (bKGD_colorType == PNGImageReader.PNG_COLOR_PALETTE) {
// node = new IIOMetadataNode("BackgroundIndex");
@@ -415,24 +433,25 @@ public final class PSDMetadata extends AbstractMetadata {
// chroma_node.appendChild(node);
// }
- return chroma_node;
+ return chroma;
}
private IIOMetadataNode createPaletteNode() {
- IIOMetadataNode node = new IIOMetadataNode("Palette");
+ IIOMetadataNode palette = new IIOMetadataNode("Palette");
IndexColorModel cm = colorData.getIndexColorModel();
for (int i = 0; i < cm.getMapSize(); i++) {
IIOMetadataNode entry = new IIOMetadataNode("PaletteEntry");
+
entry.setAttribute("index", Integer.toString(i));
entry.setAttribute("red", Integer.toString(cm.getRed(i)));
entry.setAttribute("green", Integer.toString(cm.getGreen(i)));
entry.setAttribute("blue", Integer.toString(cm.getBlue(i)));
- node.appendChild(entry);
+ palette.appendChild(entry);
}
- return node;
+ return palette;
}
private String getMultiChannelCS(short channels) {
@@ -446,33 +465,33 @@ public final class PSDMetadata extends AbstractMetadata {
@Override
protected IIOMetadataNode getStandardCompressionNode() {
IIOMetadataNode compressionNode = new IIOMetadataNode("Compression");
- IIOMetadataNode node; // scratch node
- node = new IIOMetadataNode("CompressionTypeName");
- String compression;
+ IIOMetadataNode compressionTypeName = new IIOMetadataNode("CompressionTypeName");
+ String compressionName;
- switch (this.compression) {
+ switch (compression) {
case PSD.COMPRESSION_NONE:
- compression = "none";
+ compressionName = "none";
break;
case PSD.COMPRESSION_RLE:
- compression = "PackBits";
+ compressionName = "PackBits";
break;
case PSD.COMPRESSION_ZIP:
case PSD.COMPRESSION_ZIP_PREDICTION:
- compression = "Deflate"; // TODO: ZLib? (TIFF native metadata format specifies both.. :-P)
+ compressionName = "Zip";
break;
default:
throw new AssertionError("Unreachable");
}
- node.setAttribute("value", compression);
- compressionNode.appendChild(node);
+ compressionTypeName.setAttribute("value", compressionName);
+ compressionNode.appendChild(compressionTypeName);
- // TODO: Does it make sense to specify lossless for compression "none"?
- node = new IIOMetadataNode("Lossless");
- node.setAttribute("value", "true");
- compressionNode.appendChild(node);
+ if (compression != PSD.COMPRESSION_NONE) {
+ IIOMetadataNode lossless = new IIOMetadataNode("Lossless");
+ lossless.setAttribute("value", "true");
+ compressionNode.appendChild(lossless);
+ }
return compressionNode;
}
@@ -480,15 +499,14 @@ public final class PSDMetadata extends AbstractMetadata {
@Override
protected IIOMetadataNode getStandardDataNode() {
IIOMetadataNode dataNode = new IIOMetadataNode("Data");
- IIOMetadataNode node; // scratch node
- node = new IIOMetadataNode("PlanarConfiguration");
- node.setAttribute("value", "PlaneInterleaved"); // TODO: Check with spec
- dataNode.appendChild(node);
+ IIOMetadataNode planarConfiguration = new IIOMetadataNode("PlanarConfiguration");
+ planarConfiguration.setAttribute("value", "PlaneInterleaved");
+ dataNode.appendChild(planarConfiguration);
- node = new IIOMetadataNode("SampleFormat");
- node.setAttribute("value", header.mode == PSD.COLOR_MODE_INDEXED ? "Index" : "UnsignedIntegral");
- dataNode.appendChild(node);
+ IIOMetadataNode sampleFormat = new IIOMetadataNode("SampleFormat");
+ sampleFormat.setAttribute("value", header.mode == PSD.COLOR_MODE_INDEXED ? "Index" : "UnsignedIntegral");
+ dataNode.appendChild(sampleFormat);
String bitDepth = Integer.toString(header.bits); // bits per plane
@@ -496,11 +514,9 @@ public final class PSDMetadata extends AbstractMetadata {
String[] bps = new String[header.channels];
Arrays.fill(bps, bitDepth);
- node = new IIOMetadataNode("BitsPerSample");
- node.setAttribute("value", StringUtil.toCSVString(bps, " "));
- dataNode.appendChild(node);
-
- // TODO: SampleMSB? Or is network (aka Motorola/big endian) byte order assumed?
+ IIOMetadataNode bitsPerSample = new IIOMetadataNode("BitsPerSample");
+ bitsPerSample.setAttribute("value", StringUtil.toCSVString(bps, " "));
+ dataNode.appendChild(bitsPerSample);
return dataNode;
}
@@ -542,33 +558,6 @@ public final class PSDMetadata extends AbstractMetadata {
dimensionNode.appendChild(node);
}
- // TODO:
- /*
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- */
return dimensionNode;
}
@@ -580,11 +569,10 @@ public final class PSDMetadata extends AbstractMetadata {
@Override
protected IIOMetadataNode getStandardDocumentNode() {
IIOMetadataNode document_node = new IIOMetadataNode("Document");
- IIOMetadataNode node; // scratch node
- node = new IIOMetadataNode("FormatVersion");
- node.setAttribute("value", "1"); // PSD format version is always 1
- document_node.appendChild(node);
+ IIOMetadataNode formatVersion = new IIOMetadataNode("FormatVersion");
+ formatVersion.setAttribute("value", header.largeFormat ? "2" : "1"); // PSD format version is always 1, PSB is 2
+ document_node.appendChild(formatVersion);
// Get EXIF data if present
Iterator exif = getResources(PSDEXIF1Data.class);
@@ -594,18 +582,18 @@ public final class PSDMetadata extends AbstractMetadata {
// Get the EXIF DateTime (aka ModifyDate) tag if present
Entry dateTime = data.directory.getEntryById(TIFF.TAG_DATE_TIME);
if (dateTime != null) {
- node = new IIOMetadataNode("ImageCreationTime"); // As TIFF, but could just as well be ImageModificationTime
+ IIOMetadataNode imageCreationTime = new IIOMetadataNode("ImageCreationTime"); // As TIFF, but could just as well be ImageModificationTime
// Format: "YYYY:MM:DD hh:mm:ss"
String value = dateTime.getValueAsString();
- node.setAttribute("year", value.substring(0, 4));
- node.setAttribute("month", value.substring(5, 7));
- node.setAttribute("day", value.substring(8, 10));
- node.setAttribute("hour", value.substring(11, 13));
- node.setAttribute("minute", value.substring(14, 16));
- node.setAttribute("second", value.substring(17, 19));
+ imageCreationTime.setAttribute("year", value.substring(0, 4));
+ imageCreationTime.setAttribute("month", value.substring(5, 7));
+ imageCreationTime.setAttribute("day", value.substring(8, 10));
+ imageCreationTime.setAttribute("hour", value.substring(11, 13));
+ imageCreationTime.setAttribute("minute", value.substring(14, 16));
+ imageCreationTime.setAttribute("second", value.substring(17, 19));
- document_node.appendChild(node);
+ document_node.appendChild(imageCreationTime);
}
}
@@ -614,7 +602,7 @@ public final class PSDMetadata extends AbstractMetadata {
@Override
protected IIOMetadataNode getStandardTextNode() {
- // TODO: TIFF uses
+ // NOTE: TIFF uses
// DocumentName, ImageDescription, Make, Model, PageName, Software, Artist, HostComputer, InkNames, Copyright:
// /Text/TextEntry@keyword = field name, /Text/TextEntry@value = field value.
// Example: TIFF Software field => /Text/TextEntry@keyword = "Software",
@@ -679,9 +667,10 @@ public final class PSDMetadata extends AbstractMetadata {
}
private void appendTextEntriesFlat(final IIOMetadataNode node, final Directory directory, final FilterIterator.Filter filter) {
- FilterIterator pEntries = new FilterIterator(directory.iterator(), filter);
- while (pEntries.hasNext()) {
- Entry entry = pEntries.next();
+ FilterIterator entries = new FilterIterator(directory.iterator(), filter);
+
+ while (entries.hasNext()) {
+ Entry entry = entries.next();
if (entry.getValue() instanceof Directory) {
appendTextEntriesFlat(node, (Directory) entry.getValue(), filter);
@@ -694,7 +683,7 @@ public final class PSDMetadata extends AbstractMetadata {
tag.setAttribute("keyword", fieldName);
}
else {
- // TODO: This should never happen, as we filter out only specific nodes
+ // NOTE: This should never happen, as we filter out only specific nodes
tag.setAttribute("keyword", String.format("%s", entry.getIdentifier()));
}
@@ -711,14 +700,13 @@ public final class PSDMetadata extends AbstractMetadata {
@Override
protected IIOMetadataNode getStandardTransparencyNode() {
- IIOMetadataNode transparency_node = new IIOMetadataNode("Transparency");
- IIOMetadataNode node; // scratch node
+ IIOMetadataNode transparencyNode = new IIOMetadataNode("Transparency");
- node = new IIOMetadataNode("Alpha");
- node.setAttribute("value", hasAlpha() ? "nonpremultiplied" : "none"); // TODO: Check spec
- transparency_node.appendChild(node);
+ IIOMetadataNode node = new IIOMetadataNode("Alpha");
+ node.setAttribute("value", hasAlpha() ? "premultiplied" : "none");
+ transparencyNode.appendChild(node);
- return transparency_node;
+ return transparencyNode;
}
private boolean hasAlpha() {
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadataFormat.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadataFormat.java
old mode 100644
new mode 100755
index 4d19eec9..c6df5c3e
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadataFormat.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadataFormat.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import com.twelvemonkeys.imageio.metadata.Directory;
@@ -17,7 +45,7 @@ import java.util.Arrays;
*/
public final class PSDMetadataFormat extends IIOMetadataFormatImpl {
- private final static PSDMetadataFormat sInstance = new PSDMetadataFormat();
+ private static final PSDMetadataFormat instance = new PSDMetadataFormat();
/**
* Private constructor.
@@ -207,6 +235,6 @@ public final class PSDMetadataFormat extends IIOMetadataFormatImpl {
* @see javax.imageio.metadata.IIOMetadata#getMetadataFormat
*/
public static PSDMetadataFormat getInstance() {
- return sInstance;
+ return instance;
}
}
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPathResource.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPathResource.java
new file mode 100755
index 00000000..b9397870
--- /dev/null
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPathResource.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, 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.psd;
+
+import javax.imageio.stream.ImageInputStream;
+import java.io.IOException;
+
+/**
+ * PSDPathResource
+ *
+ * @author Harald Kuhr
+ * @author last modified by $Author: haraldk$
+ * @version $Id: PSDPathResource.java,v 1.0 Sept 4, 2014 8:23:09 PM haraldk Exp$
+ */
+final class PSDPathResource extends PSDImageResource {
+ PSDPathResource(final short resourceId, final ImageInputStream input) throws IOException {
+ super(resourceId, input);
+ }
+}
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPixelAspectRatio.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPixelAspectRatio.java
index fd09b4bf..f2a2d7bb 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPixelAspectRatio.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPixelAspectRatio.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import javax.imageio.stream.ImageInputStream;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintFlags.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintFlags.java
old mode 100644
new mode 100755
index 9d054b52..000dec83
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintFlags.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintFlags.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import javax.imageio.stream.ImageInputStream;
@@ -33,9 +61,13 @@ final class PSDPrintFlags extends PSDImageResource {
negative = pInput.readBoolean();
flip = pInput.readBoolean();
interpolate = pInput.readBoolean();
- caption = pInput.readBoolean();
- pInput.skipBytes(size - 8);
+ // Photoshop 2.5 and before has shorter struct
+ if (size > 7) {
+ caption = pInput.readBoolean();
+
+ pInput.skipBytes(size - 8);
+ }
}
@Override
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintFlagsInformation.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintFlagsInformation.java
index c63c8811..59c45fb0 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintFlagsInformation.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintFlagsInformation.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import javax.imageio.stream.ImageInputStream;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintScale.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintScale.java
index e89e5613..8d4183a1 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintScale.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintScale.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import javax.imageio.stream.ImageInputStream;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDResolutionInfo.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDResolutionInfo.java
index f3943f73..d4558ee5 100755
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDResolutionInfo.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDResolutionInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@ import java.io.IOException;
* @author last modified by $Author: haraldk$
* @version $Id: PSDResolutionInfo.java,v 1.0 May 2, 2008 3:58:19 PM haraldk Exp$
*/
-class PSDResolutionInfo extends PSDImageResource {
+final class PSDResolutionInfo extends PSDImageResource {
// typedef struct _ResolutionInfo
// {
// LONG hRes; /* Fixed-point number: pixels per inch */
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDThumbnail.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDThumbnail.java
old mode 100644
new mode 100755
index 31c2352f..bf0df7ba
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDThumbnail.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDThumbnail.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import javax.imageio.IIOException;
@@ -16,7 +44,7 @@ import java.io.IOException;
* @author last modified by $Author: haraldk$
* @version $Id: PSDThumbnail.java,v 1.0 Jul 29, 2009 4:41:06 PM haraldk Exp$
*/
-class PSDThumbnail extends PSDImageResource {
+final class PSDThumbnail extends PSDImageResource {
private int format;
private int width;
private int height;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUnicodeAlphaNames.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUnicodeAlphaNames.java
index 21f752c1..23705172 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUnicodeAlphaNames.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUnicodeAlphaNames.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import javax.imageio.stream.ImageInputStream;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUtil.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUtil.java
index 9f840406..55f0c840 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUtil.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDVersionInfo.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDVersionInfo.java
index 10210ce8..9ac99f4f 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDVersionInfo.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDVersionInfo.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import javax.imageio.stream.ImageInputStream;
diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDXMPData.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDXMPData.java
index 2e14bc31..dfd6c76c 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDXMPData.java
+++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDXMPData.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import com.twelvemonkeys.imageio.metadata.Directory;
diff --git a/imageio/imageio-psd/src/test/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderTestCase.java b/imageio/imageio-psd/src/test/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderTestCase.java
old mode 100644
new mode 100755
index 34ee100f..a5808c20
--- a/imageio/imageio-psd/src/test/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderTestCase.java
+++ b/imageio/imageio-psd/src/test/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderTestCase.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.psd;
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase;
@@ -27,7 +55,7 @@ import static org.junit.Assert.*;
*/
public class PSDImageReaderTestCase extends ImageReaderAbstractTestCase {
- static ImageReaderSpi provider = new PSDImageReaderSpi();
+ private static final ImageReaderSpi provider = new PSDImageReaderSpi();
protected List getTestData() {
return Arrays.asList(
@@ -48,7 +76,21 @@ public class PSDImageReaderTestCase extends ImageReaderAbstractTestCase