mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-03 11:35:29 -04:00
Revert "Work in progress for PSD metadata support:"
This reverts commit 0d41db32cf91ec87b5070e69ee683c49f51b0fa9.
This commit is contained in:
parent
0d41db32cf
commit
e8a4cc048c
@ -101,7 +101,7 @@ interface PSD {
|
|||||||
int COMPRESSION_ZIP = 2;
|
int COMPRESSION_ZIP = 2;
|
||||||
|
|
||||||
/** ZIP compression with prediction */
|
/** ZIP compression with prediction */
|
||||||
int COMPRESSION_ZIP_PREDICTION = 3;
|
int COMPRESSION_ZIP_PREDICTON = 3;
|
||||||
|
|
||||||
// Color Modes
|
// Color Modes
|
||||||
/** Bitmap (monochrome) */
|
/** Bitmap (monochrome) */
|
||||||
|
@ -48,11 +48,11 @@ class PSDAlphaChannelInfo extends PSDImageResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readData(final ImageInputStream pInput) throws IOException {
|
protected void readData(ImageInputStream pInput) throws IOException {
|
||||||
mNames = new ArrayList<String>();
|
mNames = new ArrayList<String>();
|
||||||
long left = mSize;
|
long left = mSize;
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
String name = PSDUtil.readPascalString(pInput);
|
String name = PSDUtil.readPascalStringByte(pInput);
|
||||||
mNames.add(name);
|
mNames.add(name);
|
||||||
left -= name.length() + 1;
|
left -= name.length() + 1;
|
||||||
}
|
}
|
||||||
|
@ -40,22 +40,7 @@ import java.io.IOException;
|
|||||||
* @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 {
|
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:
|
|
||||||
// PSD_CS_RGB = 0, /* RGB */
|
|
||||||
// PSD_CS_HSB = 1, /* Hue, Saturation, Brightness */
|
|
||||||
// PSD_CS_CMYK = 2, /* CMYK */
|
|
||||||
// PSD_CS_PANTONE = 3, /* Pantone matching system (Lab)*/
|
|
||||||
// PSD_CS_FOCOLTONE = 4, /* Focoltone colour system (CMYK)*/
|
|
||||||
// PSD_CS_TRUMATCH = 5, /* Trumatch color (CMYK)*/
|
|
||||||
// PSD_CS_TOYO = 6, /* Toyo 88 colorfinder 1050 (Lab)*/
|
|
||||||
// PSD_CS_LAB = 7, /* L*a*b*/
|
|
||||||
// PSD_CS_GRAYSCALE = 8, /* Grey scale */
|
|
||||||
// PSD_CS_HKS = 10, /* HKS colors (CMYK)*/
|
|
||||||
// PSD_CS_DIC = 11, /* DIC color guide (Lab)*/
|
|
||||||
// PSD_CS_ANPA = 3000, /* Anpa color (Lab)*/
|
|
||||||
|
|
||||||
//typedef _DisplayInfo
|
//typedef _DisplayInfo
|
||||||
//{
|
//{
|
||||||
// WORD ColorSpace;
|
// WORD ColorSpace;
|
||||||
@ -65,10 +50,10 @@ class PSDDisplayInfo extends PSDImageResource {
|
|||||||
// BYTE Padding; /* Always zero */
|
// BYTE Padding; /* Always zero */
|
||||||
//} DISPLAYINFO;
|
//} DISPLAYINFO;
|
||||||
|
|
||||||
int mColorSpace;
|
private int mColorSpace;
|
||||||
short[] mColors;
|
private short[] mColors;
|
||||||
short mOpacity;
|
private short mOpacity;
|
||||||
byte mKind;
|
private byte mKind;
|
||||||
|
|
||||||
PSDDisplayInfo(final short pId, final ImageInputStream pInput) throws IOException {
|
PSDDisplayInfo(final short pId, final ImageInputStream pInput) throws IOException {
|
||||||
super(pId, pInput);
|
super(pId, pInput);
|
||||||
|
@ -10,7 +10,6 @@ import java.io.IOException;
|
|||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,8 +67,8 @@ final class PSDEXIF1Data extends PSDImageResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TIFF Image file directory (IFD)
|
// TIFF Image file directory (IFD)
|
||||||
static class Directory implements Iterable<Entry> {
|
private static class Directory {
|
||||||
private List<Entry> mEntries = new ArrayList<Entry>();
|
List<Entry> mEntries = new ArrayList<Entry>();
|
||||||
|
|
||||||
private Directory() {}
|
private Directory() {}
|
||||||
|
|
||||||
@ -91,20 +90,6 @@ final class PSDEXIF1Data extends PSDImageResource {
|
|||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entry get(int pTag) {
|
|
||||||
for (Entry entry : mEntries) {
|
|
||||||
if (entry.mTag == pTag) {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<Entry> iterator() {
|
|
||||||
return mEntries.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("Directory%s", mEntries);
|
return String.format("Directory%s", mEntries);
|
||||||
@ -112,7 +97,7 @@ final class PSDEXIF1Data extends PSDImageResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TIFF IFD Entry
|
// TIFF IFD Entry
|
||||||
static class Entry {
|
private static class Entry {
|
||||||
private static final int EXIF_IFD = 0x8769;
|
private static final int EXIF_IFD = 0x8769;
|
||||||
|
|
||||||
private final static String[] TYPE_NAMES = {
|
private final static String[] TYPE_NAMES = {
|
||||||
|
@ -28,9 +28,6 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.imageio.plugins.psd;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
|
|
||||||
import javax.imageio.metadata.IIOMetadataNode;
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
import javax.imageio.IIOException;
|
import javax.imageio.IIOException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -64,7 +61,7 @@ class PSDHeader {
|
|||||||
final short mBits;
|
final short mBits;
|
||||||
final short mMode;
|
final short mMode;
|
||||||
|
|
||||||
PSDHeader(final ImageInputStream pInput) throws IOException {
|
PSDHeader(ImageInputStream 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) + ")");
|
||||||
|
@ -69,12 +69,11 @@ import java.util.List;
|
|||||||
// See http://www.adobeforums.com/webx?14@@.3bc381dc/0
|
// See http://www.adobeforums.com/webx?14@@.3bc381dc/0
|
||||||
public class PSDImageReader extends ImageReaderBase {
|
public class PSDImageReader extends ImageReaderBase {
|
||||||
private PSDHeader mHeader;
|
private PSDHeader mHeader;
|
||||||
// private PSDColorData mColorData;
|
private PSDColorData mColorData;
|
||||||
// private List<PSDImageResource> mImageResources;
|
private List<PSDImageResource> mImageResources;
|
||||||
// private PSDGlobalLayerMask mGlobalLayerMask;
|
private PSDGlobalLayerMask mGlobalLayerMask;
|
||||||
// private List<PSDLayerInfo> mLayerInfo;
|
private List<PSDLayerInfo> mLayerInfo;
|
||||||
private ICC_ColorSpace mColorSpace;
|
private ICC_ColorSpace mColorSpace;
|
||||||
protected PSDMetadata mMetadata;
|
|
||||||
|
|
||||||
protected PSDImageReader(final ImageReaderSpi pOriginatingProvider) {
|
protected PSDImageReader(final ImageReaderSpi pOriginatingProvider) {
|
||||||
super(pOriginatingProvider);
|
super(pOriginatingProvider);
|
||||||
@ -82,9 +81,8 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
protected void resetMembers() {
|
protected void resetMembers() {
|
||||||
mHeader = null;
|
mHeader = null;
|
||||||
// mColorData = null;
|
mColorData = null;
|
||||||
// mImageResources = null;
|
mImageResources = null;
|
||||||
mMetadata = null;
|
|
||||||
mColorSpace = null;
|
mColorSpace = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +122,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
case PSD.COLOR_MODE_INDEXED:
|
case PSD.COLOR_MODE_INDEXED:
|
||||||
// TODO: 16 bit indexed?! Does it exist?
|
// TODO: 16 bit indexed?! Does it exist?
|
||||||
if (mHeader.mChannels == 1 && mHeader.mBits == 8) {
|
if (mHeader.mChannels == 1 && mHeader.mBits == 8) {
|
||||||
return IndexedImageTypeSpecifier.createFromIndexColorModel(mMetadata.mColorData.getIndexColorModel());
|
return IndexedImageTypeSpecifier.createFromIndexColorModel(mColorData.getIndexColorModel());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IIOException(
|
throw new IIOException(
|
||||||
@ -266,7 +264,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
if (mColorSpace == null) {
|
if (mColorSpace == null) {
|
||||||
ICC_Profile profile = null;
|
ICC_Profile profile = null;
|
||||||
for (PSDImageResource resource : mMetadata.mImageResources) {
|
for (PSDImageResource resource : mImageResources) {
|
||||||
if (resource instanceof ICCProfile) {
|
if (resource instanceof ICCProfile) {
|
||||||
profile = ((ICCProfile) resource).getProfile();
|
profile = ((ICCProfile) resource).getProfile();
|
||||||
break;
|
break;
|
||||||
@ -335,8 +333,6 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
int[] byteCounts = null;
|
int[] byteCounts = null;
|
||||||
int compression = mImageInput.readShort();
|
int compression = mImageInput.readShort();
|
||||||
// TODO: Need to make sure compression is set in metadata, even without reading the image data!
|
|
||||||
mMetadata.mCompression = compression;
|
|
||||||
|
|
||||||
switch (compression) {
|
switch (compression) {
|
||||||
case PSD.COMPRESSION_NONE:
|
case PSD.COMPRESSION_NONE:
|
||||||
@ -350,7 +346,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
break;
|
break;
|
||||||
case PSD.COMPRESSION_ZIP:
|
case PSD.COMPRESSION_ZIP:
|
||||||
// TODO: Could probably use the ZIPDecoder (DeflateDecoder) here..
|
// TODO: Could probably use the ZIPDecoder (DeflateDecoder) here..
|
||||||
case PSD.COMPRESSION_ZIP_PREDICTION:
|
case PSD.COMPRESSION_ZIP_PREDICTON:
|
||||||
// TODO: Need to find out if the normal java.util.zip can handle this...
|
// TODO: Need to find out if the normal java.util.zip can handle this...
|
||||||
// Could be same as PNG prediction? Read up...
|
// Could be same as PNG prediction? Read up...
|
||||||
throw new IIOException("ZIP compression not supported yet");
|
throw new IIOException("ZIP compression not supported yet");
|
||||||
@ -697,9 +693,6 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
if (mHeader == null) {
|
if (mHeader == null) {
|
||||||
mHeader = new PSDHeader(mImageInput);
|
mHeader = new PSDHeader(mImageInput);
|
||||||
|
|
||||||
mMetadata = new PSDMetadata();
|
|
||||||
mMetadata.mHeader = mHeader;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Contains the required data to define the color mode.
|
Contains the required data to define the color mode.
|
||||||
|
|
||||||
@ -712,7 +705,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
around as a black box for use when saving the file.
|
around as a black box for use when saving the file.
|
||||||
*/
|
*/
|
||||||
if (mHeader.mMode == PSD.COLOR_MODE_INDEXED) {
|
if (mHeader.mMode == PSD.COLOR_MODE_INDEXED) {
|
||||||
mMetadata.mColorData = new PSDColorData(mImageInput);
|
mColorData = new PSDColorData(mImageInput);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: We need to store the duotone spec if we decide to create a writer...
|
// TODO: We need to store the duotone spec if we decide to create a writer...
|
||||||
@ -736,14 +729,14 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
long length = mImageInput.readUnsignedInt();
|
long length = mImageInput.readUnsignedInt();
|
||||||
|
|
||||||
if (pParseData && length > 0) {
|
if (pParseData && length > 0) {
|
||||||
if (mMetadata.mImageResources == null) {
|
if (mImageResources == null) {
|
||||||
mMetadata.mImageResources = new ArrayList<PSDImageResource>();
|
mImageResources = new ArrayList<PSDImageResource>();
|
||||||
long expectedEnd = mImageInput.getStreamPosition() + length;
|
long expectedEnd = mImageInput.getStreamPosition() + length;
|
||||||
|
|
||||||
while (mImageInput.getStreamPosition() < expectedEnd) {
|
while (mImageInput.getStreamPosition() < expectedEnd) {
|
||||||
// TODO: Have PSDImageResources defer actual parsing? (Just store stream offsets)
|
// TODO: Have PSDImageResources defer actual parsing? (Just store stream offsets)
|
||||||
PSDImageResource resource = PSDImageResource.read(mImageInput);
|
PSDImageResource resource = PSDImageResource.read(mImageInput);
|
||||||
mMetadata.mImageResources.add(resource);
|
mImageResources.add(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mImageInput.getStreamPosition() != expectedEnd) {
|
if (mImageInput.getStreamPosition() != expectedEnd) {
|
||||||
@ -777,7 +770,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
for (int i = 0; i < layerInfos.length; i++) {
|
for (int i = 0; i < layerInfos.length; i++) {
|
||||||
layerInfos[i] = new PSDLayerInfo(mImageInput);
|
layerInfos[i] = new PSDLayerInfo(mImageInput);
|
||||||
}
|
}
|
||||||
mMetadata.mLayerInfo = Arrays.asList(layerInfos);
|
mLayerInfo = Arrays.asList(layerInfos);
|
||||||
|
|
||||||
// TODO: Clean-up
|
// TODO: Clean-up
|
||||||
mImageInput.mark();
|
mImageInput.mark();
|
||||||
@ -790,9 +783,9 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
BufferedImage layer = readLayerData(layerInfo, raw, imageType);
|
BufferedImage layer = readLayerData(layerInfo, raw, imageType);
|
||||||
|
|
||||||
// TODO: Don't show! Store in meta data somehow...
|
// TODO: Don't show! Store in meta data somehow...
|
||||||
// if (layer != null) {
|
if (layer != null) {
|
||||||
// showIt(layer, layerInfo.mLayerName + " " + layerInfo.mBlendMode.toString());
|
showIt(layer, layerInfo.mLayerName + " " + layerInfo.mBlendMode.toString());
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long read = mImageInput.getStreamPosition() - pos;
|
long read = mImageInput.getStreamPosition() - pos;
|
||||||
@ -806,7 +799,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
long layerMaskInfoLength = mImageInput.readUnsignedInt();
|
long layerMaskInfoLength = mImageInput.readUnsignedInt();
|
||||||
// System.out.println("GlobalLayerMaskInfo length: " + layerMaskInfoLength);
|
// System.out.println("GlobalLayerMaskInfo length: " + layerMaskInfoLength);
|
||||||
if (layerMaskInfoLength > 0) {
|
if (layerMaskInfoLength > 0) {
|
||||||
mMetadata.mGlobalLayerMask = new PSDGlobalLayerMask(mImageInput);
|
mGlobalLayerMask = new PSDGlobalLayerMask(mImageInput);
|
||||||
// System.out.println("mGlobalLayerMask: " + mGlobalLayerMask);
|
// System.out.println("mGlobalLayerMask: " + mGlobalLayerMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -884,7 +877,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case PSD.COMPRESSION_ZIP:
|
case PSD.COMPRESSION_ZIP:
|
||||||
case PSD.COMPRESSION_ZIP_PREDICTION:
|
case PSD.COMPRESSION_ZIP_PREDICTON:
|
||||||
default:
|
default:
|
||||||
// Explicitly skipped above
|
// Explicitly skipped above
|
||||||
throw new AssertionError(String.format("Unsupported layer data. Compression: %d", compression));
|
throw new AssertionError(String.format("Unsupported layer data. Compression: %d", compression));
|
||||||
@ -992,19 +985,16 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
readImageResources(true);
|
readImageResources(true);
|
||||||
readLayerAndMaskInfo(true);
|
readLayerAndMaskInfo(true);
|
||||||
|
|
||||||
// TODO: Need to make sure compression is set in metadata, even without reading the image data!
|
PSDMetadata metadata = new PSDMetadata();
|
||||||
mMetadata.mCompression = mImageInput.readShort();
|
metadata.mHeader = mHeader;
|
||||||
|
metadata.mColorData = mColorData;
|
||||||
// mMetadata.mHeader = mHeader;
|
metadata.mImageResources = mImageResources;
|
||||||
// mMetadata.mColorData = mColorData;
|
return metadata;
|
||||||
// mMetadata.mImageResources = mImageResources;
|
|
||||||
|
|
||||||
return mMetadata; // TODO: clone if we change to mutable metadata
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IIOMetadata getImageMetadata(final int imageIndex, final String formatName, final Set<String> nodeNames) throws IOException {
|
public IIOMetadata getImageMetadata(final int imageIndex, final String formatName, final Set<String> nodeNames) throws IOException {
|
||||||
// TODO: It might make sense to overload this, as there's loads of meta data in the file
|
// TODO: This might make sense, as there's loads of meta data in the file
|
||||||
return super.getImageMetadata(imageIndex, formatName, nodeNames);
|
return super.getImageMetadata(imageIndex, formatName, nodeNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1021,14 +1011,14 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
List<PSDThumbnail> thumbnails = null;
|
List<PSDThumbnail> thumbnails = null;
|
||||||
|
|
||||||
if (mMetadata.mImageResources == null) {
|
if (mImageResources == 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
|
// TODO: Skip this, requires storing some stream offsets
|
||||||
readLayerAndMaskInfo(false);
|
readLayerAndMaskInfo(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PSDImageResource resource : mMetadata.mImageResources) {
|
for (PSDImageResource resource : mImageResources) {
|
||||||
if (resource instanceof PSDThumbnail) {
|
if (resource instanceof PSDThumbnail) {
|
||||||
if (thumbnails == null) {
|
if (thumbnails == null) {
|
||||||
thumbnails = new ArrayList<PSDThumbnail>();
|
thumbnails = new ArrayList<PSDThumbnail>();
|
||||||
@ -1130,25 +1120,15 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
// System.out.println("imageReader.mHeader: " + imageReader.mHeader);
|
// System.out.println("imageReader.mHeader: " + imageReader.mHeader);
|
||||||
|
|
||||||
imageReader.readImageResources(true);
|
imageReader.readImageResources(true);
|
||||||
System.out.println("imageReader.mImageResources: " + imageReader.mMetadata.mImageResources);
|
System.out.println("imageReader.mImageResources: " + imageReader.mImageResources);
|
||||||
System.out.println();
|
|
||||||
|
|
||||||
imageReader.readLayerAndMaskInfo(true);
|
imageReader.readLayerAndMaskInfo(true);
|
||||||
System.out.println("imageReader.mLayerInfo: " + imageReader.mMetadata.mLayerInfo);
|
System.out.println("imageReader.mLayerInfo: " + imageReader.mLayerInfo);
|
||||||
// System.out.println("imageReader.mGlobalLayerMask: " + imageReader.mGlobalLayerMask);
|
// System.out.println("imageReader.mGlobalLayerMask: " + imageReader.mGlobalLayerMask);
|
||||||
System.out.println();
|
|
||||||
|
|
||||||
IIOMetadata metadata = imageReader.getImageMetadata(0);
|
IIOMetadata metadata = imageReader.getImageMetadata(0);
|
||||||
Node node;
|
Node node = metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
|
||||||
XMLSerializer serializer;
|
XMLSerializer serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
|
||||||
|
|
||||||
node = metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
|
|
||||||
serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
|
|
||||||
serializer.serialize(node, true);
|
|
||||||
System.out.println();
|
|
||||||
|
|
||||||
node = metadata.getAsTree(PSDMetadata.NATIVE_METADATA_FORMAT_NAME);
|
|
||||||
serializer = new XMLSerializer(System.out, System.getProperty("file.encoding"));
|
|
||||||
serializer.serialize(node, true);
|
serializer.serialize(node, true);
|
||||||
|
|
||||||
if (imageReader.hasThumbnails(0)) {
|
if (imageReader.hasThumbnails(0)) {
|
||||||
|
@ -28,8 +28,6 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.imageio.plugins.psd;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import com.twelvemonkeys.lang.StringUtil;
|
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
import javax.imageio.IIOException;
|
import javax.imageio.IIOException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -52,12 +50,6 @@ class PSDImageResource {
|
|||||||
|
|
||||||
mName = PSDUtil.readPascalString(pInput);
|
mName = PSDUtil.readPascalString(pInput);
|
||||||
|
|
||||||
// Skip pad
|
|
||||||
int nameSize = mName.length() + 1;
|
|
||||||
if (nameSize % 2 != 0) {
|
|
||||||
pInput.readByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
mSize = pInput.readUnsignedInt();
|
mSize = pInput.readUnsignedInt();
|
||||||
readData(pInput);
|
readData(pInput);
|
||||||
|
|
||||||
@ -92,10 +84,7 @@ class PSDImageResource {
|
|||||||
protected StringBuilder toStringBuilder() {
|
protected StringBuilder toStringBuilder() {
|
||||||
StringBuilder builder = new StringBuilder(getClass().getSimpleName());
|
StringBuilder builder = new StringBuilder(getClass().getSimpleName());
|
||||||
|
|
||||||
String fakeType = resourceTypeForId(mId);
|
builder.append(resourceTypeForId(mId));
|
||||||
if (fakeType != null) {
|
|
||||||
builder.append("(").append(fakeType).append(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.append("[ID: 0x");
|
builder.append("[ID: 0x");
|
||||||
builder.append(Integer.toHexString(mId));
|
builder.append(Integer.toHexString(mId));
|
||||||
@ -117,25 +106,23 @@ class PSDImageResource {
|
|||||||
case PSD.RES_THUMBNAIL_PS4:
|
case PSD.RES_THUMBNAIL_PS4:
|
||||||
case PSD.RES_THUMBNAIL:
|
case PSD.RES_THUMBNAIL:
|
||||||
case PSD.RES_ICC_PROFILE:
|
case PSD.RES_ICC_PROFILE:
|
||||||
case PSD.RES_VERSION_INFO:
|
|
||||||
case PSD.RES_EXIF_DATA_1:
|
case PSD.RES_EXIF_DATA_1:
|
||||||
// case PSD.RES_EXIF_DATA_3:
|
// case PSD.RES_EXIF_DATA_3:
|
||||||
case PSD.RES_XMP_DATA:
|
case PSD.RES_XMP_DATA:
|
||||||
case PSD.RES_PRINT_FLAGS_INFORMATION:
|
case PSD.RES_PRINT_FLAGS_INFORMATION:
|
||||||
return null;
|
return "";
|
||||||
default:
|
default:
|
||||||
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) {
|
||||||
String name = field.getName().substring(4);
|
return "(" + field.getName().substring(4) + ")";
|
||||||
return StringUtil.lispToCamel(name.replace("_", "-").toLowerCase(), true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException ignore) {
|
catch (IllegalAccessException ignore) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown resource";
|
return "(unknown resource)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,8 +149,6 @@ class PSDImageResource {
|
|||||||
return new PSDThumbnail(id, pInput);
|
return new PSDThumbnail(id, pInput);
|
||||||
case PSD.RES_ICC_PROFILE:
|
case PSD.RES_ICC_PROFILE:
|
||||||
return new ICCProfile(id, pInput);
|
return new ICCProfile(id, pInput);
|
||||||
case PSD.RES_VERSION_INFO:
|
|
||||||
return new PSDVersionInfo(id, pInput);
|
|
||||||
case PSD.RES_EXIF_DATA_1:
|
case PSD.RES_EXIF_DATA_1:
|
||||||
return new PSDEXIF1Data(id, pInput);
|
return new PSDEXIF1Data(id, pInput);
|
||||||
case PSD.RES_XMP_DATA:
|
case PSD.RES_XMP_DATA:
|
||||||
|
@ -98,12 +98,14 @@ class PSDLayerInfo {
|
|||||||
mLayerName = PSDUtil.readPascalString(pInput);
|
mLayerName = PSDUtil.readPascalString(pInput);
|
||||||
|
|
||||||
int layerNameSize = mLayerName.length() + 1;
|
int layerNameSize = mLayerName.length() + 1;
|
||||||
|
// readPascalString has already read pad byte for word alignment
|
||||||
// Skip pad bytes for long word alignment
|
if (layerNameSize % 2 != 0) {
|
||||||
|
layerNameSize++;
|
||||||
|
}
|
||||||
|
// Skip two more pad bytes if needed
|
||||||
if (layerNameSize % 4 != 0) {
|
if (layerNameSize % 4 != 0) {
|
||||||
int skip = layerNameSize % 4;
|
pInput.skipBytes(2);
|
||||||
pInput.skipBytes(skip);
|
layerNameSize += 2;
|
||||||
layerNameSize += skip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: There's some data skipped here...
|
// TODO: There's some data skipped here...
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
package com.twelvemonkeys.imageio.plugins.psd;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import com.twelvemonkeys.lang.StringUtil;
|
import com.twelvemonkeys.lang.StringUtil;
|
||||||
import com.twelvemonkeys.util.FilterIterator;
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
|
|
||||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||||
import javax.imageio.metadata.IIOMetadata;
|
import javax.imageio.metadata.IIOMetadata;
|
||||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||||
import javax.imageio.metadata.IIOMetadataNode;
|
import javax.imageio.metadata.IIOMetadataNode;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import java.awt.image.IndexColorModel;
|
import java.awt.image.IndexColorModel;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,28 +21,16 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
||||||
|
|
||||||
// TODO: Decide on image/stream metadata...
|
static final String NATIVE_METADATA_FORMAT_NAME = "com_twelvemonkeys_imageio_psd_1.0";
|
||||||
static final String NATIVE_METADATA_FORMAT_NAME = "com_twelvemonkeys_imageio_psd_image_1.0";
|
|
||||||
static final String NATIVE_METADATA_FORMAT_CLASS_NAME = "com.twelvemonkeys.imageio.plugins.psd.PSDMetadataFormat";
|
static final String NATIVE_METADATA_FORMAT_CLASS_NAME = "com.twelvemonkeys.imageio.plugins.psd.PSDMetadataFormat";
|
||||||
|
|
||||||
|
// TODO: Move fields from PSDImageReader (header, color map, resources, etc) here
|
||||||
PSDHeader mHeader;
|
PSDHeader mHeader;
|
||||||
PSDColorData mColorData;
|
PSDColorData mColorData;
|
||||||
int mCompression = -1;
|
|
||||||
List<PSDImageResource> mImageResources;
|
List<PSDImageResource> mImageResources;
|
||||||
PSDGlobalLayerMask mGlobalLayerMask;
|
PSDGlobalLayerMask mGlobalLayerMask;
|
||||||
List<PSDLayerInfo> mLayerInfo;
|
List<PSDLayerInfo> mLayerInfo;
|
||||||
|
|
||||||
static final String[] COLOR_MODES = {
|
|
||||||
"MONOCHROME", "GRAYSCALE", "INDEXED", "RGB", "CMYK", null, null, "MULTICHANNEL", "DUOTONE", "LAB"
|
|
||||||
};
|
|
||||||
|
|
||||||
static final String[] DISPLAY_INFO_CS = {
|
|
||||||
"RGB", "HSB", "CMYK", "PANTONE", "FOCOLTONE", "TRUMATCH", "TOYO", "LAB", "GRAYSCALE", null, "HKS", "DIC",
|
|
||||||
null, // ... (until index 2999),
|
|
||||||
"ANPA"
|
|
||||||
};
|
|
||||||
static final String[] DISPLAY_INFO_KINDS = {"selected", "protected"};
|
|
||||||
|
|
||||||
protected PSDMetadata() {
|
protected PSDMetadata() {
|
||||||
// TODO: Allow XMP, EXIF and IPTC as extra formats?
|
// TODO: Allow XMP, EXIF and IPTC as extra formats?
|
||||||
super(true, NATIVE_METADATA_FORMAT_NAME, NATIVE_METADATA_FORMAT_CLASS_NAME, null, null);
|
super(true, NATIVE_METADATA_FORMAT_NAME, NATIVE_METADATA_FORMAT_CLASS_NAME, null, null);
|
||||||
@ -136,112 +119,8 @@ public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Native format support
|
|
||||||
|
|
||||||
private Node getNativeTree() {
|
private Node getNativeTree() {
|
||||||
IIOMetadataNode root = new IIOMetadataNode(NATIVE_METADATA_FORMAT_NAME);
|
throw new UnsupportedOperationException("getNativeTree");
|
||||||
|
|
||||||
root.appendChild(createHeaderNode());
|
|
||||||
|
|
||||||
if (mHeader.mMode == PSD.COLOR_MODE_INDEXED) {
|
|
||||||
root.appendChild(createPaletteNode());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mImageResources != null && !mImageResources.isEmpty()) {
|
|
||||||
root.appendChild(createImageResourcesNode());
|
|
||||||
}
|
|
||||||
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Node createHeaderNode() {
|
|
||||||
IIOMetadataNode header = new IIOMetadataNode("PSDHeader");
|
|
||||||
|
|
||||||
header.setAttribute("version", "1");
|
|
||||||
header.setAttribute("channels", Integer.toString(mHeader.mChannels));
|
|
||||||
header.setAttribute("height", Integer.toString(mHeader.mHeight));
|
|
||||||
header.setAttribute("width", Integer.toString(mHeader.mWidth));
|
|
||||||
header.setAttribute("bits", Integer.toString(mHeader.mBits));
|
|
||||||
header.setAttribute("mode", COLOR_MODES[mHeader.mMode]);
|
|
||||||
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Node createImageResourcesNode() {
|
|
||||||
IIOMetadataNode resource = new IIOMetadataNode("ImageResources");
|
|
||||||
IIOMetadataNode node;
|
|
||||||
|
|
||||||
for (PSDImageResource imageResource : mImageResources) {
|
|
||||||
// TODO: Always add name (if set) and id (as resourceId) to all nodes?
|
|
||||||
// Resource Id is useful for people with access to the PSD spec..
|
|
||||||
|
|
||||||
if (imageResource instanceof PSDAlphaChannelInfo) {
|
|
||||||
PSDAlphaChannelInfo alphaChannelInfo = (PSDAlphaChannelInfo) imageResource;
|
|
||||||
|
|
||||||
node = new IIOMetadataNode("AlphaChannelInfo");
|
|
||||||
|
|
||||||
for (String name : alphaChannelInfo.mNames) {
|
|
||||||
IIOMetadataNode nameNode = new IIOMetadataNode("Name");
|
|
||||||
nameNode.setAttribute("value", name);
|
|
||||||
node.appendChild(nameNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
resource.appendChild(node);
|
|
||||||
}
|
|
||||||
else if (imageResource instanceof PSDDisplayInfo) {
|
|
||||||
PSDDisplayInfo displayInfo = (PSDDisplayInfo) imageResource;
|
|
||||||
|
|
||||||
node = new IIOMetadataNode("DisplayInfo");
|
|
||||||
node.setAttribute("colorSpace", DISPLAY_INFO_CS[displayInfo.mColorSpace]);
|
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
for (short color : displayInfo.mColors) {
|
|
||||||
if (builder.length() > 0) {
|
|
||||||
builder.append(" ");
|
|
||||||
}
|
|
||||||
builder.append(Integer.toString(color));
|
|
||||||
}
|
|
||||||
|
|
||||||
node.setAttribute("colors", builder.toString());
|
|
||||||
node.setAttribute("opacity", Integer.toString(displayInfo.mOpacity));
|
|
||||||
node.setAttribute("kind", DISPLAY_INFO_KINDS[displayInfo.mKind]);
|
|
||||||
|
|
||||||
resource.appendChild(node);
|
|
||||||
}
|
|
||||||
else if (imageResource instanceof PSDXMPData) {
|
|
||||||
// TODO: Revise/rethink this...
|
|
||||||
PSDXMPData xmp = (PSDXMPData) imageResource;
|
|
||||||
|
|
||||||
node = new IIOMetadataNode("XMPData");
|
|
||||||
|
|
||||||
try {
|
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
||||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
|
||||||
Document document = builder.parse(new InputSource(xmp.getData()));
|
|
||||||
|
|
||||||
// Set the entire XMP document as user data
|
|
||||||
node.setUserObject(document);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
resource.appendChild(node);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Generic resource..
|
|
||||||
node = new IIOMetadataNode(PSDImageResource.resourceTypeForId(imageResource.mId));
|
|
||||||
|
|
||||||
resource.appendChild(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: More resources
|
|
||||||
|
|
||||||
node.setAttribute("resourceId", Integer.toHexString(imageResource.mId));
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Standard format support
|
/// Standard format support
|
||||||
@ -256,7 +135,7 @@ public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
|||||||
switch (mHeader.mMode) {
|
switch (mHeader.mMode) {
|
||||||
case PSD.COLOR_MODE_MONOCHROME:
|
case PSD.COLOR_MODE_MONOCHROME:
|
||||||
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 is spec says treat as gray...
|
||||||
cs = "GRAY";
|
cs = "GRAY";
|
||||||
break;
|
break;
|
||||||
case PSD.COLOR_MODE_RGB:
|
case PSD.COLOR_MODE_RGB:
|
||||||
@ -267,7 +146,8 @@ public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
|||||||
cs = "CMYK";
|
cs = "CMYK";
|
||||||
break;
|
break;
|
||||||
case PSD.COLOR_MODE_MULTICHANNEL:
|
case PSD.COLOR_MODE_MULTICHANNEL:
|
||||||
cs = getMultiChannelCS(mHeader.mChannels);
|
// TODO: FixMe
|
||||||
|
cs = "???";
|
||||||
break;
|
break;
|
||||||
case PSD.COLOR_MODE_LAB:
|
case PSD.COLOR_MODE_LAB:
|
||||||
cs = "Lab";
|
cs = "Lab";
|
||||||
@ -278,22 +158,42 @@ public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
|||||||
node.setAttribute("name", cs);
|
node.setAttribute("name", cs);
|
||||||
chroma_node.appendChild(node);
|
chroma_node.appendChild(node);
|
||||||
|
|
||||||
// TODO: Channels might be 5 for RGB + A + Mask... Probably not correct
|
// TODO: Channels might be 5 for RGB + A + Mask...
|
||||||
node = new IIOMetadataNode("NumChannels");
|
node = new IIOMetadataNode("NumChannels");
|
||||||
node.setAttribute("value", Integer.toString(mHeader.mChannels));
|
node.setAttribute("value", Integer.toString(mHeader.mChannels));
|
||||||
chroma_node.appendChild(node);
|
chroma_node.appendChild(node);
|
||||||
|
|
||||||
|
// if (gAMA_present) {
|
||||||
|
// node = new IIOMetadataNode("Gamma");
|
||||||
|
// node.setAttribute("value", Float.toString(gAMA_gamma*1.0e-5F));
|
||||||
|
// chroma_node.appendChild(node);
|
||||||
|
// }
|
||||||
|
|
||||||
// TODO: Check if this is correct with bitmap (monchrome)
|
// TODO: Check if this is correct with bitmap (monchrome)
|
||||||
node = new IIOMetadataNode("BlackIsZero");
|
node = new IIOMetadataNode("BlackIsZero");
|
||||||
node.setAttribute("value", "true");
|
node.setAttribute("value", "true");
|
||||||
chroma_node.appendChild(node);
|
chroma_node.appendChild(node);
|
||||||
|
|
||||||
if (mHeader.mMode == PSD.COLOR_MODE_INDEXED) {
|
if (mHeader.mMode == PSD.COLOR_MODE_INDEXED) {
|
||||||
node = createPaletteNode();
|
node = new IIOMetadataNode("Palette");
|
||||||
|
|
||||||
|
IndexColorModel cm = mColorData.getIndexColorModel();
|
||||||
|
for (int i = 0; i < cm.getMapSize(); i++) {
|
||||||
|
IIOMetadataNode entry =
|
||||||
|
new IIOMetadataNode("PaletteEntry");
|
||||||
|
entry.setAttribute("index", Integer.toString(i));
|
||||||
|
entry.setAttribute("red",
|
||||||
|
Integer.toString(cm.getRed(i)));
|
||||||
|
entry.setAttribute("green",
|
||||||
|
Integer.toString(cm.getGreen(i)));
|
||||||
|
entry.setAttribute("blue",
|
||||||
|
Integer.toString(cm.getBlue(i)));
|
||||||
|
|
||||||
|
node.appendChild(entry);
|
||||||
|
}
|
||||||
chroma_node.appendChild(node);
|
chroma_node.appendChild(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Hardcode background color to white?
|
|
||||||
// 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");
|
||||||
@ -319,59 +219,22 @@ public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
|||||||
return chroma_node;
|
return chroma_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IIOMetadataNode createPaletteNode() {
|
|
||||||
IIOMetadataNode node = new IIOMetadataNode("Palette");
|
|
||||||
IndexColorModel cm = mColorData.getIndexColorModel();
|
|
||||||
|
|
||||||
for (int i = 0; i < cm.getMapSize(); i++) {
|
|
||||||
IIOMetadataNode entry = new IIOMetadataNode("PaletteEntry");
|
|
||||||
entry.setAttribute("index", Integer.toString(i));
|
|
||||||
entry.setAttribute("red", Integer.toString(cm.getRed(i)));
|
|
||||||
entry.setAttribute("green", Integer.toString(cm.getGreen(i)));
|
|
||||||
entry.setAttribute("blue", Integer.toString(cm.getBlue(i)));
|
|
||||||
|
|
||||||
node.appendChild(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getMultiChannelCS(short pChannels) {
|
|
||||||
if (pChannels < 16) {
|
|
||||||
return Integer.toHexString(pChannels) + "CLR";
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new UnsupportedOperationException("Standard meta data format does not support more than 15 channels");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IIOMetadataNode getStandardCompressionNode() {
|
protected IIOMetadataNode getStandardCompressionNode() {
|
||||||
IIOMetadataNode compression_node = new IIOMetadataNode("Compression");
|
IIOMetadataNode compression_node = new IIOMetadataNode("Compression");
|
||||||
IIOMetadataNode node; // scratch node
|
IIOMetadataNode node; // scratch node
|
||||||
|
|
||||||
node = new IIOMetadataNode("CompressionTypeName");
|
node = new IIOMetadataNode("CompressionTypeName");
|
||||||
String compression;
|
// TODO: Only if set...
|
||||||
switch (mCompression) {
|
node.setAttribute("value", "PackBits");
|
||||||
case PSD.COMPRESSION_NONE:
|
|
||||||
compression = "none";
|
|
||||||
break;
|
|
||||||
case PSD.COMPRESSION_RLE:
|
|
||||||
compression = "packbits";
|
|
||||||
break;
|
|
||||||
case PSD.COMPRESSION_ZIP:
|
|
||||||
case PSD.COMPRESSION_ZIP_PREDICTION:
|
|
||||||
compression = "zip";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new AssertionError("Unreachable");
|
|
||||||
}
|
|
||||||
node.setAttribute("value", compression);
|
|
||||||
compression_node.appendChild(node);
|
compression_node.appendChild(node);
|
||||||
|
|
||||||
node = new IIOMetadataNode("Lossless");
|
node = new IIOMetadataNode("Lossless");
|
||||||
node.setAttribute("value", "true");
|
node.setAttribute("value", "true");
|
||||||
compression_node.appendChild(node);
|
compression_node.appendChild(node);
|
||||||
|
|
||||||
|
// compression_node.appendChild(node);
|
||||||
|
|
||||||
return compression_node;
|
return compression_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,9 +280,9 @@ public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
|||||||
node.setAttribute("value", "Normal");
|
node.setAttribute("value", "Normal");
|
||||||
dimension_node.appendChild(node);
|
dimension_node.appendChild(node);
|
||||||
|
|
||||||
Iterator<PSDResolutionInfo> resolutionInfos = getResources(PSDResolutionInfo.class);
|
List<PSDResolutionInfo> resolutionInfos = getResources(PSDResolutionInfo.class);
|
||||||
if (!resolutionInfos.hasNext()) {
|
if (!resolutionInfos.isEmpty()) {
|
||||||
PSDResolutionInfo resolutionInfo = resolutionInfos.next();
|
PSDResolutionInfo resolutionInfo = resolutionInfos.get(0);
|
||||||
|
|
||||||
node = new IIOMetadataNode("HorizontalPixelSize");
|
node = new IIOMetadataNode("HorizontalPixelSize");
|
||||||
node.setAttribute("value", Float.toString(asMM(resolutionInfo.mHResUnit, resolutionInfo.mHRes)));
|
node.setAttribute("value", Float.toString(asMM(resolutionInfo.mHResUnit, resolutionInfo.mHRes)));
|
||||||
@ -467,49 +330,31 @@ public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IIOMetadataNode getStandardDocumentNode() {
|
protected IIOMetadataNode getStandardDocumentNode() {
|
||||||
IIOMetadataNode document_node = new IIOMetadataNode("Document");
|
// TODO: PSDVersionInfo
|
||||||
IIOMetadataNode node; // scratch node
|
|
||||||
|
|
||||||
node = new IIOMetadataNode("FormatVersion");
|
// if (!tIME_present) {
|
||||||
node.setAttribute("value", "1"); // PSD format version is always 1
|
// return null;
|
||||||
document_node.appendChild(node);
|
// }
|
||||||
|
//
|
||||||
// Get EXIF data if present
|
// IIOMetadataNode document_node = new IIOMetadataNode("Document");
|
||||||
Iterator<PSDEXIF1Data> exif = getResources(PSDEXIF1Data.class);
|
// IIOMetadataNode node = null; // scratch node
|
||||||
if (exif.hasNext()) {
|
//
|
||||||
PSDEXIF1Data data = exif.next();
|
// node = new IIOMetadataNode("ImageModificationTime");
|
||||||
|
// node.setAttribute("year", Integer.toString(tIME_year));
|
||||||
// Get the EXIF DateTime (aka ModifyDate) tag if present
|
// node.setAttribute("month", Integer.toString(tIME_month));
|
||||||
PSDEXIF1Data.Entry dateTime = data.mDirectory.get(0x0132); // TODO: Constant
|
// node.setAttribute("day", Integer.toString(tIME_day));
|
||||||
if (dateTime != null) {
|
// node.setAttribute("hour", Integer.toString(tIME_hour));
|
||||||
node = new IIOMetadataNode("ImageModificationTime");
|
// node.setAttribute("minute", Integer.toString(tIME_minute));
|
||||||
// Format: "YYYY:MM:DD hh:mm:ss" (with quotes! :-P)
|
// node.setAttribute("second", Integer.toString(tIME_second));
|
||||||
String value = dateTime.getValueAsString();
|
// document_node.appendChild(node);
|
||||||
|
//
|
||||||
node.setAttribute("year", value.substring(1, 5));
|
// return document_node;
|
||||||
node.setAttribute("month", value.substring(6, 8));
|
return null;
|
||||||
node.setAttribute("day", value.substring(9, 11));
|
|
||||||
node.setAttribute("hour", value.substring(12, 14));
|
|
||||||
node.setAttribute("minute", value.substring(15, 17));
|
|
||||||
node.setAttribute("second", value.substring(18, 20));
|
|
||||||
|
|
||||||
document_node.appendChild(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return document_node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IIOMetadataNode getStandardTextNode() {
|
protected IIOMetadataNode getStandardTextNode() {
|
||||||
// TODO: CaptionDigest?, EXIF, XMP
|
// TODO: CaptionDigest?, EXIF, XMP
|
||||||
|
|
||||||
Iterator<PSDImageResource> textResources = getResources(PSDEXIF1Data.class, PSDXMPData.class);
|
|
||||||
|
|
||||||
while (textResources.hasNext()) {
|
|
||||||
PSDImageResource textResource = textResources.next();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// int numEntries = tEXt_keyword.size() +
|
// int numEntries = tEXt_keyword.size() +
|
||||||
// iTXt_keyword.size() + zTXt_keyword.size();
|
// iTXt_keyword.size() + zTXt_keyword.size();
|
||||||
@ -566,7 +411,8 @@ public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IIOMetadataNode getStandardTransparencyNode() {
|
protected IIOMetadataNode getStandardTransparencyNode() {
|
||||||
IIOMetadataNode transparency_node = new IIOMetadataNode("Transparency");
|
IIOMetadataNode transparency_node =
|
||||||
|
new IIOMetadataNode("Transparency");
|
||||||
IIOMetadataNode node; // scratch node
|
IIOMetadataNode node; // scratch node
|
||||||
|
|
||||||
node = new IIOMetadataNode("Alpha");
|
node = new IIOMetadataNode("Alpha");
|
||||||
@ -581,31 +427,20 @@ public final class PSDMetadata extends IIOMetadata implements Cloneable {
|
|||||||
mHeader.mMode == PSD.COLOR_MODE_CMYK & mHeader.mChannels >= 5;
|
mHeader.mMode == PSD.COLOR_MODE_CMYK & mHeader.mChannels >= 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
<T extends PSDImageResource> Iterator<T> getResources(final Class<T> pResourceType) {
|
// TODO: Replace with filter iterator?
|
||||||
// NOTE: The cast here is wrong, strictly speaking, but it does not matter...
|
<T extends PSDImageResource> List<T> getResources(final Class<T> pResourceType) {
|
||||||
@SuppressWarnings({"unchecked"})
|
List<T> filtered = null;
|
||||||
Iterator<T> iterator = (Iterator<T>) mImageResources.iterator();
|
|
||||||
|
|
||||||
return new FilterIterator<T>(iterator, new FilterIterator.Filter<T>() {
|
for (PSDImageResource resource : mImageResources) {
|
||||||
public boolean accept(final T pElement) {
|
if (pResourceType.isInstance(resource)) {
|
||||||
return pResourceType.isInstance(pElement);
|
if (filtered == null) {
|
||||||
}
|
filtered = new ArrayList<T>();
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator<PSDImageResource> getResources(final Class<? extends PSDImageResource>... pResourceTypes) {
|
|
||||||
Iterator<PSDImageResource> iterator = mImageResources.iterator();
|
|
||||||
|
|
||||||
return new FilterIterator<PSDImageResource>(iterator, new FilterIterator.Filter<PSDImageResource>() {
|
|
||||||
public boolean accept(final PSDImageResource pElement) {
|
|
||||||
for (Class<?> type : pResourceTypes) {
|
|
||||||
if (type.isInstance(pElement)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
filtered.add(pResourceType.cast(resource));
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.twelvemonkeys.imageio.plugins.psd;
|
package com.twelvemonkeys.imageio.plugins.psd;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
|
|
||||||
import javax.imageio.ImageTypeSpecifier;
|
import javax.imageio.ImageTypeSpecifier;
|
||||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -35,7 +33,7 @@ public final class PSDMetadataFormat extends IIOMetadataFormatImpl {
|
|||||||
addElement("PSDHeader", PSDMetadata.NATIVE_METADATA_FORMAT_NAME, CHILD_POLICY_EMPTY);
|
addElement("PSDHeader", PSDMetadata.NATIVE_METADATA_FORMAT_NAME, CHILD_POLICY_EMPTY);
|
||||||
|
|
||||||
// TODO: Do the first two make sense?
|
// TODO: Do the first two make sense?
|
||||||
// addAttribute("PSDHeader", "signature", DATATYPE_STRING, false, "8BPS", Arrays.asList("8BPS"));
|
addAttribute("PSDHeader", "signature", DATATYPE_STRING, false, "8BPS", Arrays.asList("8BPS"));
|
||||||
addAttribute("PSDHeader", "version", DATATYPE_INTEGER, false, "1", Arrays.asList("1"));
|
addAttribute("PSDHeader", "version", DATATYPE_INTEGER, false, "1", Arrays.asList("1"));
|
||||||
|
|
||||||
addAttribute("PSDHeader", "channels", DATATYPE_INTEGER, true, null, "1", "24", true, true);
|
addAttribute("PSDHeader", "channels", DATATYPE_INTEGER, true, null, "1", "24", true, true);
|
||||||
@ -44,8 +42,16 @@ public final class PSDMetadataFormat extends IIOMetadataFormatImpl {
|
|||||||
// columns?
|
// columns?
|
||||||
addAttribute("PSDHeader", "width", DATATYPE_INTEGER, true, null, "1", "30000", true, true);
|
addAttribute("PSDHeader", "width", DATATYPE_INTEGER, true, null, "1", "30000", true, true);
|
||||||
addAttribute("PSDHeader", "bits", DATATYPE_INTEGER, true, null, Arrays.asList("1", "8", "16"));
|
addAttribute("PSDHeader", "bits", DATATYPE_INTEGER, true, null, Arrays.asList("1", "8", "16"));
|
||||||
// TODO: Consider using more readable names?!
|
addAttribute("PSDHeader", "mode", DATATYPE_INTEGER, true, null, Arrays.asList(
|
||||||
addAttribute("PSDHeader", "mode", DATATYPE_INTEGER, true, null, Arrays.asList(PSDMetadata.COLOR_MODES));
|
String.valueOf(PSD.COLOR_MODE_MONOCHROME),
|
||||||
|
String.valueOf(PSD.COLOR_MODE_GRAYSCALE),
|
||||||
|
String.valueOf(PSD.COLOR_MODE_INDEXED),
|
||||||
|
String.valueOf(PSD.COLOR_MODE_RGB),
|
||||||
|
String.valueOf(PSD.COLOR_MODE_CMYK),
|
||||||
|
String.valueOf(PSD.COLOR_MODE_MULTICHANNEL),
|
||||||
|
String.valueOf(PSD.COLOR_MODE_DUOTONE),
|
||||||
|
String.valueOf(PSD.COLOR_MODE_LAB)
|
||||||
|
));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Contains the required data to define the color mode.
|
Contains the required data to define the color mode.
|
||||||
@ -63,7 +69,7 @@ public final class PSDMetadataFormat extends IIOMetadataFormatImpl {
|
|||||||
// NOTE: Palette, PaletteEntry naming taken from the standard format, native PSD naming is ColorModeData
|
// NOTE: Palette, PaletteEntry naming taken from the standard format, native PSD naming is ColorModeData
|
||||||
// NOTE: PSD stores these as 256 Red, 256 Green, 256 Blue.. Should we do the same in the meta data?
|
// NOTE: PSD stores these as 256 Red, 256 Green, 256 Blue.. Should we do the same in the meta data?
|
||||||
addElement("Palette", PSDMetadata.NATIVE_METADATA_FORMAT_NAME, 256, 256); // 768 = 256 * 3
|
addElement("Palette", PSDMetadata.NATIVE_METADATA_FORMAT_NAME, 256, 256); // 768 = 256 * 3
|
||||||
addElement("PaletteEntry", "Palette", CHILD_POLICY_EMPTY);
|
addElement("PaletteEntry", "PSDColorData", CHILD_POLICY_EMPTY);
|
||||||
addAttribute("PaletteEntry", "index", DATATYPE_INTEGER, true, null, "0", "255", true, true);
|
addAttribute("PaletteEntry", "index", DATATYPE_INTEGER, true, null, "0", "255", true, true);
|
||||||
addAttribute("PaletteEntry", "red", DATATYPE_INTEGER, true, null, "0", "255", true, true);
|
addAttribute("PaletteEntry", "red", DATATYPE_INTEGER, true, null, "0", "255", true, true);
|
||||||
addAttribute("PaletteEntry", "green", DATATYPE_INTEGER, true, null, "0", "255", true, true);
|
addAttribute("PaletteEntry", "green", DATATYPE_INTEGER, true, null, "0", "255", true, true);
|
||||||
@ -83,19 +89,15 @@ public final class PSDMetadataFormat extends IIOMetadataFormatImpl {
|
|||||||
// TODO: Allow arbitrary values to be added as a generic resource...
|
// TODO: Allow arbitrary values to be added as a generic resource...
|
||||||
|
|
||||||
// root -> ImageResources -> AlphaChannelInfo
|
// root -> ImageResources -> AlphaChannelInfo
|
||||||
addElement("AlphaChannelInfo", "ImageResources", 0, Integer.MAX_VALUE); // The format probably does not support that many layers..
|
addElement("AlphaChannelInfo", "ImageResources", CHILD_POLICY_EMPTY);
|
||||||
addElement("Name", "AlphaChannelInfo", CHILD_POLICY_EMPTY);
|
addAttribute("AlphaChannelInfo", "names", DATATYPE_STRING, true, 0, Integer.MAX_VALUE);
|
||||||
addAttribute("Name", "value", DATATYPE_STRING, true, 0, Integer.MAX_VALUE);
|
|
||||||
|
|
||||||
// root -> ImageResources -> DisplayInfo
|
// root -> ImageResources -> DisplayInfo
|
||||||
addElement("DisplayInfo", "ImageResources", CHILD_POLICY_EMPTY);
|
addElement("DisplayInfo", "ImageResources", CHILD_POLICY_EMPTY);
|
||||||
// TODO: Consider using human readable strings
|
|
||||||
// TODO: Limit values (0-8, 10, 11, 3000)
|
|
||||||
addAttribute("DisplayInfo", "colorSpace", DATATYPE_INTEGER, true, null);
|
addAttribute("DisplayInfo", "colorSpace", DATATYPE_INTEGER, true, null);
|
||||||
addAttribute("DisplayInfo", "colors", DATATYPE_INTEGER, true, 4, 4);
|
addAttribute("DisplayInfo", "colors", DATATYPE_INTEGER, true, 4, 4);
|
||||||
addAttribute("DisplayInfo", "opacity", DATATYPE_INTEGER, true, null, "0", "100", true, true);
|
addAttribute("DisplayInfo", "opacity", DATATYPE_INTEGER, true, null, "0", "100", true, true);
|
||||||
// TODO: Consider using human readable strings
|
addAttribute("DisplayInfo", "kind", DATATYPE_INTEGER, true, null, Arrays.asList("0", "1"));
|
||||||
addAttribute("DisplayInfo", "kind", DATATYPE_INTEGER, true, null, Arrays.asList(PSDMetadata.DISPLAY_INFO_KINDS));
|
|
||||||
|
|
||||||
// root -> ImageResources -> EXIF1Data
|
// root -> ImageResources -> EXIF1Data
|
||||||
addElement("EXIF1Data", "ImageResources", CHILD_POLICY_ALL);
|
addElement("EXIF1Data", "ImageResources", CHILD_POLICY_ALL);
|
||||||
@ -136,7 +138,6 @@ public final class PSDMetadataFormat extends IIOMetadataFormatImpl {
|
|||||||
// root -> ImageResources -> XMPData
|
// root -> ImageResources -> XMPData
|
||||||
addElement("XMPData", "ImageResources", CHILD_POLICY_CHOICE);
|
addElement("XMPData", "ImageResources", CHILD_POLICY_CHOICE);
|
||||||
// TODO: Incorporate XMP metadata here somehow (or treat as opaque bytes?)
|
// TODO: Incorporate XMP metadata here somehow (or treat as opaque bytes?)
|
||||||
addObjectValue("XMPData", Document.class, true, null);
|
|
||||||
|
|
||||||
// TODO: Layers
|
// TODO: Layers
|
||||||
//addElement("ChannelSourceDestinationRange", "LayerSomething", CHILD_POLICY_CHOICE);
|
//addElement("ChannelSourceDestinationRange", "LayerSomething", CHILD_POLICY_CHOICE);
|
||||||
|
@ -26,14 +26,14 @@ final class PSDPrintFlags extends PSDImageResource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readData(final ImageInputStream pInput) throws IOException {
|
protected void readData(final ImageInputStream pInput) throws IOException {
|
||||||
mLabels = pInput.readBoolean();
|
mLabels = pInput.readUnsignedByte() != 0;
|
||||||
mCropMasks = pInput.readBoolean();
|
mCropMasks = pInput.readUnsignedByte() != 0;
|
||||||
mColorBars = pInput.readBoolean();
|
mColorBars = pInput.readUnsignedByte() != 0;
|
||||||
mRegistrationMarks = pInput.readBoolean();
|
mRegistrationMarks = pInput.readUnsignedByte() != 0;
|
||||||
mNegative = pInput.readBoolean();
|
mNegative = pInput.readUnsignedByte() != 0;
|
||||||
mFlip = pInput.readBoolean();
|
mFlip = pInput.readUnsignedByte() != 0;
|
||||||
mInterpolate = pInput.readBoolean();
|
mInterpolate = pInput.readUnsignedByte() != 0;
|
||||||
mCaption = pInput.readBoolean();
|
mCaption = pInput.readUnsignedByte() != 0;
|
||||||
|
|
||||||
pInput.skipBytes(mSize - 8);
|
pInput.skipBytes(mSize - 8);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ final class PSDPrintFlagsInformation extends PSDImageResource {
|
|||||||
@Override
|
@Override
|
||||||
protected void readData(final ImageInputStream pInput) throws IOException {
|
protected void readData(final ImageInputStream pInput) throws IOException {
|
||||||
mVersion = pInput.readUnsignedShort();
|
mVersion = pInput.readUnsignedShort();
|
||||||
mCropMasks = pInput.readBoolean();
|
mCropMasks = pInput.readUnsignedByte() != 0;
|
||||||
mField = pInput.readUnsignedByte();
|
mField = pInput.readUnsignedByte();
|
||||||
mBleedWidth = pInput.readUnsignedInt();
|
mBleedWidth = pInput.readUnsignedInt();
|
||||||
mBleedScale = pInput.readUnsignedShort();
|
mBleedScale = pInput.readUnsignedShort();
|
||||||
|
@ -37,7 +37,7 @@ class PSDThumbnail extends PSDImageResource {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void readData(final ImageInputStream pInput) throws IOException {
|
protected void readData(final ImageInputStream pInput) throws IOException {
|
||||||
// TODO: Support for RAW RGB (format == 0): Extract RAW reader from PICT RAW QuickTime decompressor
|
// TODO: Support for RAW RGB (format == 0)
|
||||||
int format = pInput.readInt();
|
int format = pInput.readInt();
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -31,10 +31,8 @@ package com.twelvemonkeys.imageio.plugins.psd;
|
|||||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||||
import com.twelvemonkeys.io.enc.DecoderStream;
|
import com.twelvemonkeys.io.enc.DecoderStream;
|
||||||
import com.twelvemonkeys.io.enc.PackBitsDecoder;
|
import com.twelvemonkeys.io.enc.PackBitsDecoder;
|
||||||
import com.twelvemonkeys.lang.StringUtil;
|
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
@ -59,22 +57,23 @@ final class PSDUtil {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Proably also useful for PICT reader, move to some common util?
|
// TODO: Proably also useful for PICT reader, move to some common util?
|
||||||
// TODO: Is this REALLY different from the previous method? Maybe the pad should not be read..
|
static String readPascalString(ImageInputStream pInput) throws IOException {
|
||||||
static String readPascalString(final DataInput pInput) throws IOException {
|
int length = pInput.readUnsignedByte();
|
||||||
|
// int length = pInput.readUnsignedShort();
|
||||||
|
byte[] bytes = new byte[length];
|
||||||
|
pInput.readFully(bytes);
|
||||||
|
if (length % 2 == 0) {
|
||||||
|
pInput.readByte(); // Pad
|
||||||
|
}
|
||||||
|
return new String(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String readPascalStringByte(ImageInputStream pInput) throws IOException {
|
||||||
int length = pInput.readUnsignedByte();
|
int length = pInput.readUnsignedByte();
|
||||||
byte[] bytes = new byte[length];
|
byte[] bytes = new byte[length];
|
||||||
pInput.readFully(bytes);
|
pInput.readFully(bytes);
|
||||||
|
return new String(bytes);
|
||||||
return StringUtil.decode(bytes, 0, bytes.length, "ASCII");
|
|
||||||
}
|
|
||||||
|
|
||||||
static String readUTF16String(final DataInput pInput) throws IOException {
|
|
||||||
int length = pInput.readInt();
|
|
||||||
byte[] bytes = new byte[length * 2];
|
|
||||||
pInput.readFully(bytes);
|
|
||||||
|
|
||||||
return StringUtil.decode(bytes, 0, bytes.length, "UTF-16");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DataInputStream createPackBitsStream(final ImageInputStream pInput, long pLength) {
|
static DataInputStream createPackBitsStream(final ImageInputStream pInput, long pLength) {
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
package com.twelvemonkeys.imageio.plugins.psd;
|
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PSDVersionInfo
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
|
||||||
* @author last modified by $Author: haraldk$
|
|
||||||
* @version $Id: PSDVersionInfo.java,v 1.0 Nov 6, 2009 1:02:19 PM haraldk Exp$
|
|
||||||
*/
|
|
||||||
final class PSDVersionInfo extends PSDImageResource {
|
|
||||||
|
|
||||||
int mVersion;
|
|
||||||
boolean mHasRealMergedData;
|
|
||||||
String mWriter;
|
|
||||||
String mReader;
|
|
||||||
int mFileVersion;
|
|
||||||
|
|
||||||
PSDVersionInfo(final short pId, final ImageInputStream pInput) throws IOException {
|
|
||||||
super(pId, pInput);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void readData(final ImageInputStream pInput) throws IOException {
|
|
||||||
/*
|
|
||||||
4 bytes version
|
|
||||||
1 byte hasRealMergedData
|
|
||||||
Unicode string: writer name
|
|
||||||
Unicode string: reader name
|
|
||||||
4 bytes file version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
mVersion = pInput.readInt();
|
|
||||||
mHasRealMergedData = pInput.readBoolean();
|
|
||||||
|
|
||||||
mWriter = PSDUtil.readUTF16String(pInput);
|
|
||||||
mReader = PSDUtil.readUTF16String(pInput);
|
|
||||||
|
|
||||||
mFileVersion = pInput.readInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder builder = toStringBuilder();
|
|
||||||
|
|
||||||
builder.append(", version: ").append(mVersion);
|
|
||||||
builder.append(", hasRealMergedData: ").append(mHasRealMergedData);
|
|
||||||
builder.append(", writer: ").append(mWriter);
|
|
||||||
builder.append(", reader: ").append(mReader);
|
|
||||||
builder.append(", file version: ").append(mFileVersion);
|
|
||||||
builder.append("]");
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user