From 27553dc47af2e646104654abd26c6887191f3f3e Mon Sep 17 00:00:00 2001 From: Erlend Hamnaberg Date: Wed, 11 Nov 2009 21:47:31 +0100 Subject: [PATCH] Revert "Work in progress for PSD metadata support:" This reverts commit b5f6c96583a486896b5532a5785d488d56762d4b. --- .../util/ImageReaderAbstractTestCase.java | 27 +- .../imageio/plugins/psd/PSDColorData.java | 4 +- .../imageio/plugins/psd/PSDDisplayInfo.java | 20 +- .../imageio/plugins/psd/PSDEXIF1Data.java | 2 +- .../imageio/plugins/psd/PSDImageReader.java | 107 +---- .../plugins/psd/PSDImageReaderSpi.java | 8 +- .../imageio/plugins/psd/PSDMetadata.java | 446 ------------------ .../plugins/psd/PSDMetadataFormat.java | 165 ------- .../plugins/psd/PSDResolutionInfo.java | 13 +- 9 files changed, 44 insertions(+), 748 deletions(-) delete mode 100644 twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadata.java delete mode 100644 twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadataFormat.java diff --git a/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java b/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java index 601ff974..11be9e0d 100644 --- a/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java +++ b/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/util/ImageReaderAbstractTestCase.java @@ -36,7 +36,6 @@ import org.jmock.core.Stub; import javax.imageio.*; import javax.imageio.event.IIOReadProgressListener; -import javax.imageio.metadata.IIOMetadata; import javax.imageio.spi.IIORegistry; import javax.imageio.spi.ImageReaderSpi; import javax.imageio.stream.ImageInputStream; @@ -1321,9 +1320,7 @@ public abstract class ImageReaderAbstractTestCase extends assertEquals(type.getColorModel(), result.getColorModel()); - // The following logically tests - // assertEquals(type.getSampleModel(), result.getSampleModel()); - // but SampleModel does not have a proper equals method. +// assertEquals(type.getSampleModel(), result.getSampleModel()); SampleModel expectedModel = type.getSampleModel(); SampleModel resultModel = result.getSampleModel(); @@ -1338,6 +1335,10 @@ public abstract class ImageReaderAbstractTestCase extends } } +// public void testSetDestinationTypeIllegal() throws IOException { +// throw new UnsupportedOperationException("Method testSetDestinationTypeIllegal not implemented"); // TODO: Implement +// } +// // public void testSetDestinationBands() throws IOException { // throw new UnsupportedOperationException("Method testSetDestinationBands not implemented"); // TODO: Implement // } @@ -1346,24 +1347,6 @@ public abstract class ImageReaderAbstractTestCase extends // throw new UnsupportedOperationException("Method testSetDestinationBands not implemented"); // TODO: Implement // } - public void testProviderAndMetadataFormatNamesMatch() throws IOException { - ImageReaderSpi provider = createProvider(); - - ImageReader reader = createReader(); - reader.setInput(getTestData().get(0).getInputStream()); - - IIOMetadata imageMetadata = reader.getImageMetadata(0); - if (imageMetadata != null) { - assertEquals(provider.getNativeImageMetadataFormatName(), imageMetadata.getNativeMetadataFormatName()); - } - - IIOMetadata streamMetadata = reader.getStreamMetadata(); - if (streamMetadata != null) { - assertEquals(provider.getNativeStreamMetadataFormatName(), streamMetadata.getNativeMetadataFormatName()); - } - } - - protected URL getClassLoaderResource(final String pName) { return getClass().getResource(pName); } diff --git a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDColorData.java b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDColorData.java index d8e67cde..2d64c5a8 100644 --- a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDColorData.java +++ b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDColorData.java @@ -47,7 +47,7 @@ class PSDColorData { final byte[] mColors; private IndexColorModel mColorModel; - PSDColorData(final ImageInputStream pInput) throws IOException { + PSDColorData(ImageInputStream pInput) throws IOException { int length = pInput.readInt(); if (length == 0) { throw new IIOException("No palette information in PSD"); @@ -72,7 +72,7 @@ class PSDColorData { return mColorModel; } - private static int[] toInterleavedRGB(final byte[] pColors) { + private int[] toInterleavedRGB(byte[] pColors) { int[] rgb = new int[pColors.length / 3]; for (int i = 0; i < rgb.length; i++) { diff --git a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDDisplayInfo.java b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDDisplayInfo.java index d4d41347..6b04cf12 100755 --- a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDDisplayInfo.java +++ b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDDisplayInfo.java @@ -40,7 +40,7 @@ import java.io.IOException; * @version $Id: PSDResolutionInfo.java,v 1.0 May 2, 2008 3:58:19 PM haraldk Exp$ */ 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... //typedef _DisplayInfo //{ // WORD ColorSpace; @@ -67,20 +67,20 @@ class PSDDisplayInfo extends PSDImageResource { // long left = mSize; // while (left > 0) { - mColorSpace = pInput.readShort(); + mColorSpace = pInput.readShort(); - // Color[4]...? + // Color[4]...? mColors = new short[4]; - mColors[0] = pInput.readShort(); - mColors[1] = pInput.readShort(); - mColors[2] = pInput.readShort(); - mColors[3] = pInput.readShort(); + mColors[0] = pInput.readShort(); + mColors[1] = pInput.readShort(); + mColors[2] = pInput.readShort(); + mColors[3] = pInput.readShort(); - mOpacity = pInput.readShort(); + mOpacity = pInput.readShort(); - mKind = pInput.readByte(); + mKind = pInput.readByte(); - pInput.readByte(); // Pad + pInput.readByte(); // Pad // left -= 14; // } pInput.skipBytes(mSize - 14); diff --git a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDEXIF1Data.java b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDEXIF1Data.java index a2f6f486..a54bb6a8 100644 --- a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDEXIF1Data.java +++ b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDEXIF1Data.java @@ -35,7 +35,7 @@ final class PSDEXIF1Data extends PSDImageResource { protected void readData(final ImageInputStream pInput) throws IOException { // This is in essence an embedded TIFF file. // TODO: Extract TIFF parsing to more general purpose package - // TODO: Instead, read the byte data, store for later parsing (or store offset, and read on request) + // TODO: Instead, read the byte data, store for later parsing MemoryCacheImageInputStream stream = new MemoryCacheImageInputStream(IIOUtil.createStreamAdapter(pInput, mSize)); byte[] bom = new byte[2]; diff --git a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReader.java b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReader.java index d2f05792..52680c9c 100644 --- a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReader.java +++ b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReader.java @@ -31,15 +31,8 @@ package com.twelvemonkeys.imageio.plugins.psd; import com.twelvemonkeys.image.ImageUtil; import com.twelvemonkeys.imageio.ImageReaderBase; import com.twelvemonkeys.imageio.util.IndexedImageTypeSpecifier; -import com.twelvemonkeys.xml.XMLSerializer; -import org.w3c.dom.Node; -import javax.imageio.IIOException; -import javax.imageio.ImageIO; -import javax.imageio.ImageReadParam; -import javax.imageio.ImageTypeSpecifier; -import javax.imageio.metadata.IIOMetadata; -import javax.imageio.metadata.IIOMetadataFormatImpl; +import javax.imageio.*; import javax.imageio.spi.ImageReaderSpi; import javax.imageio.stream.ImageInputStream; import java.awt.*; @@ -50,11 +43,13 @@ import java.awt.image.*; import java.io.DataInputStream; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; import java.util.List; /** - * ImageReader for Adobe Photoshop Document (PSD) format. + * ImageReader for Adobe Photoshop Document format. * * @see Adobe Photoshop File Format Summary * @author Harald Kuhr @@ -62,7 +57,7 @@ import java.util.List; * @version $Id: PSDImageReader.java,v 1.0 Apr 29, 2008 4:45:52 PM haraldk Exp$ */ // TODO: Implement ImageIO meta data interface -// TODO: API for reading separate layers +// TODO: Allow reading separate (or some?) layers // TODO: Consider Romain Guy's Java 2D implementation of PS filters for the blending modes in layers // http://www.curious-creature.org/2006/09/20/new-blendings-modes-for-java2d/ // See http://www.codeproject.com/KB/graphics/PSDParser.aspx @@ -120,7 +115,7 @@ public class PSDImageReader extends ImageReaderBase { ); case PSD.COLOR_MODE_INDEXED: - // TODO: 16 bit indexed?! Does it exist? + // TODO: 16 bit indexed?! if (mHeader.mChannels == 1 && mHeader.mBits == 8) { return IndexedImageTypeSpecifier.createFromIndexColorModel(mColorData.getIndexColorModel()); } @@ -189,11 +184,6 @@ public class PSDImageReader extends ImageReaderBase { throw new IIOException( String.format("Unsupported channel count/bit depth for CMYK PSD: %d channels/%d bits", mHeader.mChannels, mHeader.mBits) ); - - case PSD.COLOR_MODE_MULTICHANNEL: - // TODO: Implement - case PSD.COLOR_MODE_LAB: - // TODO: Implement default: throw new IIOException( String.format("Unsupported PSD MODE: %s (%d channels/%d bits)", mHeader.mMode, mHeader.mChannels, mHeader.mBits) @@ -414,7 +404,7 @@ public class PSDImageReader extends ImageReaderBase { read16bitChannel(c, mHeader.mChannels, data16, interleavedBands, bandOffset, pSourceCM, row16, pSource, pDest, pXSub, pYSub, mHeader.mWidth, mHeader.mHeight, pByteCounts, c * mHeader.mHeight, pCompression == PSD.COMPRESSION_RLE); break; default: - throw new IIOException(String.format("Unknown PSD bit depth: %s", mHeader.mBits)); + throw new IIOException("Unknown PSD bit depth: " + mHeader.mBits); } if (abortRequested()) { @@ -546,7 +536,6 @@ public class PSDImageReader extends ImageReaderBase { } } - @SuppressWarnings({"UnusedDeclaration"}) private void read1bitChannel(final int pChannel, final int pChannelCount, final byte[] pData, final int pBands, final int pBandOffset, final ColorModel pSourceColorModel, @@ -708,7 +697,6 @@ public class PSDImageReader extends ImageReaderBase { mColorData = new PSDColorData(mImageInput); } else { - // TODO: We need to store the duotone spec if we decide to create a writer... // Skip color mode data for other modes long length = mImageInput.readUnsignedInt(); mImageInput.skipBytes(length); @@ -720,7 +708,6 @@ public class PSDImageReader extends ImageReaderBase { } // TODO: Flags or list of interesting resources to parse - // TODO: Obey ignoreMetadata private void readImageResources(final boolean pParseData) throws IOException { // TODO: Avoid unnecessary stream repositioning long pos = mImageInput.getFlushedPosition(); @@ -748,8 +735,6 @@ public class PSDImageReader extends ImageReaderBase { mImageInput.seek(pos + length + 4); } - // TODO: Flags or list of interesting resources to parse - // TODO: Obey ignoreMetadata private void readLayerAndMaskInfo(final boolean pParseData) throws IOException { // TODO: Make sure we are positioned correctly long length = mImageInput.readUnsignedInt(); @@ -782,7 +767,7 @@ public class PSDImageReader extends ImageReaderBase { // TODO: If not explicitly needed, skip layers... BufferedImage layer = readLayerData(layerInfo, raw, imageType); - // TODO: Don't show! Store in meta data somehow... + // TODO: Don't show! Store in metadata somehow... if (layer != null) { showIt(layer, layerInfo.mLayerName + " " + layerInfo.mBlendMode.toString()); } @@ -810,7 +795,6 @@ public class PSDImageReader extends ImageReaderBase { mImageInput.skipBytes(toSkip); } else { - // Skip entire layer and mask section mImageInput.skipBytes(length); } } @@ -854,7 +838,7 @@ public class PSDImageReader extends ImageReaderBase { } else { // 0 = red, 1 = green, etc - // -1 = transparency mask; -2 = user supplied layer mask + // ?1 = transparency mask; ?2 = user supplied layer mask int c = channelInfo.mChannelId == -1 ? pLayerInfo.mChannelInfo.length - 1 : channelInfo.mChannelId; // NOTE: For layers, byte counts are written per channel, while for the composite data @@ -908,7 +892,7 @@ public class PSDImageReader extends ImageReaderBase { read16bitChannel(c, imageType.getNumBands(), data16, interleavedBands, bandOffset, sourceCM, row16, area, area, xsub, ysub, width, height, byteCounts, 0, compression == PSD.COMPRESSION_RLE); break; default: - throw new IIOException(String.format("Unknown PSD bit depth: %s", mHeader.mBits)); + throw new IIOException("Unknown PSD bit depth: " + mHeader.mBits); } if (abortRequested()) { @@ -947,57 +931,6 @@ public class PSDImageReader extends ImageReaderBase { return pOriginal; } - /// Layer support - // TODO: For now, leave as Metadata - - /* - int getNumLayers(int pImageIndex) throws IOException; - - boolean hasLayers(int pImageIndex) throws IOException; - - BufferedImage readLayer(int pImageIndex, int pLayerIndex, ImageReadParam pParam) throws IOException; - - int getLayerWidth(int pImageIndex, int pLayerIndex) throws IOException; - - int getLayerHeight(int pImageIndex, int pLayerIndex) throws IOException; - - // ? - Point getLayerOffset(int pImageIndex, int pLayerIndex) throws IOException; - - */ - - /// Metadata support - // TODO - - @Override - public IIOMetadata getStreamMetadata() throws IOException { - // null might be appropriate here - // "For image formats that contain a single image, only image metadata is used." - return super.getStreamMetadata(); - } - - @Override - public IIOMetadata getImageMetadata(final int pImageIndex) throws IOException { - // TODO: Implement - checkBounds(pImageIndex); - - readHeader(); - readImageResources(true); - readLayerAndMaskInfo(true); - - PSDMetadata metadata = new PSDMetadata(); - metadata.mHeader = mHeader; - metadata.mColorData = mColorData; - metadata.mImageResources = mImageResources; - return metadata; - } - - @Override - public IIOMetadata getImageMetadata(final int imageIndex, final String formatName, final Set nodeNames) throws IOException { - // TODO: This might make sense, as there's loads of meta data in the file - return super.getImageMetadata(imageIndex, formatName, nodeNames); - } - /// Thumbnail support @Override public boolean readerSupportsThumbnails() { @@ -1032,13 +965,13 @@ public class PSDImageReader extends ImageReaderBase { } @Override - public int getNumThumbnails(final int pIndex) throws IOException { + public int getNumThumbnails(int pIndex) throws IOException { List thumbnails = getThumbnailResources(pIndex); return thumbnails == null ? 0 : thumbnails.size(); } - private PSDThumbnail getThumbnailResource(final int pImageIndex, final int pThumbnailIndex) throws IOException { + private PSDThumbnail getThumbnailResource(int pImageIndex, int pThumbnailIndex) throws IOException { List thumbnails = getThumbnailResources(pImageIndex); if (thumbnails == null) { @@ -1049,17 +982,17 @@ public class PSDImageReader extends ImageReaderBase { } @Override - public int getThumbnailWidth(final int pImageIndex, final int pThumbnailIndex) throws IOException { + public int getThumbnailWidth(int pImageIndex, int pThumbnailIndex) throws IOException { return getThumbnailResource(pImageIndex, pThumbnailIndex).getWidth(); } @Override - public int getThumbnailHeight(final int pImageIndex, final int pThumbnailIndex) throws IOException { + public int getThumbnailHeight(int pImageIndex, int pThumbnailIndex) throws IOException { return getThumbnailResource(pImageIndex, pThumbnailIndex).getHeight(); } @Override - public BufferedImage readThumbnail(final int pImageIndex, final int pThumbnailIndex) throws IOException { + public BufferedImage readThumbnail(int pImageIndex, int pThumbnailIndex) throws IOException { // TODO: Thumbnail progress listeners... PSDThumbnail thumbnail = getThumbnailResource(pImageIndex, pThumbnailIndex); @@ -1068,7 +1001,6 @@ public class PSDImageReader extends ImageReaderBase { processThumbnailStarted(pImageIndex, pThumbnailIndex); processThumbnailComplete(); - // TODO: Returning a cached mutable thumbnail is not really safe... return thumbnail.getThumbnail(); } @@ -1120,17 +1052,12 @@ public class PSDImageReader extends ImageReaderBase { // System.out.println("imageReader.mHeader: " + imageReader.mHeader); imageReader.readImageResources(true); - System.out.println("imageReader.mImageResources: " + imageReader.mImageResources); +// System.out.println("imageReader.mImageResources: " + imageReader.mImageResources); imageReader.readLayerAndMaskInfo(true); System.out.println("imageReader.mLayerInfo: " + imageReader.mLayerInfo); // System.out.println("imageReader.mGlobalLayerMask: " + imageReader.mGlobalLayerMask); - IIOMetadata metadata = imageReader.getImageMetadata(0); - Node node = metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName); - XMLSerializer serializer = new XMLSerializer(System.out, System.getProperty("file.encoding")); - serializer.serialize(node, true); - if (imageReader.hasThumbnails(0)) { int thumbnails = imageReader.getNumThumbnails(0); for (int i = 0; i < thumbnails; i++) { diff --git a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderSpi.java b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderSpi.java index 0b63af8d..5a27b1c5 100755 --- a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderSpi.java +++ b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDImageReaderSpi.java @@ -67,12 +67,8 @@ public class PSDImageReaderSpi extends ImageReaderSpi { STANDARD_INPUT_TYPE, // new String[]{"com.twelvemkonkeys.imageio.plugins.psd.PSDImageWriterSpi"}, null, - true, // supports standard stream metadata - null, null, // native stream format name and class - null, null, // extra stream formats - true, // supports standard image metadata - PSDMetadata.NATIVE_METADATA_FORMAT_NAME, PSDMetadata.NATIVE_METADATA_FORMAT_CLASS_NAME, - null, null // extra image metadata formats + true, null, null, null, null, + true, null, null, null, null ); } diff --git a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadata.java b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadata.java deleted file mode 100644 index a9755fad..00000000 --- a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadata.java +++ /dev/null @@ -1,446 +0,0 @@ -package com.twelvemonkeys.imageio.plugins.psd; - -import com.twelvemonkeys.lang.StringUtil; -import org.w3c.dom.Node; - -import javax.imageio.metadata.IIOInvalidTreeException; -import javax.imageio.metadata.IIOMetadata; -import javax.imageio.metadata.IIOMetadataFormatImpl; -import javax.imageio.metadata.IIOMetadataNode; -import java.awt.image.IndexColorModel; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * PSDMetadata - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: PSDMetadata.java,v 1.0 Nov 4, 2009 5:28:12 PM haraldk Exp$ - */ -public final class PSDMetadata extends IIOMetadata implements Cloneable { - - static final String NATIVE_METADATA_FORMAT_NAME = "com_twelvemonkeys_imageio_psd_1.0"; - 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; - PSDColorData mColorData; - List mImageResources; - PSDGlobalLayerMask mGlobalLayerMask; - List mLayerInfo; - - protected PSDMetadata() { - // TODO: Allow XMP, EXIF and IPTC as extra formats? - super(true, NATIVE_METADATA_FORMAT_NAME, NATIVE_METADATA_FORMAT_CLASS_NAME, null, null); - } - - @Override - public boolean isReadOnly() { - // TODO: Extract to abstract metadata impl class? - return true; - } - - @Override - public Node getAsTree(final String pFormatName) { - validateFormatName(pFormatName); - - if (pFormatName.equals(nativeMetadataFormatName)) { - return getNativeTree(); - } - else if (pFormatName.equals(IIOMetadataFormatImpl.standardMetadataFormatName)) { - return getStandardTree(); - } - - throw new AssertionError("Unreachable"); - } - - @Override - public void mergeTree(final String pFormatName, final Node pRoot) throws IIOInvalidTreeException { - // TODO: Extract to abstract metadata impl class? - assertMutable(); - - validateFormatName(pFormatName); - - if (!pRoot.getNodeName().equals(nativeMetadataFormatName)) { - throw new IIOInvalidTreeException("Root must be " + nativeMetadataFormatName, pRoot); - } - - Node node = pRoot.getFirstChild(); - while (node != null) { - // TODO: Merge values from node into this - - // Move to the next sibling - node = node.getNextSibling(); - } - } - - @Override - public void reset() { - // TODO: Extract to abstract metadata impl class? - assertMutable(); - - throw new UnsupportedOperationException("Method reset not implemented"); // TODO: Implement - } - - // TODO: Extract to abstract metadata impl class? - private void assertMutable() { - if (isReadOnly()) { - throw new IllegalStateException("Metadata is read-only"); - } - } - - // TODO: Extract to abstract metadata impl class? - private void validateFormatName(final String pFormatName) { - String[] metadataFormatNames = getMetadataFormatNames(); - - if (metadataFormatNames != null) { - for (String metadataFormatName : metadataFormatNames) { - if (metadataFormatName.equals(pFormatName)) { - return; // Found, we're ok! - } - } - } - - throw new IllegalArgumentException( - String.format("Bad format name: \"%s\". Expected one of %s", pFormatName, Arrays.toString(metadataFormatNames)) - ); - } - - @Override - public Object clone() { - // TODO: Make it a deep clone - try { - return super.clone(); - } - catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - - private Node getNativeTree() { - throw new UnsupportedOperationException("getNativeTree"); - } - - /// Standard format support - - @Override - protected IIOMetadataNode getStandardChromaNode() { - IIOMetadataNode chroma_node = new IIOMetadataNode("Chroma"); - IIOMetadataNode node; // scratch node - - node = new IIOMetadataNode("ColorSpaceType"); - String cs; - switch (mHeader.mMode) { - case PSD.COLOR_MODE_MONOCHROME: - case PSD.COLOR_MODE_GRAYSCALE: - case PSD.COLOR_MODE_DUOTONE: // Rationale is spec says treat as gray... - cs = "GRAY"; - break; - case PSD.COLOR_MODE_RGB: - case PSD.COLOR_MODE_INDEXED: - cs = "RGB"; - break; - case PSD.COLOR_MODE_CMYK: - cs = "CMYK"; - break; - case PSD.COLOR_MODE_MULTICHANNEL: - // TODO: FixMe - cs = "???"; - break; - case PSD.COLOR_MODE_LAB: - cs = "Lab"; - break; - default: - throw new AssertionError("Unreachable"); - } - node.setAttribute("name", cs); - chroma_node.appendChild(node); - - // TODO: Channels might be 5 for RGB + A + Mask... - node = new IIOMetadataNode("NumChannels"); - node.setAttribute("value", Integer.toString(mHeader.mChannels)); - 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) - node = new IIOMetadataNode("BlackIsZero"); - node.setAttribute("value", "true"); - chroma_node.appendChild(node); - - if (mHeader.mMode == PSD.COLOR_MODE_INDEXED) { - 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); - } - -// if (bKGD_present) { -// if (bKGD_colorType == PNGImageReader.PNG_COLOR_PALETTE) { -// node = new IIOMetadataNode("BackgroundIndex"); -// node.setAttribute("value", Integer.toString(bKGD_index)); -// } else { -// node = new IIOMetadataNode("BackgroundColor"); -// int r, g, b; -// -// if (bKGD_colorType == PNGImageReader.PNG_COLOR_GRAY) { -// r = g = b = bKGD_gray; -// } else { -// r = bKGD_red; -// g = bKGD_green; -// b = bKGD_blue; -// } -// node.setAttribute("red", Integer.toString(r)); -// node.setAttribute("green", Integer.toString(g)); -// node.setAttribute("blue", Integer.toString(b)); -// } -// chroma_node.appendChild(node); -// } - - return chroma_node; - } - - @Override - protected IIOMetadataNode getStandardCompressionNode() { - IIOMetadataNode compression_node = new IIOMetadataNode("Compression"); - IIOMetadataNode node; // scratch node - - node = new IIOMetadataNode("CompressionTypeName"); - // TODO: Only if set... - node.setAttribute("value", "PackBits"); - compression_node.appendChild(node); - - node = new IIOMetadataNode("Lossless"); - node.setAttribute("value", "true"); - compression_node.appendChild(node); - -// compression_node.appendChild(node); - - return compression_node; - } - - @Override - protected IIOMetadataNode getStandardDataNode() { - IIOMetadataNode data_node = new IIOMetadataNode("Data"); - IIOMetadataNode node; // scratch node - - node = new IIOMetadataNode("PlanarConfiguration"); - node.setAttribute("value", "PlaneInterleaved"); // TODO: Check with spec - data_node.appendChild(node); - - node = new IIOMetadataNode("SampleFormat"); - node.setAttribute("value", mHeader.mMode == PSD.COLOR_MODE_INDEXED ? "Index" : "UnsignedIntegral"); - data_node.appendChild(node); - - String bitDepth = Integer.toString(mHeader.mBits); // bits per plane - // TODO: Channels might be 5 for RGB + A + Mask... - String[] bps = new String[mHeader.mChannels]; - Arrays.fill(bps, bitDepth); - - node = new IIOMetadataNode("BitsPerSample"); - node.setAttribute("value", StringUtil.toCSVString(bps, " ")); - data_node.appendChild(node); - - // TODO: SampleMSB? Or is network (aka Motorola/big endian) byte order assumed? - - return data_node; - } - - @Override - protected IIOMetadataNode getStandardDimensionNode() { - IIOMetadataNode dimension_node = new IIOMetadataNode("Dimension"); - IIOMetadataNode node; // scratch node - - node = new IIOMetadataNode("PixelAspectRatio"); - // TODO: This is not incorrect wrt resolution info - float ratio = 1f; - node.setAttribute("value", Float.toString(ratio)); - dimension_node.appendChild(node); - - node = new IIOMetadataNode("ImageOrientation"); - node.setAttribute("value", "Normal"); - dimension_node.appendChild(node); - - List resolutionInfos = getResources(PSDResolutionInfo.class); - if (!resolutionInfos.isEmpty()) { - PSDResolutionInfo resolutionInfo = resolutionInfos.get(0); - - node = new IIOMetadataNode("HorizontalPixelSize"); - node.setAttribute("value", Float.toString(asMM(resolutionInfo.mHResUnit, resolutionInfo.mHRes))); - dimension_node.appendChild(node); - - node = new IIOMetadataNode("VerticalPixelSize"); - node.setAttribute("value", Float.toString(asMM(resolutionInfo.mVResUnit, resolutionInfo.mVRes))); - dimension_node.appendChild(node); - } - - // TODO: - /* - - - - - - - - - - - - - - - - - - - - - */ - return dimension_node; - } - - private static float asMM(final short pUnit, final float pResolution) { - // Unit: 1 -> pixels per inch, 2 -> pixels pr cm - return (pUnit == 1 ? 25.4f : 10) / pResolution; - } - - @Override - protected IIOMetadataNode getStandardDocumentNode() { - // TODO: PSDVersionInfo - -// if (!tIME_present) { -// return null; -// } -// -// IIOMetadataNode document_node = new IIOMetadataNode("Document"); -// IIOMetadataNode node = null; // scratch node -// -// node = new IIOMetadataNode("ImageModificationTime"); -// node.setAttribute("year", Integer.toString(tIME_year)); -// node.setAttribute("month", Integer.toString(tIME_month)); -// node.setAttribute("day", Integer.toString(tIME_day)); -// node.setAttribute("hour", Integer.toString(tIME_hour)); -// node.setAttribute("minute", Integer.toString(tIME_minute)); -// node.setAttribute("second", Integer.toString(tIME_second)); -// document_node.appendChild(node); -// -// return document_node; - return null; - } - - @Override - protected IIOMetadataNode getStandardTextNode() { - // TODO: CaptionDigest?, EXIF, XMP - -// int numEntries = tEXt_keyword.size() + -// iTXt_keyword.size() + zTXt_keyword.size(); -// if (numEntries == 0) { -// return null; -// } -// -// IIOMetadataNode text_node = new IIOMetadataNode("Text"); -// IIOMetadataNode node = null; // scratch node -// -// for (int i = 0; i < tEXt_keyword.size(); i++) { -// node = new IIOMetadataNode("TextEntry"); -// node.setAttribute("keyword", (String)tEXt_keyword.get(i)); -// node.setAttribute("value", (String)tEXt_text.get(i)); -// node.setAttribute("encoding", "ISO-8859-1"); -// node.setAttribute("compression", "none"); -// -// text_node.appendChild(node); -// } -// -// for (int i = 0; i < iTXt_keyword.size(); i++) { -// node = new IIOMetadataNode("TextEntry"); -// node.setAttribute("keyword", iTXt_keyword.get(i)); -// node.setAttribute("value", iTXt_text.get(i)); -// node.setAttribute("language", -// iTXt_languageTag.get(i)); -// if (iTXt_compressionFlag.get(i)) { -// node.setAttribute("compression", "deflate"); -// } else { -// node.setAttribute("compression", "none"); -// } -// -// text_node.appendChild(node); -// } -// -// for (int i = 0; i < zTXt_keyword.size(); i++) { -// node = new IIOMetadataNode("TextEntry"); -// node.setAttribute("keyword", (String)zTXt_keyword.get(i)); -// node.setAttribute("value", (String)zTXt_text.get(i)); -// node.setAttribute("compression", "deflate"); -// -// text_node.appendChild(node); -// } -// -// return text_node; - return null; - - } - - @Override - protected IIOMetadataNode getStandardTileNode() { - return super.getStandardTileNode(); - } - - @Override - protected IIOMetadataNode getStandardTransparencyNode() { - IIOMetadataNode transparency_node = - new IIOMetadataNode("Transparency"); - IIOMetadataNode node; // scratch node - - node = new IIOMetadataNode("Alpha"); - node.setAttribute("value", hasAlpha() ? "nonpremultipled" : "none"); // TODO: Check spec - transparency_node.appendChild(node); - - return transparency_node; - } - - private boolean hasAlpha() { - return mHeader.mMode == PSD.COLOR_MODE_RGB && mHeader.mChannels >= 4 || - mHeader.mMode == PSD.COLOR_MODE_CMYK & mHeader.mChannels >= 5; - } - - // TODO: Replace with filter iterator? - List getResources(final Class pResourceType) { - List filtered = null; - - for (PSDImageResource resource : mImageResources) { - if (pResourceType.isInstance(resource)) { - if (filtered == null) { - filtered = new ArrayList(); - } - - filtered.add(pResourceType.cast(resource)); - } - } - - return filtered; - } -} diff --git a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadataFormat.java b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadataFormat.java deleted file mode 100644 index 072748ce..00000000 --- a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDMetadataFormat.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.twelvemonkeys.imageio.plugins.psd; - -import javax.imageio.ImageTypeSpecifier; -import javax.imageio.metadata.IIOMetadataFormatImpl; -import java.util.Arrays; - -/** - * PSDMetadataFormat - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: PSDMetadataFormat.java,v 1.0 Nov 4, 2009 5:27:53 PM haraldk Exp$ - */ -public final class PSDMetadataFormat extends IIOMetadataFormatImpl { - - private final static PSDMetadataFormat sInstance = new PSDMetadataFormat(); - - /** - * Private constructor. - *

- * The {@link javax.imageio.metadata.IIOMetadata} class will instantiate this class - * by reflection, invoking the static {@code getInstance()} method. - * - * @see javax.imageio.metadata.IIOMetadata#getMetadataFormat - * @see #getInstance() - */ - private PSDMetadataFormat() { - // Defines the root element - super(PSDMetadata.NATIVE_METADATA_FORMAT_NAME, CHILD_POLICY_SOME); - - // root -> PSDHeader - // TODO: How do I specify that the header is required? - addElement("PSDHeader", PSDMetadata.NATIVE_METADATA_FORMAT_NAME, CHILD_POLICY_EMPTY); - - // TODO: Do the first two make sense? - addAttribute("PSDHeader", "signature", DATATYPE_STRING, false, "8BPS", Arrays.asList("8BPS")); - addAttribute("PSDHeader", "version", DATATYPE_INTEGER, false, "1", Arrays.asList("1")); - - addAttribute("PSDHeader", "channels", DATATYPE_INTEGER, true, null, "1", "24", true, true); - // rows? - addAttribute("PSDHeader", "height", DATATYPE_INTEGER, true, null, "1", "30000", true, true); - // columns? - 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", "mode", DATATYPE_INTEGER, true, null, Arrays.asList( - 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. - - For indexed color images, the count will be equal to 768, and the mode data - will contain the color table for the image, in non-interleaved order. - - For duotone images, the mode data will contain the duotone specification, - the format of which is not documented. Non-Photoshop readers can treat - the duotone image as a grayscale image, and keep the duotone specification - around as a black box for use when saving the file. - */ - // root -> Palette - // Color map for indexed, optional - // 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? - addElement("Palette", PSDMetadata.NATIVE_METADATA_FORMAT_NAME, 256, 256); // 768 = 256 * 3 - addElement("PaletteEntry", "PSDColorData", CHILD_POLICY_EMPTY); - addAttribute("PaletteEntry", "index", 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", "blue", DATATYPE_INTEGER, true, null, "0", "255", true, true); - // No alpha allowed in indexed color PSD - - // TODO: Duotone spec, optional (use same element as palette?) - // Or use object or raw bytes.. - - // root -> ImageResources - // Image resources, optional - addElement("ImageResources", PSDMetadata.NATIVE_METADATA_FORMAT_NAME, CHILD_POLICY_SEQUENCE); // SOME? - - // root -> ImageResources -> ImageResource - // Generic resource - addElement("ImageResource", "ImageResources", CHILD_POLICY_ALL); - // TODO: Allow arbitrary values to be added as a generic resource... - - // root -> ImageResources -> AlphaChannelInfo - addElement("AlphaChannelInfo", "ImageResources", CHILD_POLICY_EMPTY); - addAttribute("AlphaChannelInfo", "names", DATATYPE_STRING, true, 0, Integer.MAX_VALUE); - - // root -> ImageResources -> DisplayInfo - addElement("DisplayInfo", "ImageResources", CHILD_POLICY_EMPTY); - addAttribute("DisplayInfo", "colorSpace", DATATYPE_INTEGER, true, null); - addAttribute("DisplayInfo", "colors", DATATYPE_INTEGER, true, 4, 4); - addAttribute("DisplayInfo", "opacity", DATATYPE_INTEGER, true, null, "0", "100", true, true); - addAttribute("DisplayInfo", "kind", DATATYPE_INTEGER, true, null, Arrays.asList("0", "1")); - - // root -> ImageResources -> EXIF1Data - addElement("EXIF1Data", "ImageResources", CHILD_POLICY_ALL); - // TODO: Incorporate EXIF / TIFF metadata here somehow... (or treat as opaque bytes?) - - // root -> ImageResources -> PrintFlags - addElement("PrintFlags", "ImageResources", CHILD_POLICY_EMPTY); - addBooleanAttribute("PrintFlags", "labels", false, false); - addBooleanAttribute("PrintFlags", "cropMasks", false, false); - addBooleanAttribute("PrintFlags", "colorBars", false, false); - addBooleanAttribute("PrintFlags", "registrationMarks", false, false); - addBooleanAttribute("PrintFlags", "negative", false, false); - addBooleanAttribute("PrintFlags", "flip", false, false); - addBooleanAttribute("PrintFlags", "interpolate", false, false); - addBooleanAttribute("PrintFlags", "caption", false, false); - - // root -> ImageResources -> PrintFlagsInformation - addElement("PrintFlagsInformation", "ImageResources", CHILD_POLICY_EMPTY); - addAttribute("PrintFlagsInformation", "version", DATATYPE_INTEGER, true, null); - addBooleanAttribute("PrintFlagsInformation", "cropMarks", false, false); - addAttribute("PrintFlagsInformation", "field", DATATYPE_INTEGER, true, null); - addAttribute("PrintFlagsInformation", "bleedWidth", DATATYPE_INTEGER, true, null, "0", String.valueOf(Long.MAX_VALUE), true, true); // TODO: LONG??! - addAttribute("PrintFlagsInformation", "bleedScale", DATATYPE_INTEGER, true, null, "0", String.valueOf(Integer.MAX_VALUE), true, true); - - // root -> ImageResources -> ResolutionInfo - addElement("ResolutionInfo", "ImageResources", CHILD_POLICY_EMPTY); - addAttribute("ResolutionInfo", "hRes", DATATYPE_FLOAT, true, null); - // TODO: Or use string and more friendly names? "pixels/inch"/"pixels/cm" and "inch"/"cm"/"pt"/"pica"/"column" - addAttribute("ResolutionInfo", "hResUnit", DATATYPE_INTEGER, true, null, Arrays.asList("1", "2")); - addAttribute("ResolutionInfo", "widthUnit", DATATYPE_INTEGER, true, null, Arrays.asList("1", "2", "3", "4", "5")); - addAttribute("ResolutionInfo", "vRes", DATATYPE_FLOAT, true, null); - // TODO: Or use more friendly names? - addAttribute("ResolutionInfo", "vResUnit", DATATYPE_INTEGER, true, null, Arrays.asList("1", "2")); - addAttribute("ResolutionInfo", "heightUnit", DATATYPE_INTEGER, true, null, Arrays.asList("1", "2", "3", "4", "5")); - - // ??? addElement("Thumbnail", "ImageResources", CHILD_POLICY_CHOICE); - - // root -> ImageResources -> XMPData - addElement("XMPData", "ImageResources", CHILD_POLICY_CHOICE); - // TODO: Incorporate XMP metadata here somehow (or treat as opaque bytes?) - - // TODO: Layers - //addElement("ChannelSourceDestinationRange", "LayerSomething", CHILD_POLICY_CHOICE); - - // TODO: Global layer mask info - } - - - - @Override - public boolean canNodeAppear(final String pElementName, final ImageTypeSpecifier pImageType) { - // TODO: PSDColorData and PaletteEntry only for indexed color model - throw new UnsupportedOperationException("Method canNodeAppear not implemented"); // TODO: Implement - } - - /** - * Returns the shared instance of the {@code PSDMetadataFormat}. - * - * @return the shared instance. - * @see javax.imageio.metadata.IIOMetadata#getMetadataFormat - */ - public static PSDMetadataFormat getInstance() { - return sInstance; - } -} diff --git a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDResolutionInfo.java b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDResolutionInfo.java index 629f3a9c..43102599 100755 --- a/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDResolutionInfo.java +++ b/twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDResolutionInfo.java @@ -50,12 +50,13 @@ class PSDResolutionInfo extends PSDImageResource { // WORD HeightUnit; /* 1=in, 2=cm, 3=pt, 4=picas, 5=columns */ // } RESOLUTIONINFO; - float mHRes; - short mHResUnit; - short mWidthUnit; - float mVRes; - short mVResUnit; - short mHeightUnit; + private float mHRes; + private short mHResUnit; + private short mWidthUnit; + private float mVRes; + private short mVResUnit; + private short mHeightUnit; + PSDResolutionInfo(final short pId, final ImageInputStream pInput) throws IOException { super(pId, pInput);