com.twelvemonkeys.imageio.metadata.psd.PSDReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of imageio-metadata Show documentation
Show all versions of imageio-metadata Show documentation
TwelveMonkeys ImageIO metadata support classes.
/*
* Copyright (c) 2014, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.metadata.psd;
import com.twelvemonkeys.imageio.metadata.Directory;
import com.twelvemonkeys.imageio.metadata.MetadataReader;
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
import com.twelvemonkeys.lang.StringUtil;
import com.twelvemonkeys.lang.Validate;
import javax.imageio.IIOException;
import javax.imageio.stream.ImageInputStream;
import java.io.DataInput;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* PhotoshopReader
*
* @author Harald Kuhr
* @author last modified by $Author: haraldk$
* @version $Id: PhotoshopReader.java,v 1.0 04.01.12 11:56 haraldk Exp$
*/
public final class PSDReader extends MetadataReader {
// TODO: Add constructor to allow optional parsing of resources
// TODO: Maybe this should be modelled more like the JPEG segment parsing, as it's all binary data...
// - Segment/SegmentReader + List
@Override
public Directory read(final ImageInputStream input) throws IOException {
Validate.notNull(input, "input");
List entries = new ArrayList<>();
while (true) {
try {
int type = input.readInt();
if (type != PSD.RESOURCE_TYPE) {
throw new IIOException(String.format("Wrong image resource type, expected '8BIM': '%08x'", type));
}
short id = input.readShort();
PSDResource resource = new PSDResource(id, input);
entries.add(new PSDEntry(id, resource.name(), resource.data()));
}
catch (EOFException e) {
break;
}
}
return new PSDDirectory(entries);
}
protected static class PSDResource {
static String readPascalString(final DataInput pInput) throws IOException {
int length = pInput.readUnsignedByte();
if (length == 0) {
return "";
}
byte[] bytes = new byte[length];
pInput.readFully(bytes);
return StringUtil.decode(bytes, 0, bytes.length, "ASCII");
}
final short id;
final String name;
final long size;
byte[] data;
PSDResource(final short resourceId, final ImageInputStream input) throws IOException {
id = resourceId;
name = readPascalString(input);
// Skip pad
int nameSize = name.length() + 1;
if (nameSize % 2 != 0) {
input.readByte();
}
size = input.readUnsignedInt();
long startPos = input.getStreamPosition();
readData(new SubImageInputStream(input, size));
// NOTE: This should never happen, however it's safer to keep it here for future compatibility
if (input.getStreamPosition() != startPos + size) {
input.seek(startPos + size);
}
// Data is even-padded (word aligned)
if (size % 2 != 0) {
input.read();
}
}
protected void readData(final ImageInputStream pInput) throws IOException {
// TODO: This design is ugly, as subclasses readData is invoked BEFORE their respective constructor...
data = new byte[(int) size];
pInput.readFully(data);
}
public final int id() {
return id;
}
public final byte[] data() {
return data;
}
public String name() {
return name;
}
@Override
public String toString() {
StringBuilder builder = toStringBuilder();
builder.append(", data length: ");
builder.append(size);
builder.append("]");
return builder.toString();
}
protected StringBuilder toStringBuilder() {
StringBuilder builder = new StringBuilder(getClass().getSimpleName());
builder.append("[ID: 0x");
builder.append(Integer.toHexString(id));
if (name != null && name.trim().length() != 0) {
builder.append(", name: \"");
builder.append(name);
builder.append("\"");
}
return builder;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy