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