mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-10-03 23:53:15 -04:00
TMI-PSD: Added support for PSB (aka "Large Document Format")
Added support for 32 bit channels. Added test cases + fixed a few bugs General code clean-up
This commit is contained in:
8
imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSD.java
Normal file → Executable file
8
imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSD.java
Normal file → Executable file
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @version $Id: PSD.java,v 1.0 24.01.12 16:51 haraldk Exp$
|
||||||
*/
|
*/
|
||||||
public interface PSD {
|
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;
|
||||||
}
|
}
|
||||||
|
6
imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSDReader.java
Normal file → Executable file
6
imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/psd/PSDReader.java
Normal file → Executable file
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -136,6 +136,10 @@ public final class PSDReader extends MetadataReader {
|
|||||||
pInput.readFully(data);
|
pInput.readFully(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final int id() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
public final byte[] data() {
|
public final byte[] data() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: ICCProfile.java,v 1.0 May 20, 2008 6:24:10 PM haraldk Exp$
|
* @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;
|
private ICC_Profile profile;
|
||||||
|
|
||||||
ICCProfile(final short pId, final ImageInputStream pInput) throws IOException {
|
ICCProfile(final short pId, final ImageInputStream pInput) throws IOException {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSD.java,v 1.0 Apr 29, 2008 4:47:47 PM haraldk Exp$
|
* @version $Id: PSD.java,v 1.0 Apr 29, 2008 4:47:47 PM haraldk Exp$
|
||||||
*
|
*
|
||||||
|
* @see <a href="http://www.adobe.com/devnet-apps/photoshop/fileformatashtml">Adobe Photoshop File Formats Specification</a>
|
||||||
* @see <a href="http://www.fileformat.info/format/psd/egff.htm">http://www.fileformat.info/format/psd/egff.htm</a>
|
* @see <a href="http://www.fileformat.info/format/psd/egff.htm">http://www.fileformat.info/format/psd/egff.htm</a>
|
||||||
*/
|
*/
|
||||||
interface PSD {
|
interface PSD {
|
||||||
/** PSD 2+ Native format (.PSD) identifier "8BPS" */
|
/** PSD 2+ Native format (.PSD) identifier "8BPS" */
|
||||||
int SIGNATURE_8BPS = ('8' << 24) + ('B' << 16) + ('P' << 8) + 'S';
|
int SIGNATURE_8BPS = ('8' << 24) + ('B' << 16) + ('P' << 8) + 'S';
|
||||||
|
|
||||||
|
// TODO: Is this ever used??! Spec says (and sample files uses) 8BPS + version == 2 for PSB...
|
||||||
/** PSD 5+ Large Document Format (.PSB) identifier "8BPB" */
|
/** PSD 5+ Large Document Format (.PSB) identifier "8BPB" */
|
||||||
int SIGNATURE_8BPB = ('8' << 24) + ('B' << 16) + ('P' << 8) + 'B';
|
int SIGNATURE_8BPB = ('8' << 24) + ('B' << 16) + ('P' << 8) + 'B';
|
||||||
|
|
||||||
|
int VERSION_PSD = 1;
|
||||||
|
int VERSION_PSB = 2;
|
||||||
|
|
||||||
/** PSD Resource type identifier "8BIM" */
|
/** PSD Resource type identifier "8BIM" */
|
||||||
int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M';
|
int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M';
|
||||||
|
|
||||||
@@ -105,7 +110,7 @@ interface PSD {
|
|||||||
|
|
||||||
// Color Modes
|
// Color Modes
|
||||||
/** Bitmap (monochrome) */
|
/** Bitmap (monochrome) */
|
||||||
short COLOR_MODE_MONOCHROME = 0;
|
short COLOR_MODE_BITMAP = 0;
|
||||||
|
|
||||||
/** Gray-scale */
|
/** Gray-scale */
|
||||||
short COLOR_MODE_GRAYSCALE = 1;
|
short COLOR_MODE_GRAYSCALE = 1;
|
||||||
@@ -541,4 +546,13 @@ interface PSD {
|
|||||||
*/
|
*/
|
||||||
int RES_PRINT_FLAGS_INFORMATION = 0x2710;
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDAlphaChannelInfo.java,v 1.0 May 2, 2008 5:33:40 PM haraldk Exp$
|
* @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<String> names;
|
List<String> names;
|
||||||
|
|
||||||
public PSDAlphaChannelInfo(short pId, final ImageInputStream pInput) throws IOException {
|
public PSDAlphaChannelInfo(short pId, final ImageInputStream pInput) throws IOException {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDChannelInfo.java,v 1.0 May 6, 2008 2:46:23 PM haraldk Exp$
|
* @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 short channelId;
|
||||||
final long length;
|
final long length;
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDChannelSourceDestinationRange.java,v 1.0 May 6, 2008 5:14:13 PM haraldk Exp$
|
* @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 String channel;
|
||||||
private short sourceBlack;
|
private short sourceBlack;
|
||||||
private short sourceWhite;
|
private short sourceWhite;
|
||||||
|
4
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDColorData.java
Normal file → Executable file
4
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDColorData.java
Normal file → Executable file
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDColorData.java,v 1.0 Apr 29, 2008 5:33:01 PM haraldk Exp$
|
* @version $Id: PSDColorData.java,v 1.0 Apr 29, 2008 5:33:01 PM haraldk Exp$
|
||||||
*/
|
*/
|
||||||
class PSDColorData {
|
final class PSDColorData {
|
||||||
final byte[] colors;
|
final byte[] colors;
|
||||||
private IndexColorModel colorModel;
|
private IndexColorModel colorModel;
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDResolutionInfo.java,v 1.0 May 2, 2008 3:58:19 PM haraldk Exp$
|
* @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
|
// TODO: Size of this struct should be 14.. Does not compute... Something bogus here
|
||||||
|
|
||||||
// ColorSpace definitions:
|
// ColorSpace definitions:
|
||||||
|
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDGlobalLayerMask.java,v 1.0 May 8, 2008 5:33:48 PM haraldk Exp$
|
* @version $Id: PSDGlobalLayerMask.java,v 1.0 May 8, 2008 5:33:48 PM haraldk Exp$
|
||||||
*/
|
*/
|
||||||
class PSDGlobalLayerMask {
|
final class PSDGlobalLayerMask {
|
||||||
final int colorSpace;
|
final int colorSpace;
|
||||||
final int color1;
|
final int color1;
|
||||||
final int color2;
|
final int color2;
|
||||||
final int color3;
|
final int color3;
|
||||||
|
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
152
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDHeader.java
Normal file → Executable file
152
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDHeader.java
Normal file → Executable file
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -28,8 +28,9 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.imageio.plugins.psd;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
|
||||||
import javax.imageio.IIOException;
|
import javax.imageio.IIOException;
|
||||||
|
|
||||||
|
import java.io.DataInput;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,19 +40,21 @@ import java.io.IOException;
|
|||||||
* @author last modified by $Author: haraldk$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDHeader.java,v 1.0 Apr 29, 2008 5:18:22 PM haraldk Exp$
|
* @version $Id: PSDHeader.java,v 1.0 Apr 29, 2008 5:18:22 PM haraldk Exp$
|
||||||
*/
|
*/
|
||||||
class PSDHeader {
|
final class PSDHeader {
|
||||||
// The header is 26 bytes in length and is structured as follows:
|
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
|
// typedef struct _PSD_HEADER
|
||||||
// {
|
// {
|
||||||
// BYTE Signature[4]; /* File ID "8BPS" */
|
// 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 */
|
// 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 */
|
// channels */
|
||||||
// LONG Rows; /* Height of image in pixels (1-30000) */
|
// LONG Rows; /* Height of image in pixels (1-30000/1-300000 for PSB) */
|
||||||
// LONG Columns; /* Width of image in pixels (1-30000) */
|
// LONG Columns; /* Width of image in pixels (1-30000/1-300000 for PSB) */
|
||||||
// WORD Depth; /* Number of bits per channel (1, 8, and 16) */
|
// WORD Depth; /* Number of bits per channel (1, 8, 16 or 32) */
|
||||||
// WORD Mode; /* Color mode */
|
// WORD Mode; /* Color mode */
|
||||||
// } PSD_HEADER;
|
// } PSD_HEADER;
|
||||||
|
|
||||||
@@ -60,8 +63,9 @@ class PSDHeader {
|
|||||||
final int height;
|
final int height;
|
||||||
final short bits;
|
final short bits;
|
||||||
final short mode;
|
final short mode;
|
||||||
|
final boolean largeFormat;
|
||||||
|
|
||||||
PSDHeader(final ImageInputStream pInput) throws IOException {
|
PSDHeader(final DataInput pInput) throws IOException {
|
||||||
int signature = pInput.readInt();
|
int signature = pInput.readInt();
|
||||||
if (signature != PSD.SIGNATURE_8BPS) {
|
if (signature != PSD.SIGNATURE_8BPS) {
|
||||||
throw new IIOException("Not a PSD document, expected signature \"8BPS\": \"" + PSDUtil.intToStr(signature) + "\" (0x" + Integer.toHexString(signature) + ")");
|
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();
|
int version = pInput.readUnsignedShort();
|
||||||
|
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case 1:
|
case PSD.VERSION_PSD:
|
||||||
|
largeFormat = false;
|
||||||
|
break;
|
||||||
|
case PSD.VERSION_PSB:
|
||||||
|
largeFormat = true;
|
||||||
break;
|
break;
|
||||||
case 2:
|
|
||||||
throw new IIOException("Photoshop Large Document Format (PSB) not supported yet.");
|
|
||||||
default:
|
default:
|
||||||
throw new IIOException(String.format("Unknown PSD version, expected 1 or 2: 0x%08x", version));
|
throw new IIOException(String.format("Unknown PSD version, expected 1 or 2: 0x%08x", version));
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] reserved = new byte[6];
|
byte[] reserved = new byte[6];
|
||||||
pInput.readFully(reserved);
|
pInput.readFully(reserved); // We don't really care
|
||||||
|
|
||||||
channels = pInput.readShort();
|
channels = pInput.readShort();
|
||||||
|
if (channels <= 0) {
|
||||||
|
throw new IIOException(String.format("Unsupported number of channels: %d", channels));
|
||||||
|
}
|
||||||
|
|
||||||
height = pInput.readInt(); // Rows
|
height = pInput.readInt(); // Rows
|
||||||
width = pInput.readInt(); // Columns
|
width = pInput.readInt(); // Columns
|
||||||
|
|
||||||
bits = pInput.readShort();
|
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();
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder(getClass().getSimpleName());
|
return new StringBuilder(getClass().getSimpleName())
|
||||||
builder.append("[Channels: ");
|
.append("[version: ")
|
||||||
builder.append(channels);
|
.append(largeFormat ? "2" : "1")
|
||||||
builder.append(", width: ");
|
.append(", channels: ")
|
||||||
builder.append(width);
|
.append(channels)
|
||||||
builder.append(", height: ");
|
.append(", width: ")
|
||||||
builder.append(height);
|
.append(width)
|
||||||
builder.append(", depth: ");
|
.append(", height: ")
|
||||||
builder.append(bits);
|
.append(height)
|
||||||
builder.append(", mode: ");
|
.append(", depth: ")
|
||||||
builder.append(mode);
|
.append(bits)
|
||||||
switch (mode) {
|
.append(", mode: ")
|
||||||
case PSD.COLOR_MODE_MONOCHROME:
|
.append(mode)
|
||||||
builder.append(" (Monochrome)");
|
.append(" (")
|
||||||
break;
|
.append(modeAsString())
|
||||||
case PSD.COLOR_MODE_GRAYSCALE:
|
.append(")]")
|
||||||
builder.append(" (Grayscale)");
|
.toString();
|
||||||
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 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";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||||
|
543
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReader.java
Normal file → Executable file
543
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReader.java
Normal file → Executable file
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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.ImageReaderBase;
|
||||||
import com.twelvemonkeys.imageio.color.ColorSpaces;
|
import com.twelvemonkeys.imageio.color.ColorSpaces;
|
||||||
import com.twelvemonkeys.imageio.util.IndexedImageTypeSpecifier;
|
import com.twelvemonkeys.imageio.util.IndexedImageTypeSpecifier;
|
||||||
import com.twelvemonkeys.xml.XMLSerializer;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
|
|
||||||
import javax.imageio.IIOException;
|
import javax.imageio.IIOException;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.imageio.ImageReadParam;
|
import javax.imageio.ImageReadParam;
|
||||||
import javax.imageio.ImageTypeSpecifier;
|
import javax.imageio.ImageTypeSpecifier;
|
||||||
import javax.imageio.metadata.IIOMetadata;
|
import javax.imageio.metadata.IIOMetadata;
|
||||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
|
||||||
import javax.imageio.spi.ImageReaderSpi;
|
import javax.imageio.spi.ImageReaderSpi;
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@@ -70,12 +67,12 @@ import java.util.List;
|
|||||||
// See http://www.codeproject.com/KB/graphics/PSDParser.aspx
|
// See http://www.codeproject.com/KB/graphics/PSDParser.aspx
|
||||||
// See http://www.adobeforums.com/webx?14@@.3bc381dc/0
|
// See http://www.adobeforums.com/webx?14@@.3bc381dc/0
|
||||||
// Done: Allow reading the extra alpha channels (index after composite data)
|
// 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 PSDHeader header;
|
||||||
private ICC_ColorSpace colorSpace;
|
private ICC_ColorSpace colorSpace;
|
||||||
protected PSDMetadata metadata;
|
private PSDMetadata metadata;
|
||||||
|
|
||||||
protected PSDImageReader(final ImageReaderSpi originatingProvider) {
|
PSDImageReader(final ImageReaderSpi originatingProvider) {
|
||||||
super(originatingProvider);
|
super(originatingProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,10 +105,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getLayerWidth(int layerIndex) throws IOException {
|
private int getLayerWidth(int layerIndex) throws IOException {
|
||||||
if (metadata == null || metadata.layerInfo == null) {
|
readLayerAndMaskInfo(true);
|
||||||
readImageResources(false);
|
|
||||||
readLayerAndMaskInfo(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
PSDLayerInfo layerInfo = metadata.layerInfo.get(layerIndex);
|
PSDLayerInfo layerInfo = metadata.layerInfo.get(layerIndex);
|
||||||
|
|
||||||
@@ -119,10 +113,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getLayerHeight(int layerIndex) throws IOException {
|
private int getLayerHeight(int layerIndex) throws IOException {
|
||||||
if (metadata == null || metadata.layerInfo == null) {
|
readLayerAndMaskInfo(true);
|
||||||
readImageResources(false);
|
|
||||||
readLayerAndMaskInfo(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
PSDLayerInfo layerInfo = metadata.layerInfo.get(layerIndex);
|
PSDLayerInfo layerInfo = metadata.layerInfo.get(layerIndex);
|
||||||
|
|
||||||
@@ -136,14 +127,10 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
private ImageTypeSpecifier getRawImageTypeInternal(final int imageIndex) throws IOException {
|
private ImageTypeSpecifier getRawImageTypeInternal(final int imageIndex) throws IOException {
|
||||||
checkBounds(imageIndex);
|
checkBounds(imageIndex);
|
||||||
readHeader();
|
|
||||||
|
|
||||||
// Image index above 0, means a layer
|
// Image index above 0, means a layer
|
||||||
if (imageIndex > 0) {
|
if (imageIndex > 0) {
|
||||||
if (metadata == null || metadata.layerInfo == null) {
|
readLayerAndMaskInfo(true);
|
||||||
readImageResources(false);
|
|
||||||
readLayerAndMaskInfo(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getRawImageTypeForLayer(imageIndex - 1);
|
return getRawImageTypeForLayer(imageIndex - 1);
|
||||||
}
|
}
|
||||||
@@ -154,46 +141,56 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
private ImageTypeSpecifier getRawImageTypeForCompositeLayer() throws IOException {
|
private ImageTypeSpecifier getRawImageTypeForCompositeLayer() throws IOException {
|
||||||
ColorSpace cs;
|
ColorSpace cs;
|
||||||
|
|
||||||
switch (header.mode) {
|
switch (header.mode) {
|
||||||
case PSD.COLOR_MODE_MONOCHROME:
|
case PSD.COLOR_MODE_BITMAP:
|
||||||
if (header.channels == 1 && header.bits == 1) {
|
if (header.channels == 1 && header.bits == 1) {
|
||||||
return ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
|
return ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IIOException(
|
throw new IIOException(String.format("Unsupported channel count/bit depth for Monochrome PSD: %d channels/%d bits", header.channels, header.bits));
|
||||||
String.format("Unsupported channel count/bit depth for Monochrome PSD: %d channels/%d bits", header.channels, header.bits)
|
|
||||||
);
|
|
||||||
|
|
||||||
case PSD.COLOR_MODE_INDEXED:
|
case PSD.COLOR_MODE_INDEXED:
|
||||||
// TODO: 16 bit indexed?! Does it exist?
|
|
||||||
if (header.channels == 1 && header.bits == 8) {
|
if (header.channels == 1 && header.bits == 8) {
|
||||||
return IndexedImageTypeSpecifier.createFromIndexColorModel(metadata.colorData.getIndexColorModel());
|
return IndexedImageTypeSpecifier.createFromIndexColorModel(metadata.colorData.getIndexColorModel());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IIOException(
|
throw new IIOException(String.format("Unsupported channel count/bit depth for Indexed Color PSD: %d channels/%d bits", header.channels, header.bits));
|
||||||
String.format("Unsupported channel count/bit depth for Indexed Color PSD: %d channels/%d bits", header.channels, header.bits)
|
|
||||||
);
|
|
||||||
|
|
||||||
case PSD.COLOR_MODE_DUOTONE:
|
case PSD.COLOR_MODE_DUOTONE:
|
||||||
// NOTE: Duotone (whatever that is) should be treated as gray scale
|
// NOTE: Duotone (whatever that is) should be treated as gray scale
|
||||||
// Fall-through
|
// Fall-through
|
||||||
case PSD.COLOR_MODE_GRAYSCALE:
|
case PSD.COLOR_MODE_GRAYSCALE:
|
||||||
|
cs = getEmbeddedColorSpace();
|
||||||
|
if (cs == null) {
|
||||||
|
cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
|
||||||
|
}
|
||||||
|
|
||||||
if (header.channels == 1 && header.bits == 8) {
|
if (header.channels == 1 && header.bits == 8) {
|
||||||
return ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY);
|
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) {
|
else if (header.channels == 1 && header.bits == 16) {
|
||||||
return ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_USHORT_GRAY);
|
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(
|
throw new IIOException(String.format("Unsupported channel count/bit depth for Gray Scale PSD: %d channels/%d bits", header.channels, header.bits));
|
||||||
String.format("Unsupported channel count/bit depth for Gray Scale PSD: %d channels/%d bits", header.channels, header.bits)
|
|
||||||
);
|
|
||||||
|
|
||||||
case PSD.COLOR_MODE_RGB:
|
case PSD.COLOR_MODE_RGB:
|
||||||
cs = getEmbeddedColorSpace();
|
cs = getEmbeddedColorSpace();
|
||||||
if (cs == null) {
|
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);
|
||||||
cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); // ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998); ?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header.channels == 3 && header.bits == 8) {
|
if (header.channels == 3 && header.bits == 8) {
|
||||||
@@ -208,10 +205,14 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
else if (header.channels >= 4 && header.bits == 16) {
|
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);
|
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(
|
throw new IIOException(String.format("Unsupported channel count/bit depth for RGB PSD: %d channels/%d bits", header.channels, header.bits));
|
||||||
String.format("Unsupported channel count/bit depth for RGB PSD: %d channels/%d bits", header.channels, header.bits)
|
|
||||||
);
|
|
||||||
|
|
||||||
case PSD.COLOR_MODE_CMYK:
|
case PSD.COLOR_MODE_CMYK:
|
||||||
cs = getEmbeddedColorSpace();
|
cs = getEmbeddedColorSpace();
|
||||||
@@ -231,10 +232,14 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
else if (header.channels == 5 && header.bits == 16) {
|
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);
|
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(
|
throw new IIOException(String.format("Unsupported channel count/bit depth for CMYK PSD: %d channels/%d bits", header.channels, header.bits));
|
||||||
String.format("Unsupported channel count/bit depth for CMYK PSD: %d channels/%d bits", header.channels, header.bits)
|
|
||||||
);
|
|
||||||
|
|
||||||
case PSD.COLOR_MODE_MULTICHANNEL:
|
case PSD.COLOR_MODE_MULTICHANNEL:
|
||||||
// TODO: Implement
|
// TODO: Implement
|
||||||
@@ -242,9 +247,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
// TODO: Implement
|
// TODO: Implement
|
||||||
// TODO: If there's a color profile embedded, it should be easy, otherwise we're out of luck...
|
// TODO: If there's a color profile embedded, it should be easy, otherwise we're out of luck...
|
||||||
default:
|
default:
|
||||||
throw new IIOException(
|
throw new IIOException(String.format("Unsupported PSD MODE: %s (%d channels/%d bits)", header.mode, header.channels, header.bits));
|
||||||
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 {
|
private ColorSpace getEmbeddedColorSpace() throws IOException {
|
||||||
readImageResources(true);
|
readImageResources(true);
|
||||||
// TODO: Skip this, requires storing some stream offsets
|
|
||||||
readLayerAndMaskInfo(false);
|
|
||||||
|
|
||||||
if (colorSpace == null) {
|
if (colorSpace == null) {
|
||||||
ICC_Profile profile = 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 {
|
public BufferedImage read(final int imageIndex, final ImageReadParam param) throws IOException {
|
||||||
checkBounds(imageIndex);
|
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?
|
// 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...
|
// 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: Support layer in index 0, if "has real merged data" flag is false?
|
||||||
// TODO: Param support in layer code (more duping/cleanup..)
|
// TODO: Param support in layer code (more duping/cleanup..)
|
||||||
if (imageIndex > 0) {
|
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);
|
return readLayerData(imageIndex - 1, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,13 +407,11 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
ySub = param.getSourceYSubsampling();
|
ySub = param.getSourceYSubsampling();
|
||||||
}
|
}
|
||||||
|
|
||||||
processImageStarted(imageIndex);
|
imageInput.seek(metadata.imageDataStart);
|
||||||
|
|
||||||
int[] byteCounts = null;
|
|
||||||
int compression = imageInput.readShort();
|
int compression = imageInput.readShort();
|
||||||
// TODO: Need to make sure compression is set in metadata, even without reading the image data!
|
|
||||||
metadata.compression = compression;
|
metadata.compression = compression;
|
||||||
|
|
||||||
|
int[] byteCounts = null;
|
||||||
switch (compression) {
|
switch (compression) {
|
||||||
case PSD.COMPRESSION_NONE:
|
case PSD.COMPRESSION_NONE:
|
||||||
break;
|
break;
|
||||||
@@ -435,14 +419,12 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
// NOTE: Byte counts will allow us to easily skip rows before AOI
|
// NOTE: Byte counts will allow us to easily skip rows before AOI
|
||||||
byteCounts = new int[header.channels * header.height];
|
byteCounts = new int[header.channels * header.height];
|
||||||
for (int i = 0; i < byteCounts.length; i++) {
|
for (int i = 0; i < byteCounts.length; i++) {
|
||||||
byteCounts[i] = imageInput.readUnsignedShort();
|
byteCounts[i] = header.largeFormat ? imageInput.readInt() : imageInput.readUnsignedShort();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PSD.COMPRESSION_ZIP:
|
case PSD.COMPRESSION_ZIP:
|
||||||
// TODO: Could probably use the ZIPDecoder (DeflateDecoder) here..
|
|
||||||
case PSD.COMPRESSION_ZIP_PREDICTION:
|
case PSD.COMPRESSION_ZIP_PREDICTION:
|
||||||
// TODO: Look at TIFF prediction reading
|
// TODO: Could probably use the ZIPDecoder (DeflateDecoder) here.. Look at TIFF prediction reading
|
||||||
// Could be same as PNG prediction? Read up...
|
|
||||||
throw new IIOException("PSD with ZIP compression not supported");
|
throw new IIOException("PSD with ZIP compression not supported");
|
||||||
default:
|
default:
|
||||||
throw new IIOException(
|
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
|
// What we read here is the "composite layer" of the PSD file
|
||||||
readImageData(image, rawType.getColorModel(), source, dest, xSub, ySub, byteCounts, compression);
|
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();
|
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);
|
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;
|
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:
|
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()) {
|
if (abortRequested()) {
|
||||||
@@ -531,6 +519,67 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
processImageProgress(100f * channel / channelCount + 100f * y / (height * channelCount));
|
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,
|
private void read16bitChannel(final int pChannel, final int pChannelCount,
|
||||||
final DataBuffer pData, final int pBands, final int pBandOffset,
|
final DataBuffer pData, final int pBands, final int pBandOffset,
|
||||||
final ColorModel pSourceColorModel,
|
final ColorModel pSourceColorModel,
|
||||||
@@ -731,7 +780,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
private void decomposeAlpha(final ColorModel pModel, final DataBuffer pBuffer,
|
private void decomposeAlpha(final ColorModel pModel, final DataBuffer pBuffer,
|
||||||
final int pWidth, final int pHeight, final int pChannels) {
|
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?
|
// TODO: What about CMYK + alpha?
|
||||||
if (pModel.hasAlpha() && pModel.getColorSpace().getType() == ColorSpace.TYPE_RGB) {
|
if (pModel.hasAlpha() && pModel.getColorSpace().getType() == ColorSpace.TYPE_RGB) {
|
||||||
|
|
||||||
@@ -791,9 +840,16 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
private void readHeader() throws IOException {
|
private void readHeader() throws IOException {
|
||||||
assertInput();
|
assertInput();
|
||||||
|
|
||||||
if (header == null) {
|
if (header == null) {
|
||||||
header = new PSDHeader(imageInput);
|
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 = new PSDMetadata();
|
||||||
metadata.header = header;
|
metadata.header = header;
|
||||||
|
|
||||||
@@ -818,6 +874,8 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
imageInput.skipBytes(length);
|
imageInput.skipBytes(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metadata.imageResourcesStart = imageInput.getStreamPosition();
|
||||||
|
|
||||||
// Don't need the header again
|
// Don't need the header again
|
||||||
imageInput.flushBefore(imageInput.getStreamPosition());
|
imageInput.flushBefore(imageInput.getStreamPosition());
|
||||||
}
|
}
|
||||||
@@ -826,85 +884,104 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
// TODO: Flags or list of interesting resources to parse
|
// TODO: Flags or list of interesting resources to parse
|
||||||
// TODO: Obey ignoreMetadata
|
// TODO: Obey ignoreMetadata
|
||||||
private void readImageResources(final boolean pParseData) throws IOException {
|
private void readImageResources(final boolean pParseData) throws IOException {
|
||||||
// TODO: Avoid unnecessary stream repositioning
|
readHeader();
|
||||||
long pos = imageInput.getFlushedPosition();
|
|
||||||
imageInput.seek(pos);
|
|
||||||
|
|
||||||
long length = imageInput.readUnsignedInt();
|
if (pParseData || metadata.layerAndMaskInfoStart == 0) {
|
||||||
|
imageInput.seek(metadata.imageResourcesStart);
|
||||||
|
|
||||||
if (pParseData && length > 0) {
|
long imageResourcesLength = imageInput.readUnsignedInt();
|
||||||
if (metadata.imageResources == null) {
|
|
||||||
metadata.imageResources = new ArrayList<PSDImageResource>();
|
|
||||||
long expectedEnd = imageInput.getStreamPosition() + length;
|
|
||||||
|
|
||||||
while (imageInput.getStreamPosition() < expectedEnd) {
|
if (pParseData && imageResourcesLength > 0) {
|
||||||
// TODO: Have PSDImageResources defer actual parsing? (Just store stream offsets)
|
if (metadata.imageResources == null) {
|
||||||
PSDImageResource resource = PSDImageResource.read(imageInput);
|
metadata.imageResources = new ArrayList<PSDImageResource>();
|
||||||
metadata.imageResources.add(resource);
|
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) {
|
// TODO: We should now be able to flush input
|
||||||
throw new IIOException("Corrupt PSD document"); // ..or maybe just a bug in the reader.. ;-)
|
// 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: Flags or list of interesting resources to parse
|
||||||
// TODO: Obey ignoreMetadata
|
// TODO: Obey ignoreMetadata
|
||||||
private void readLayerAndMaskInfo(final boolean pParseData) throws IOException {
|
private void readLayerAndMaskInfo(final boolean pParseData) throws IOException {
|
||||||
// TODO: Make sure we are positioned correctly
|
readImageResources(false);
|
||||||
// TODO: Avoid unnecessary stream repositioning
|
|
||||||
long length = imageInput.readUnsignedInt();
|
|
||||||
if (pParseData && length > 0) {
|
|
||||||
long pos = imageInput.getStreamPosition();
|
|
||||||
|
|
||||||
long read;
|
if (pParseData || metadata.imageDataStart == 0) {
|
||||||
if (metadata.layerInfo == null) {
|
imageInput.seek(metadata.layerAndMaskInfoStart);
|
||||||
long layerInfoLength = imageInput.readUnsignedInt();
|
|
||||||
|
|
||||||
/*
|
long layerAndMaskInfoLength = header.largeFormat ? imageInput.readLong() : imageInput.readUnsignedInt();
|
||||||
"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();
|
|
||||||
|
|
||||||
PSDLayerInfo[] layerInfos = new PSDLayerInfo[Math.abs(layers)];
|
// NOTE: The spec says that if this section is empty, the length should be 0.
|
||||||
for (int i = 0; i < layerInfos.length; i++) {
|
// Yet I have a PSB file that has size 12, and both contained lengths set to 0 (which
|
||||||
layerInfos[i] = new PSDLayerInfo(imageInput);
|
// 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;
|
// read = imageInput.getStreamPosition() - pos;
|
||||||
|
//
|
||||||
long diff = layerInfoLength - (read - 4); // - 4 for the layerInfoLength field itself
|
// long toSkip = layerAndMaskInfoLength - read;
|
||||||
// System.out.println("diff: " + diff);
|
// System.out.println("toSkip: " + toSkip);
|
||||||
imageInput.skipBytes(diff);
|
// imageInput.skipBytes(toSkip);
|
||||||
|
|
||||||
// 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;
|
metadata.imageDataStart = metadata.layerAndMaskInfoStart + layerAndMaskInfoLength + (header.largeFormat ? 8 : 4);
|
||||||
|
|
||||||
long toSkip = length - read;
|
|
||||||
// System.out.println("toSkip: " + toSkip);
|
|
||||||
imageInput.skipBytes(toSkip);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Skip entire layer and mask section
|
|
||||||
imageInput.skipBytes(length);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -949,19 +1026,22 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
final boolean banded = raster.getDataBuffer().getNumBanks() > 1;
|
final boolean banded = raster.getDataBuffer().getNumBanks() > 1;
|
||||||
final int interleavedBands = banded ? 1 : raster.getNumBands();
|
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) {
|
for (PSDChannelInfo channelInfo : layerInfo.channelInfo) {
|
||||||
int compression = imageInput.readUnsignedShort();
|
int compression = imageInput.readUnsignedShort();
|
||||||
|
|
||||||
// Skip layer if we can't read it
|
// Skip layer if we can't read it
|
||||||
// channelId == -2 means "user supplied layer mask", whatever that is...
|
// channelId
|
||||||
if (width <= 0 || height <= 0 || channelInfo.channelId == -2 ||
|
// -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)
|
||||||
(compression != PSD.COMPRESSION_NONE && compression != PSD.COMPRESSION_RLE)) {
|
if (width <= 0 || height <= 0 || channelInfo.channelId < -1 ||
|
||||||
|
(compression != PSD.COMPRESSION_NONE && compression != PSD.COMPRESSION_RLE)) { // TODO: ZIP Compressions!
|
||||||
imageInput.skipBytes(channelInfo.length - 2);
|
imageInput.skipBytes(channelInfo.length - 2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 0 = red, 1 = green, etc
|
// 0 = red, 1 = green, etc
|
||||||
// -1 = transparency mask; -2 = user supplied layer mask
|
// -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 ? layerInfo.channelInfo.length - 1 : channelInfo.channelId;
|
int c = channelInfo.channelId == -1 ? rowRaster.getNumBands() - 1 : channelInfo.channelId;
|
||||||
|
|
||||||
// NOTE: For layers, byte counts are written per channel, while for the composite data
|
// 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.
|
// byte counts are written for all channels before the image data.
|
||||||
@@ -975,10 +1055,10 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
case PSD.COMPRESSION_RLE:
|
case PSD.COMPRESSION_RLE:
|
||||||
// If RLE, the the image data starts with the byte counts
|
// If RLE, the the image data starts with the byte counts
|
||||||
// for all the scan lines in the channel (LayerBottom-LayerTop), with
|
// 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];
|
byteCounts = new int[layerInfo.bottom - layerInfo.top];
|
||||||
for (int i = 0; i < byteCounts.length; i++) {
|
for (int i = 0; i < byteCounts.length; i++) {
|
||||||
byteCounts[i] = imageInput.readUnsignedShort();
|
byteCounts[i] = header.largeFormat ? imageInput.readInt() : imageInput.readUnsignedShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -998,11 +1078,18 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
byte[] row8 = ((DataBufferByte) rowRaster.getDataBuffer()).getData();
|
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;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
short[] row16 = ((DataBufferUShort) rowRaster.getDataBuffer()).getData();
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IIOException(String.format("Unknown PSD bit depth: %s", header.bits));
|
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 layer has more channels than composite data, it's normally extra alpha...
|
||||||
if (layerInfo.channelInfo.length > compositeType.getNumBands()) {
|
if (layerInfo.channelInfo.length > compositeType.getNumBands()) {
|
||||||
// ...but, it could also be just the user mask...
|
// ...but, it could also be just one of the user masks...
|
||||||
boolean userMask = false;
|
int newBandNum = 0;
|
||||||
|
|
||||||
for (PSDChannelInfo channelInfo : layerInfo.channelInfo) {
|
for (PSDChannelInfo channelInfo : layerInfo.channelInfo) {
|
||||||
if (channelInfo.channelId == -2) {
|
// -2 = user supplied layer mask, -3 real user supplied layer mask (when both a user mask and a vector mask are present)
|
||||||
userMask = true;
|
if (channelInfo.channelId >= -1) {
|
||||||
break;
|
newBandNum++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int newBandNum = layerInfo.channelInfo.length - (userMask ? 1 : 0);
|
|
||||||
|
|
||||||
// If there really is more channels, then create new imageTypeSpec
|
// If there really is more channels, then create new imageTypeSpec
|
||||||
if (newBandNum > compositeType.getNumBands()) {
|
if (newBandNum > compositeType.getNumBands()) {
|
||||||
@@ -1056,30 +1143,28 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
/// Layer support
|
/// 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
|
@Override
|
||||||
public int getNumImages(boolean allowSearch) throws IOException {
|
public int getNumImages(boolean allowSearch) throws IOException {
|
||||||
// NOTE: Spec says this method should throw IllegalStateException if allowSearch && isSeekForwardOnly()
|
// 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?
|
// But that makes no sense for a format (like PSD) that does not need to search, right?
|
||||||
|
|
||||||
readHeader();
|
readLayerAndMaskInfo(true);
|
||||||
readImageResources(false);
|
|
||||||
readLayerAndMaskInfo(true); // TODO: Consider quicker reading of just the number of layers.
|
|
||||||
|
|
||||||
return metadata.layerInfo != null ? metadata.layerInfo.size() + 1 : 1; // TODO: Only plus one, if "has real merged data"?
|
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
|
/// Metadata support
|
||||||
// TODO
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IIOMetadata getStreamMetadata() throws IOException {
|
public IIOMetadata getStreamMetadata() throws IOException {
|
||||||
@@ -1090,20 +1175,15 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IIOMetadata getImageMetadata(final int imageIndex) throws IOException {
|
public IIOMetadata getImageMetadata(final int imageIndex) throws IOException {
|
||||||
// TODO: Implement
|
|
||||||
checkBounds(imageIndex);
|
checkBounds(imageIndex);
|
||||||
|
|
||||||
readHeader();
|
|
||||||
readImageResources(true);
|
readImageResources(true);
|
||||||
readLayerAndMaskInfo(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.compression = imageInput.readShort();
|
||||||
|
|
||||||
// metadata.header = header;
|
|
||||||
// metadata.colorData = colorData;
|
|
||||||
// metadata.imageResources = imageResources;
|
|
||||||
|
|
||||||
return metadata; // TODO: clone if we change to mutable metadata
|
return metadata; // TODO: clone if we change to mutable metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1129,8 +1209,6 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
if (metadata.imageResources == null) {
|
if (metadata.imageResources == null) {
|
||||||
// TODO: Need flag here, to specify what resources to read...
|
// TODO: Need flag here, to specify what resources to read...
|
||||||
readImageResources(true);
|
readImageResources(true);
|
||||||
// TODO: Skip this, requires storing some stream offsets
|
|
||||||
readLayerAndMaskInfo(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PSDImageResource resource : metadata.imageResources) {
|
for (PSDImageResource resource : metadata.imageResources) {
|
||||||
@@ -1236,84 +1314,89 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
PSDImageReader imageReader = new PSDImageReader(null);
|
PSDImageReader imageReader = new PSDImageReader(null);
|
||||||
|
|
||||||
File file = new File(pArgs[idx]);
|
for (; idx < pArgs.length; idx++) {
|
||||||
ImageInputStream stream = ImageIO.createImageInputStream(file);
|
File file = new File(pArgs[idx]);
|
||||||
imageReader.setInput(stream);
|
System.out.println();
|
||||||
|
System.out.println("file: " + file.getAbsolutePath());
|
||||||
|
|
||||||
imageReader.readHeader();
|
ImageInputStream stream = ImageIO.createImageInputStream(file);
|
||||||
// System.out.println("imageReader.header: " + imageReader.header);
|
imageReader.setInput(stream);
|
||||||
|
imageReader.readHeader();
|
||||||
|
System.out.println("imageReader.header: " + imageReader.header);
|
||||||
|
|
||||||
imageReader.readImageResources(true);
|
imageReader.readImageResources(true);
|
||||||
System.out.println("imageReader.imageResources: " + imageReader.metadata.imageResources);
|
System.out.println("imageReader.imageResources: " + imageReader.metadata.imageResources);
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
|
||||||
imageReader.readLayerAndMaskInfo(true);
|
imageReader.readLayerAndMaskInfo(true);
|
||||||
System.out.println("imageReader.layerInfo: " + imageReader.metadata.layerInfo);
|
System.out.println("imageReader.layerInfo: " + imageReader.metadata.layerInfo);
|
||||||
// System.out.println("imageReader.globalLayerMask: " + imageReader.globalLayerMask);
|
/*
|
||||||
System.out.println();
|
// System.out.println("imageReader.globalLayerMask: " + imageReader.globalLayerMask);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
IIOMetadata metadata = imageReader.getImageMetadata(0);
|
IIOMetadata metadata = imageReader.getImageMetadata(0);
|
||||||
Node node;
|
Node node;
|
||||||
XMLSerializer serializer;
|
XMLSerializer serializer;
|
||||||
|
|
||||||
node = metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
|
node = metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
|
||||||
serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
|
serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
|
||||||
serializer.serialize(node, true);
|
serializer.serialize(node, true);
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
|
||||||
node = metadata.getAsTree(PSDMetadata.NATIVE_METADATA_FORMAT_NAME);
|
node = metadata.getAsTree(PSDMetadata.NATIVE_METADATA_FORMAT_NAME);
|
||||||
// serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
|
// serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
|
||||||
serializer.serialize(node, true);
|
serializer.serialize(node, true);
|
||||||
|
*/
|
||||||
if (readThumbnails && imageReader.hasThumbnails(0)) {
|
if (readThumbnails && imageReader.hasThumbnails(0)) {
|
||||||
int thumbnails = imageReader.getNumThumbnails(0);
|
int thumbnails = imageReader.getNumThumbnails(0);
|
||||||
for (int i = 0; i < thumbnails; i++) {
|
for (int i = 0; i < thumbnails; i++) {
|
||||||
showIt(imageReader.readThumbnail(0, i), String.format("Thumbnail %d", 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) {
|
if (sourceRegion != null) {
|
||||||
param.setSourceRegion(sourceRegion);
|
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()));
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
if (subsampleFactor > 1) {
|
||||||
image = ImageUtil.accelerate(image);
|
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);
|
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) {
|
showIt(image, file.getName());
|
||||||
int images = imageReader.getNumImages(true);
|
|
||||||
for (int i = 1; i < images; i++) {
|
if (readLayers) {
|
||||||
start = System.currentTimeMillis();
|
int images = imageReader.getNumImages(true);
|
||||||
BufferedImage layer = imageReader.read(i);
|
for (int i = 1; i < images; i++) {
|
||||||
System.out.println("layer read time: " + (System.currentTimeMillis() - start));
|
start = System.currentTimeMillis();
|
||||||
System.err.println("layer: " + layer);
|
BufferedImage layer = imageReader.read(i);
|
||||||
showIt(layer, "layer " + i);
|
System.out.println("layer read time: " + (System.currentTimeMillis() - start));
|
||||||
|
System.err.println("layer: " + layer);
|
||||||
|
showIt(layer, "layer " + i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDImageReaderSpi.java,v 1.0 Apr 29, 2008 4:49:03 PM haraldk Exp$
|
* @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}.
|
* Creates a {@code PSDImageReaderSpi}.
|
||||||
@@ -57,18 +57,18 @@ public class PSDImageReaderSpi extends ImageReaderSpi {
|
|||||||
super(
|
super(
|
||||||
providerInfo.getVendorName(),
|
providerInfo.getVendorName(),
|
||||||
providerInfo.getVersion(),
|
providerInfo.getVersion(),
|
||||||
new String[]{"psd", "PSD"},
|
new String[] {"psd", "PSD"},
|
||||||
new String[]{"psd"},
|
new String[] {"psd"},
|
||||||
new String[]{
|
new String[] {
|
||||||
"image/vnd.adobe.photoshop", // Official, IANA registered
|
"image/vnd.adobe.photoshop", // Official, IANA registered
|
||||||
"application/vnd.adobe.photoshop", // Used in XMP
|
"application/vnd.adobe.photoshop", // Used in XMP
|
||||||
"image/x-psd",
|
"image/x-psd",
|
||||||
"application/x-photoshop",
|
"application/x-photoshop",
|
||||||
"image/x-photoshop"
|
"image/x-photoshop"
|
||||||
},
|
},
|
||||||
"com.twelvemkonkeys.imageio.plugins.psd.PSDImageReader",
|
"com.twelvemkonkeys.imageio.plugins.psd.PSDImageReader",
|
||||||
new Class[] {ImageInputStream.class},
|
new Class[] {ImageInputStream.class},
|
||||||
// new String[]{"com.twelvemkonkeys.imageio.plugins.psd.PSDImageWriterSpi"},
|
// new String[] {"com.twelvemkonkeys.imageio.plugins.psd.PSDImageWriterSpi"},
|
||||||
null,
|
null,
|
||||||
true, // supports standard stream metadata
|
true, // supports standard stream metadata
|
||||||
null, null, // native stream format name and class
|
null, null, // native stream format name and class
|
||||||
@@ -87,9 +87,23 @@ public class PSDImageReaderSpi extends ImageReaderSpi {
|
|||||||
ImageInputStream stream = (ImageInputStream) pSource;
|
ImageInputStream stream = (ImageInputStream) pSource;
|
||||||
|
|
||||||
stream.mark();
|
stream.mark();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return stream.readInt() == PSD.SIGNATURE_8BPS;
|
if (stream.readInt() == PSD.SIGNATURE_8BPS) {
|
||||||
// TODO: Test more of the header, see PSDImageReader#readHeader
|
int version = stream.readUnsignedShort();
|
||||||
|
|
||||||
|
switch (version) {
|
||||||
|
case PSD.VERSION_PSD:
|
||||||
|
case PSD.VERSION_PSB:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
stream.reset();
|
stream.reset();
|
||||||
|
22
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageResource.java
Normal file → Executable file
22
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageResource.java
Normal file → Executable file
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -110,7 +110,7 @@ public class PSDImageResource {
|
|||||||
|
|
||||||
builder.append("[ID: 0x");
|
builder.append("[ID: 0x");
|
||||||
builder.append(Integer.toHexString(id));
|
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(name);
|
builder.append(name);
|
||||||
builder.append("\"");
|
builder.append("\"");
|
||||||
@@ -139,6 +139,13 @@ public class PSDImageResource {
|
|||||||
case PSD.RES_PRINT_FLAGS_INFORMATION:
|
case PSD.RES_PRINT_FLAGS_INFORMATION:
|
||||||
return null;
|
return null;
|
||||||
default:
|
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 {
|
try {
|
||||||
for (Field field : PSD.class.getDeclaredFields()) {
|
for (Field field : PSD.class.getDeclaredFields()) {
|
||||||
if (field.getName().startsWith("RES_") && field.getInt(null) == pId) {
|
if (field.getName().startsWith("RES_") && field.getInt(null) == pId) {
|
||||||
@@ -149,7 +156,7 @@ public class PSDImageResource {
|
|||||||
}
|
}
|
||||||
catch (IllegalAccessException ignore) {
|
catch (IllegalAccessException ignore) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return "UnknownResource";
|
return "UnknownResource";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,9 +167,9 @@ public class PSDImageResource {
|
|||||||
throw new IIOException(String.format("Wrong image resource type, expected '8BIM': '%s'", PSDUtil.intToStr(type)));
|
throw new IIOException(String.format("Wrong image resource type, expected '8BIM': '%s'", PSDUtil.intToStr(type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Process more of the resource stuff, most important are IPTC, EXIF and XMP data,
|
// TODO: Have PSDImageResources defer actual parsing? (Just store stream offsets)
|
||||||
// version info, and thumbnail for thumbnail-support.
|
|
||||||
short id = pInput.readShort();
|
short id = pInput.readShort();
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case PSD.RES_RESOLUTION_INFO:
|
case PSD.RES_RESOLUTION_INFO:
|
||||||
return new PSDResolutionInfo(id, pInput);
|
return new PSDResolutionInfo(id, pInput);
|
||||||
@@ -196,9 +203,8 @@ public class PSDImageResource {
|
|||||||
case PSD.RES_PRINT_FLAGS_INFORMATION:
|
case PSD.RES_PRINT_FLAGS_INFORMATION:
|
||||||
return new PSDPrintFlagsInformation(id, pInput);
|
return new PSDPrintFlagsInformation(id, pInput);
|
||||||
default:
|
default:
|
||||||
if (id >= 0x07d0 && id <= 0x0bb6) {
|
if (id >= PSD.RES_PATH_INFO_MIN && id <= PSD.RES_PATH_INFO_MAX) {
|
||||||
// TODO: Parse saved path information
|
return new PSDPathResource(id, pInput);
|
||||||
return new PSDImageResource(id, pInput);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new PSDImageResource(id, pInput);
|
return new PSDImageResource(id, pInput);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDLayerBlendMode.java,v 1.0 May 8, 2008 4:34:35 PM haraldk Exp$
|
* @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 blendMode;
|
||||||
final int opacity; // 0-255
|
final int opacity; // 0-255
|
||||||
final int clipping; // 0: base, 1: non-base
|
final int clipping; // 0: base, 1: non-base
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDLayerInfo.java,v 1.0 Apr 29, 2008 6:01:12 PM haraldk Exp$
|
* @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 top;
|
||||||
final int left;
|
final int left;
|
||||||
final int bottom;
|
final int bottom;
|
||||||
@@ -52,7 +52,7 @@ class PSDLayerInfo {
|
|||||||
final PSDChannelSourceDestinationRange[] ranges;
|
final PSDChannelSourceDestinationRange[] ranges;
|
||||||
final String layerName;
|
final String layerName;
|
||||||
|
|
||||||
PSDLayerInfo(ImageInputStream pInput) throws IOException {
|
PSDLayerInfo(final boolean largeFormat, final ImageInputStream pInput) throws IOException {
|
||||||
top = pInput.readInt();
|
top = pInput.readInt();
|
||||||
left = pInput.readInt();
|
left = pInput.readInt();
|
||||||
bottom = pInput.readInt();
|
bottom = pInput.readInt();
|
||||||
@@ -63,7 +63,7 @@ class PSDLayerInfo {
|
|||||||
channelInfo = new PSDChannelInfo[channels];
|
channelInfo = new PSDChannelInfo[channels];
|
||||||
for (int i = 0; i < channels; i++) {
|
for (int i = 0; i < channels; i++) {
|
||||||
short channelId = pInput.readShort();
|
short channelId = pInput.readShort();
|
||||||
long length = pInput.readUnsignedInt();
|
long length = largeFormat ? pInput.readLong() : pInput.readUnsignedInt();
|
||||||
|
|
||||||
channelInfo[i] = new PSDChannelInfo(channelId, length);
|
channelInfo[i] = new PSDChannelInfo(channelId, length);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDLayerMaskData.java,v 1.0 May 6, 2008 5:15:05 PM haraldk Exp$
|
* @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 top;
|
||||||
private int left;
|
private int left;
|
||||||
private int bottom;
|
private int bottom;
|
||||||
|
220
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadata.java
Normal file → Executable file
220
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadata.java
Normal file → Executable file
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||||
@@ -35,7 +63,11 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
List<PSDImageResource> imageResources;
|
List<PSDImageResource> imageResources;
|
||||||
PSDGlobalLayerMask globalLayerMask;
|
PSDGlobalLayerMask globalLayerMask;
|
||||||
List<PSDLayerInfo> layerInfo;
|
List<PSDLayerInfo> layerInfo;
|
||||||
|
|
||||||
|
long imageResourcesStart;
|
||||||
|
long layerAndMaskInfoStart;
|
||||||
long layersStart;
|
long layersStart;
|
||||||
|
long imageDataStart;
|
||||||
|
|
||||||
static final String[] COLOR_MODES = {
|
static final String[] COLOR_MODES = {
|
||||||
"MONOCHROME", "GRAYSCALE", "INDEXED", "RGB", "CMYK", null, null, "MULTICHANNEL", "DUOTONE", "LAB"
|
"MONOCHROME", "GRAYSCALE", "INDEXED", "RGB", "CMYK", null, null, "MULTICHANNEL", "DUOTONE", "LAB"
|
||||||
@@ -85,17 +117,17 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Node createHeaderNode() {
|
private Node createHeaderNode() {
|
||||||
IIOMetadataNode header = new IIOMetadataNode("Header");
|
IIOMetadataNode headerNode = new IIOMetadataNode("Header");
|
||||||
|
|
||||||
header.setAttribute("type", "PSD");
|
headerNode.setAttribute("type", "PSD");
|
||||||
header.setAttribute("version", "1");
|
headerNode.setAttribute("version", header.largeFormat ? "2" : "1");
|
||||||
header.setAttribute("channels", Integer.toString(this.header.channels));
|
headerNode.setAttribute("channels", Integer.toString(header.channels));
|
||||||
header.setAttribute("height", Integer.toString(this.header.height));
|
headerNode.setAttribute("height", Integer.toString(header.height));
|
||||||
header.setAttribute("width", Integer.toString(this.header.width));
|
headerNode.setAttribute("width", Integer.toString(header.width));
|
||||||
header.setAttribute("bits", Integer.toString(this.header.bits));
|
headerNode.setAttribute("bits", Integer.toString(header.bits));
|
||||||
header.setAttribute("mode", COLOR_MODES[this.header.mode]);
|
headerNode.setAttribute("mode", COLOR_MODES[header.mode]);
|
||||||
|
|
||||||
return header;
|
return headerNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createImageResourcesNode() {
|
private Node createImageResourcesNode() {
|
||||||
@@ -112,18 +144,6 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
// TODO: Format spec
|
// TODO: Format spec
|
||||||
node = new IIOMetadataNode("ICCProfile");
|
node = new IIOMetadataNode("ICCProfile");
|
||||||
node.setAttribute("colorSpaceType", JAVA_CS[profile.getProfile().getColorSpaceType()]);
|
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());
|
node.setUserObject(profile.getProfile());
|
||||||
}
|
}
|
||||||
else if (imageResource instanceof PSDAlphaChannelInfo) {
|
else if (imageResource instanceof PSDAlphaChannelInfo) {
|
||||||
@@ -347,13 +367,12 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IIOMetadataNode getStandardChromaNode() {
|
protected IIOMetadataNode getStandardChromaNode() {
|
||||||
IIOMetadataNode chroma_node = new IIOMetadataNode("Chroma");
|
IIOMetadataNode chroma = new IIOMetadataNode("Chroma");
|
||||||
IIOMetadataNode node; // scratch node
|
|
||||||
|
|
||||||
node = new IIOMetadataNode("ColorSpaceType");
|
IIOMetadataNode colorSpaceType = new IIOMetadataNode("ColorSpaceType");
|
||||||
String cs;
|
String cs;
|
||||||
switch (header.mode) {
|
switch (header.mode) {
|
||||||
case PSD.COLOR_MODE_MONOCHROME:
|
case PSD.COLOR_MODE_BITMAP:
|
||||||
case PSD.COLOR_MODE_GRAYSCALE:
|
case PSD.COLOR_MODE_GRAYSCALE:
|
||||||
case PSD.COLOR_MODE_DUOTONE: // Rationale: Spec says treat as gray...
|
case PSD.COLOR_MODE_DUOTONE: // Rationale: Spec says treat as gray...
|
||||||
cs = "GRAY";
|
cs = "GRAY";
|
||||||
@@ -374,25 +393,24 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
default:
|
default:
|
||||||
throw new AssertionError("Unreachable");
|
throw new AssertionError("Unreachable");
|
||||||
}
|
}
|
||||||
node.setAttribute("name", cs);
|
colorSpaceType.setAttribute("name", cs);
|
||||||
chroma_node.appendChild(node);
|
chroma.appendChild(colorSpaceType);
|
||||||
|
|
||||||
// TODO: Channels might be 5 for RGB + A + Mask... Probably not correct
|
// TODO: Channels might be 5 for RGB + A + Mask... Probably not correct
|
||||||
node = new IIOMetadataNode("NumChannels");
|
IIOMetadataNode numChannels = new IIOMetadataNode("NumChannels");
|
||||||
node.setAttribute("value", Integer.toString(header.channels));
|
numChannels.setAttribute("value", Integer.toString(header.channels));
|
||||||
chroma_node.appendChild(node);
|
chroma.appendChild(numChannels);
|
||||||
|
|
||||||
// TODO: Check if this is correct with bitmap (monchrome)
|
IIOMetadataNode blackIsZero = new IIOMetadataNode("BlackIsZero");
|
||||||
node = new IIOMetadataNode("BlackIsZero");
|
blackIsZero.setAttribute("value", "true");
|
||||||
node.setAttribute("value", "true");
|
chroma.appendChild(blackIsZero);
|
||||||
chroma_node.appendChild(node);
|
|
||||||
|
|
||||||
if (header.mode == PSD.COLOR_MODE_INDEXED) {
|
if (header.mode == PSD.COLOR_MODE_INDEXED) {
|
||||||
node = createPaletteNode();
|
IIOMetadataNode paletteNode = createPaletteNode();
|
||||||
chroma_node.appendChild(node);
|
chroma.appendChild(paletteNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Hardcode background color to white?
|
// TODO: Use
|
||||||
// if (bKGD_present) {
|
// if (bKGD_present) {
|
||||||
// if (bKGD_colorType == PNGImageReader.PNG_COLOR_PALETTE) {
|
// if (bKGD_colorType == PNGImageReader.PNG_COLOR_PALETTE) {
|
||||||
// node = new IIOMetadataNode("BackgroundIndex");
|
// node = new IIOMetadataNode("BackgroundIndex");
|
||||||
@@ -415,24 +433,25 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
// chroma_node.appendChild(node);
|
// chroma_node.appendChild(node);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return chroma_node;
|
return chroma;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IIOMetadataNode createPaletteNode() {
|
private IIOMetadataNode createPaletteNode() {
|
||||||
IIOMetadataNode node = new IIOMetadataNode("Palette");
|
IIOMetadataNode palette = new IIOMetadataNode("Palette");
|
||||||
IndexColorModel cm = colorData.getIndexColorModel();
|
IndexColorModel cm = colorData.getIndexColorModel();
|
||||||
|
|
||||||
for (int i = 0; i < cm.getMapSize(); i++) {
|
for (int i = 0; i < cm.getMapSize(); i++) {
|
||||||
IIOMetadataNode entry = new IIOMetadataNode("PaletteEntry");
|
IIOMetadataNode entry = new IIOMetadataNode("PaletteEntry");
|
||||||
|
|
||||||
entry.setAttribute("index", Integer.toString(i));
|
entry.setAttribute("index", Integer.toString(i));
|
||||||
entry.setAttribute("red", Integer.toString(cm.getRed(i)));
|
entry.setAttribute("red", Integer.toString(cm.getRed(i)));
|
||||||
entry.setAttribute("green", Integer.toString(cm.getGreen(i)));
|
entry.setAttribute("green", Integer.toString(cm.getGreen(i)));
|
||||||
entry.setAttribute("blue", Integer.toString(cm.getBlue(i)));
|
entry.setAttribute("blue", Integer.toString(cm.getBlue(i)));
|
||||||
|
|
||||||
node.appendChild(entry);
|
palette.appendChild(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getMultiChannelCS(short channels) {
|
private String getMultiChannelCS(short channels) {
|
||||||
@@ -446,33 +465,33 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
@Override
|
@Override
|
||||||
protected IIOMetadataNode getStandardCompressionNode() {
|
protected IIOMetadataNode getStandardCompressionNode() {
|
||||||
IIOMetadataNode compressionNode = new IIOMetadataNode("Compression");
|
IIOMetadataNode compressionNode = new IIOMetadataNode("Compression");
|
||||||
IIOMetadataNode node; // scratch node
|
|
||||||
|
|
||||||
node = new IIOMetadataNode("CompressionTypeName");
|
IIOMetadataNode compressionTypeName = new IIOMetadataNode("CompressionTypeName");
|
||||||
String compression;
|
String compressionName;
|
||||||
|
|
||||||
switch (this.compression) {
|
switch (compression) {
|
||||||
case PSD.COMPRESSION_NONE:
|
case PSD.COMPRESSION_NONE:
|
||||||
compression = "none";
|
compressionName = "none";
|
||||||
break;
|
break;
|
||||||
case PSD.COMPRESSION_RLE:
|
case PSD.COMPRESSION_RLE:
|
||||||
compression = "PackBits";
|
compressionName = "PackBits";
|
||||||
break;
|
break;
|
||||||
case PSD.COMPRESSION_ZIP:
|
case PSD.COMPRESSION_ZIP:
|
||||||
case PSD.COMPRESSION_ZIP_PREDICTION:
|
case PSD.COMPRESSION_ZIP_PREDICTION:
|
||||||
compression = "Deflate"; // TODO: ZLib? (TIFF native metadata format specifies both.. :-P)
|
compressionName = "Zip";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new AssertionError("Unreachable");
|
throw new AssertionError("Unreachable");
|
||||||
}
|
}
|
||||||
|
|
||||||
node.setAttribute("value", compression);
|
compressionTypeName.setAttribute("value", compressionName);
|
||||||
compressionNode.appendChild(node);
|
compressionNode.appendChild(compressionTypeName);
|
||||||
|
|
||||||
// TODO: Does it make sense to specify lossless for compression "none"?
|
if (compression != PSD.COMPRESSION_NONE) {
|
||||||
node = new IIOMetadataNode("Lossless");
|
IIOMetadataNode lossless = new IIOMetadataNode("Lossless");
|
||||||
node.setAttribute("value", "true");
|
lossless.setAttribute("value", "true");
|
||||||
compressionNode.appendChild(node);
|
compressionNode.appendChild(lossless);
|
||||||
|
}
|
||||||
|
|
||||||
return compressionNode;
|
return compressionNode;
|
||||||
}
|
}
|
||||||
@@ -480,15 +499,14 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
@Override
|
@Override
|
||||||
protected IIOMetadataNode getStandardDataNode() {
|
protected IIOMetadataNode getStandardDataNode() {
|
||||||
IIOMetadataNode dataNode = new IIOMetadataNode("Data");
|
IIOMetadataNode dataNode = new IIOMetadataNode("Data");
|
||||||
IIOMetadataNode node; // scratch node
|
|
||||||
|
|
||||||
node = new IIOMetadataNode("PlanarConfiguration");
|
IIOMetadataNode planarConfiguration = new IIOMetadataNode("PlanarConfiguration");
|
||||||
node.setAttribute("value", "PlaneInterleaved"); // TODO: Check with spec
|
planarConfiguration.setAttribute("value", "PlaneInterleaved");
|
||||||
dataNode.appendChild(node);
|
dataNode.appendChild(planarConfiguration);
|
||||||
|
|
||||||
node = new IIOMetadataNode("SampleFormat");
|
IIOMetadataNode sampleFormat = new IIOMetadataNode("SampleFormat");
|
||||||
node.setAttribute("value", header.mode == PSD.COLOR_MODE_INDEXED ? "Index" : "UnsignedIntegral");
|
sampleFormat.setAttribute("value", header.mode == PSD.COLOR_MODE_INDEXED ? "Index" : "UnsignedIntegral");
|
||||||
dataNode.appendChild(node);
|
dataNode.appendChild(sampleFormat);
|
||||||
|
|
||||||
String bitDepth = Integer.toString(header.bits); // bits per plane
|
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];
|
String[] bps = new String[header.channels];
|
||||||
Arrays.fill(bps, bitDepth);
|
Arrays.fill(bps, bitDepth);
|
||||||
|
|
||||||
node = new IIOMetadataNode("BitsPerSample");
|
IIOMetadataNode bitsPerSample = new IIOMetadataNode("BitsPerSample");
|
||||||
node.setAttribute("value", StringUtil.toCSVString(bps, " "));
|
bitsPerSample.setAttribute("value", StringUtil.toCSVString(bps, " "));
|
||||||
dataNode.appendChild(node);
|
dataNode.appendChild(bitsPerSample);
|
||||||
|
|
||||||
// TODO: SampleMSB? Or is network (aka Motorola/big endian) byte order assumed?
|
|
||||||
|
|
||||||
return dataNode;
|
return dataNode;
|
||||||
}
|
}
|
||||||
@@ -542,33 +558,6 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
dimensionNode.appendChild(node);
|
dimensionNode.appendChild(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
|
||||||
/*
|
|
||||||
<!ELEMENT "HorizontalPixelOffset" EMPTY>
|
|
||||||
<!-- The horizonal position, in pixels, where the image should be
|
|
||||||
rendered onto a raster display -->
|
|
||||||
<!ATTLIST "HorizontalPixelOffset" "value" #CDATA #REQUIRED>
|
|
||||||
<!-- Data type: Integer -->
|
|
||||||
|
|
||||||
<!ELEMENT "VerticalPixelOffset" EMPTY>
|
|
||||||
<!-- The vertical position, in pixels, where the image should be
|
|
||||||
rendered onto a raster display -->
|
|
||||||
<!ATTLIST "VerticalPixelOffset" "value" #CDATA #REQUIRED>
|
|
||||||
<!-- Data type: Integer -->
|
|
||||||
|
|
||||||
<!ELEMENT "HorizontalScreenSize" EMPTY>
|
|
||||||
<!-- The width, in pixels, of the raster display into which the
|
|
||||||
image should be rendered -->
|
|
||||||
<!ATTLIST "HorizontalScreenSize" "value" #CDATA #REQUIRED>
|
|
||||||
<!-- Data type: Integer -->
|
|
||||||
|
|
||||||
<!ELEMENT "VerticalScreenSize" EMPTY>
|
|
||||||
<!-- The height, in pixels, of the raster display into which the
|
|
||||||
image should be rendered -->
|
|
||||||
<!ATTLIST "VerticalScreenSize" "value" #CDATA #REQUIRED>
|
|
||||||
<!-- Data type: Integer -->
|
|
||||||
|
|
||||||
*/
|
|
||||||
return dimensionNode;
|
return dimensionNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,11 +569,10 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
@Override
|
@Override
|
||||||
protected IIOMetadataNode getStandardDocumentNode() {
|
protected IIOMetadataNode getStandardDocumentNode() {
|
||||||
IIOMetadataNode document_node = new IIOMetadataNode("Document");
|
IIOMetadataNode document_node = new IIOMetadataNode("Document");
|
||||||
IIOMetadataNode node; // scratch node
|
|
||||||
|
|
||||||
node = new IIOMetadataNode("FormatVersion");
|
IIOMetadataNode formatVersion = new IIOMetadataNode("FormatVersion");
|
||||||
node.setAttribute("value", "1"); // PSD format version is always 1
|
formatVersion.setAttribute("value", header.largeFormat ? "2" : "1"); // PSD format version is always 1, PSB is 2
|
||||||
document_node.appendChild(node);
|
document_node.appendChild(formatVersion);
|
||||||
|
|
||||||
// Get EXIF data if present
|
// Get EXIF data if present
|
||||||
Iterator<PSDEXIF1Data> exif = getResources(PSDEXIF1Data.class);
|
Iterator<PSDEXIF1Data> exif = getResources(PSDEXIF1Data.class);
|
||||||
@@ -594,18 +582,18 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
// Get the EXIF DateTime (aka ModifyDate) tag if present
|
// Get the EXIF DateTime (aka ModifyDate) tag if present
|
||||||
Entry dateTime = data.directory.getEntryById(TIFF.TAG_DATE_TIME);
|
Entry dateTime = data.directory.getEntryById(TIFF.TAG_DATE_TIME);
|
||||||
if (dateTime != null) {
|
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"
|
// Format: "YYYY:MM:DD hh:mm:ss"
|
||||||
String value = dateTime.getValueAsString();
|
String value = dateTime.getValueAsString();
|
||||||
|
|
||||||
node.setAttribute("year", value.substring(0, 4));
|
imageCreationTime.setAttribute("year", value.substring(0, 4));
|
||||||
node.setAttribute("month", value.substring(5, 7));
|
imageCreationTime.setAttribute("month", value.substring(5, 7));
|
||||||
node.setAttribute("day", value.substring(8, 10));
|
imageCreationTime.setAttribute("day", value.substring(8, 10));
|
||||||
node.setAttribute("hour", value.substring(11, 13));
|
imageCreationTime.setAttribute("hour", value.substring(11, 13));
|
||||||
node.setAttribute("minute", value.substring(14, 16));
|
imageCreationTime.setAttribute("minute", value.substring(14, 16));
|
||||||
node.setAttribute("second", value.substring(17, 19));
|
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
|
@Override
|
||||||
protected IIOMetadataNode getStandardTextNode() {
|
protected IIOMetadataNode getStandardTextNode() {
|
||||||
// TODO: TIFF uses
|
// NOTE: TIFF uses
|
||||||
// DocumentName, ImageDescription, Make, Model, PageName, Software, Artist, HostComputer, InkNames, Copyright:
|
// DocumentName, ImageDescription, Make, Model, PageName, Software, Artist, HostComputer, InkNames, Copyright:
|
||||||
// /Text/TextEntry@keyword = field name, /Text/TextEntry@value = field value.
|
// /Text/TextEntry@keyword = field name, /Text/TextEntry@value = field value.
|
||||||
// Example: TIFF Software field => /Text/TextEntry@keyword = "Software",
|
// 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<Entry> filter) {
|
private void appendTextEntriesFlat(final IIOMetadataNode node, final Directory directory, final FilterIterator.Filter<Entry> filter) {
|
||||||
FilterIterator<Entry> pEntries = new FilterIterator<Entry>(directory.iterator(), filter);
|
FilterIterator<Entry> entries = new FilterIterator<Entry>(directory.iterator(), filter);
|
||||||
while (pEntries.hasNext()) {
|
|
||||||
Entry entry = pEntries.next();
|
while (entries.hasNext()) {
|
||||||
|
Entry entry = entries.next();
|
||||||
|
|
||||||
if (entry.getValue() instanceof Directory) {
|
if (entry.getValue() instanceof Directory) {
|
||||||
appendTextEntriesFlat(node, (Directory) entry.getValue(), filter);
|
appendTextEntriesFlat(node, (Directory) entry.getValue(), filter);
|
||||||
@@ -694,7 +683,7 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
tag.setAttribute("keyword", fieldName);
|
tag.setAttribute("keyword", fieldName);
|
||||||
}
|
}
|
||||||
else {
|
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()));
|
tag.setAttribute("keyword", String.format("%s", entry.getIdentifier()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,14 +700,13 @@ public final class PSDMetadata extends AbstractMetadata {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IIOMetadataNode getStandardTransparencyNode() {
|
protected IIOMetadataNode getStandardTransparencyNode() {
|
||||||
IIOMetadataNode transparency_node = new IIOMetadataNode("Transparency");
|
IIOMetadataNode transparencyNode = new IIOMetadataNode("Transparency");
|
||||||
IIOMetadataNode node; // scratch node
|
|
||||||
|
|
||||||
node = new IIOMetadataNode("Alpha");
|
IIOMetadataNode node = new IIOMetadataNode("Alpha");
|
||||||
node.setAttribute("value", hasAlpha() ? "nonpremultiplied" : "none"); // TODO: Check spec
|
node.setAttribute("value", hasAlpha() ? "premultiplied" : "none");
|
||||||
transparency_node.appendChild(node);
|
transparencyNode.appendChild(node);
|
||||||
|
|
||||||
return transparency_node;
|
return transparencyNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasAlpha() {
|
private boolean hasAlpha() {
|
||||||
|
32
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadataFormat.java
Normal file → Executable file
32
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadataFormat.java
Normal file → Executable file
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||||
@@ -17,7 +45,7 @@ import java.util.Arrays;
|
|||||||
*/
|
*/
|
||||||
public final class PSDMetadataFormat extends IIOMetadataFormatImpl {
|
public final class PSDMetadataFormat extends IIOMetadataFormatImpl {
|
||||||
|
|
||||||
private final static PSDMetadataFormat sInstance = new PSDMetadataFormat();
|
private static final PSDMetadataFormat instance = new PSDMetadataFormat();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor.
|
* Private constructor.
|
||||||
@@ -207,6 +235,6 @@ public final class PSDMetadataFormat extends IIOMetadataFormatImpl {
|
|||||||
* @see javax.imageio.metadata.IIOMetadata#getMetadataFormat
|
* @see javax.imageio.metadata.IIOMetadata#getMetadataFormat
|
||||||
*/
|
*/
|
||||||
public static PSDMetadataFormat getInstance() {
|
public static PSDMetadataFormat getInstance() {
|
||||||
return sInstance;
|
return instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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 <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
36
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintFlags.java
Normal file → Executable file
36
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDPrintFlags.java
Normal file → Executable file
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
@@ -33,9 +61,13 @@ final class PSDPrintFlags extends PSDImageResource {
|
|||||||
negative = pInput.readBoolean();
|
negative = pInput.readBoolean();
|
||||||
flip = pInput.readBoolean();
|
flip = pInput.readBoolean();
|
||||||
interpolate = 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
|
@Override
|
||||||
|
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDResolutionInfo.java,v 1.0 May 2, 2008 3:58:19 PM haraldk Exp$
|
* @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
|
// typedef struct _ResolutionInfo
|
||||||
// {
|
// {
|
||||||
// LONG hRes; /* Fixed-point number: pixels per inch */
|
// LONG hRes; /* Fixed-point number: pixels per inch */
|
||||||
|
30
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDThumbnail.java
Normal file → Executable file
30
imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDThumbnail.java
Normal file → Executable file
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import javax.imageio.IIOException;
|
import javax.imageio.IIOException;
|
||||||
@@ -16,7 +44,7 @@ import java.io.IOException;
|
|||||||
* @author last modified by $Author: haraldk$
|
* @author last modified by $Author: haraldk$
|
||||||
* @version $Id: PSDThumbnail.java,v 1.0 Jul 29, 2009 4:41:06 PM haraldk Exp$
|
* @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 format;
|
||||||
private int width;
|
private int width;
|
||||||
private int height;
|
private int height;
|
||||||
|
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Harald Kuhr
|
* Copyright (c) 2014, Harald Kuhr
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||||
|
46
imageio/imageio-psd/src/test/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderTestCase.java
Normal file → Executable file
46
imageio/imageio-psd/src/test/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderTestCase.java
Normal file → Executable file
@@ -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;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase;
|
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase;
|
||||||
@@ -27,7 +55,7 @@ import static org.junit.Assert.*;
|
|||||||
*/
|
*/
|
||||||
public class PSDImageReaderTestCase extends ImageReaderAbstractTestCase<PSDImageReader> {
|
public class PSDImageReaderTestCase extends ImageReaderAbstractTestCase<PSDImageReader> {
|
||||||
|
|
||||||
static ImageReaderSpi provider = new PSDImageReaderSpi();
|
private static final ImageReaderSpi provider = new PSDImageReaderSpi();
|
||||||
|
|
||||||
protected List<TestData> getTestData() {
|
protected List<TestData> getTestData() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
@@ -48,7 +76,21 @@ public class PSDImageReaderTestCase extends ImageReaderAbstractTestCase<PSDImage
|
|||||||
// 1 channel, gray, 16 bit samples
|
// 1 channel, gray, 16 bit samples
|
||||||
new TestData(getClassLoaderResource("/psd/test_gray16.psd"), new Dimension(710, 512)),
|
new TestData(getClassLoaderResource("/psd/test_gray16.psd"), new Dimension(710, 512)),
|
||||||
// 4 channel, CMYK, 16 bit samples
|
// 4 channel, CMYK, 16 bit samples
|
||||||
new TestData(getClassLoaderResource("/psd/cmyk_16bits.psd"), new Dimension(1000, 275))
|
new TestData(getClassLoaderResource("/psd/cmyk_16bits.psd"), new Dimension(1000, 275)),
|
||||||
|
// 3 channel, RGB, 32 bit samples
|
||||||
|
new TestData(getClassLoaderResource("/psd/32bit5x5.psd"), new Dimension(5, 5)),
|
||||||
|
// 3 channel, RGB, 8 bit samples ("Large Document Format" aka PSB)
|
||||||
|
new TestData(getClassLoaderResource("/psd/test_original.psb"), new Dimension(710, 512)),
|
||||||
|
// From http://telegraphics.com.au/svn/psdparse/trunk/psd/
|
||||||
|
new TestData(getClassLoaderResource("/psd/adobehq.psd"), new Dimension(341, 512)),
|
||||||
|
new TestData(getClassLoaderResource("/psd/adobehq_ind.psd"), new Dimension(341, 512)),
|
||||||
|
// Contains a shorter than normal PrintFlags chunk
|
||||||
|
new TestData(getClassLoaderResource("/psd/adobehq-2.5.psd"), new Dimension(341, 512)),
|
||||||
|
new TestData(getClassLoaderResource("/psd/adobehq-3.0.psd"), new Dimension(341, 512)),
|
||||||
|
new TestData(getClassLoaderResource("/psd/adobehq-5.5.psd"), new Dimension(341, 512)),
|
||||||
|
new TestData(getClassLoaderResource("/psd/adobehq-7.0.psd"), new Dimension(341, 512)),
|
||||||
|
// From https://github.com/kmike/psd-tools/tree/master/tests/psd_files
|
||||||
|
new TestData(getClassLoaderResource("/psd/masks2.psd"), new Dimension(640, 1136)) // TODO: Test read layers!
|
||||||
// TODO: Need uncompressed PSD
|
// TODO: Need uncompressed PSD
|
||||||
// TODO: Need more recent ZIP compressed PSD files from CS2/CS3+
|
// TODO: Need more recent ZIP compressed PSD files from CS2/CS3+
|
||||||
);
|
);
|
||||||
|
BIN
imageio/imageio-psd/src/test/resources/psd/32bit5x5.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/32bit5x5.psd
Executable file
Binary file not shown.
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq-2.5.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq-2.5.psd
Executable file
Binary file not shown.
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq-3.0.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq-3.0.psd
Executable file
Binary file not shown.
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq-5.5.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq-5.5.psd
Executable file
Binary file not shown.
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq-7.0.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq-7.0.psd
Executable file
Binary file not shown.
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq.psd
Executable file
Binary file not shown.
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq_ind.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq_ind.psd
Executable file
Binary file not shown.
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq_layers.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq_layers.psd
Executable file
Binary file not shown.
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq_layers.v5.maxcompat.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq_layers.v5.maxcompat.psd
Executable file
Binary file not shown.
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq_layers.v5.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/adobehq_layers.v5.psd
Executable file
Binary file not shown.
BIN
imageio/imageio-psd/src/test/resources/psd/masks2.psd
Executable file
BIN
imageio/imageio-psd/src/test/resources/psd/masks2.psd
Executable file
Binary file not shown.
Reference in New Issue
Block a user