Minor fixes and clean-up.

This commit is contained in:
Harald Kuhr 2012-02-01 15:58:54 +01:00
parent cda19ece0d
commit 1830808d56
9 changed files with 140 additions and 67 deletions

View File

@ -29,6 +29,7 @@
package com.twelvemonkeys.imageio.metadata;
import com.twelvemonkeys.lang.Validate;
import com.twelvemonkeys.util.CollectionUtil;
import java.lang.reflect.Array;
import java.util.Arrays;
@ -83,41 +84,13 @@ public abstract class AbstractEntry implements Entry {
public String getValueAsString() {
if (valueCount() > 1) {
if (valueCount() < 16) {
Class<?> type = value.getClass().getComponentType();
if (type.isPrimitive()) {
if (type.equals(boolean.class)) {
return Arrays.toString((boolean[]) value);
}
else if (type.equals(byte.class)) {
return Arrays.toString((byte[]) value);
}
else if (type.equals(char.class)) {
return new String((char[]) value);
}
else if (type.equals(double.class)) {
return Arrays.toString((double[]) value);
}
else if (type.equals(float.class)) {
return Arrays.toString((float[]) value);
}
else if (type.equals(int.class)) {
return Arrays.toString((int[]) value);
}
else if (type.equals(long.class)) {
return Arrays.toString((long[]) value);
}
else if (type.equals(short.class)) {
return Arrays.toString((short[]) value);
}
// Fall through should never happen
}
else {
return Arrays.toString((Object[]) value);
}
return arrayToString(value);
}
else {
String first = arrayToString(CollectionUtil.subArray(value, 0, 4));
String last = arrayToString(CollectionUtil.subArray(value, valueCount() - 4, 4));
return String.format("%s ... %s (%d)", first.substring(0, first.length() - 1), last.substring(1), valueCount());
}
return String.valueOf(value) + " (" + valueCount() + ")";
}
if (value != null && value.getClass().isArray() && Array.getLength(value) == 1) {
@ -127,6 +100,44 @@ public abstract class AbstractEntry implements Entry {
return String.valueOf(value);
}
private static String arrayToString(final Object value) {
Class<?> type = value.getClass().getComponentType();
if (type.isPrimitive()) {
if (type.equals(boolean.class)) {
return Arrays.toString((boolean[]) value);
}
else if (type.equals(byte.class)) {
return Arrays.toString((byte[]) value);
}
else if (type.equals(char.class)) {
return new String((char[]) value);
}
else if (type.equals(double.class)) {
return Arrays.toString((double[]) value);
}
else if (type.equals(float.class)) {
return Arrays.toString((float[]) value);
}
else if (type.equals(int.class)) {
return Arrays.toString((int[]) value);
}
else if (type.equals(long.class)) {
return Arrays.toString((long[]) value);
}
else if (type.equals(short.class)) {
return Arrays.toString((short[]) value);
}
else {
// Fall through should never happen
throw new AssertionError("Unknown type: " + type);
}
}
else {
return Arrays.toString((Object[]) value);
}
}
public String getTypeName() {
if (value == null) {
return null;

View File

@ -72,6 +72,8 @@ final class EXIFEntry extends AbstractEntry {
return "ImageWidth";
case TIFF.TAG_IMAGE_HEIGHT:
return "ImageHeight";
case TIFF.TAG_BITS_PER_SAMPLE:
return "BitsPerSample";
case TIFF.TAG_COMPRESSION:
return "Compression";
case TIFF.TAG_PHOTOMETRIC_INTERPRETATION:

View File

@ -213,6 +213,7 @@ public final class EXIFReader extends MetadataReader {
short type = pInput.readShort();
int count = pInput.readInt(); // Number of values
// TODO: Read up what the spec says about value-count == 0, it makes no sense.
if (count < 0) {
throw new IIOException(String.format("Illegal count %d for tag %s type %s @%08x", count, tagId, type, pInput.getStreamPosition()));
}
@ -242,7 +243,7 @@ public final class EXIFReader extends MetadataReader {
}
}
// TODO: For BigTiff allow size <= 8
// TODO: For BigTiff allow size > 4 && <= 8
if (valueLength > 0 && valueLength <= 4) {
value = readValueInLine(pInput, type, count);
pInput.skipBytes(4 - valueLength);

View File

@ -36,16 +36,32 @@ package com.twelvemonkeys.imageio.metadata.jpeg;
* @version $Id: JPEG.java,v 1.0 11.02.11 15.51 haraldk Exp$
*/
public interface JPEG {
/** Start of Image segment marker. */
int SOI = 0xFFD8;
/** End of Image segment marker. */
int EOI = 0xFFD9;
/** Start of Stream segment marker. */
int SOS = 0xFFDA;
// App segment markers (APPn)
int APP0 = 0xFFE0;
int APP1 = 0xFFE1;
int APP2 = 0xFFE2;
int APP3 = 0xFFE3;
int APP4 = 0xFFE4;
int APP5 = 0xFFE5;
int APP6 = 0xFFE6;
int APP7 = 0xFFE7;
int APP8 = 0xFFE8;
int APP9 = 0xFFE9;
int APP10 = 0xFFEA;
int APP11 = 0xFFEB;
int APP12 = 0xFFEC;
int APP13 = 0xFFED;
int APP14 = 0xFFEE;
int APP15 = 0xFFEF;
// Start of Frame segment markers (SOFn)
int SOF0 = 0xFFC0;
int SOF1 = 0xFFC1;
int SOF2 = 0xFFC2;
@ -59,4 +75,15 @@ public interface JPEG {
int SOF13 = 0xFFCD;
int SOF14 = 0xFFCE;
int SOF15 = 0xFFCF;
// TODO: Known/Important APPn markers
// "JFIF" APP0
// "JFXX" APP0
// "Exif" APP1
// "ICC_PROFILE" APP2
// "Adobe" APP14
// Possibly
// "http://ns.adobe.com/xap/1.0/" (XMP)
// "Photoshop 3.0" (Contains IPTC)
}

View File

@ -30,6 +30,7 @@ package com.twelvemonkeys.imageio.metadata.jpeg;
import com.twelvemonkeys.imageio.metadata.Directory;
import com.twelvemonkeys.imageio.metadata.exif.EXIFReader;
import com.twelvemonkeys.imageio.metadata.psd.PSDReader;
import com.twelvemonkeys.imageio.metadata.xmp.XMP;
import com.twelvemonkeys.imageio.metadata.xmp.XMPReader;
@ -37,8 +38,6 @@ import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.*;
@ -253,30 +252,11 @@ public final class JPEGSegmentUtil {
System.err.println("XMP: " + xmp);
}
else if ("Photoshop 3.0".equals(segment.identifier())) {
// TODO: It's probably a good idea to move some of the Photoshop ImageResource parsing code
// to the metadata sub project, as it may be contained in other formats (such as JFIF).
// TODO: The "Photoshop 3.0" segment contains several image resources, of which one might contain
// IPTC metadata. Probably duplicated in the XMP though...
try {
Class cl = Class.forName("com.twelvemonkeys.imageio.plugins.psd.PSDImageResource");
Method method = cl.getMethod("read", ImageInputStream.class);
method.setAccessible(true);
ImageInputStream stream = ImageIO.createImageInputStream(segment.data());
while (true) {
try {
Object photoShop = method.invoke(null, stream);
System.err.println("PhotoShop: " + photoShop);
}
catch (InvocationTargetException e) {
if (e.getTargetException() instanceof EOFException) {
break;
}
}
}
}
catch (Exception ignore) {
}
ImageInputStream stream = ImageIO.createImageInputStream(segment.data());
Directory psd = new PSDReader().read(stream);
System.err.println("PSD: " + psd);
}
else if ("ICC_PROFILE".equals(segment.identifier())) {
// Skip

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2012, 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;
/**
* PSD
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: PSD.java,v 1.0 24.01.12 16:51 haraldk Exp$
*/
interface PSD {
static final int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M';
static final int RES_IPTC_NAA = 0x0404;
}

View File

@ -29,6 +29,7 @@
package com.twelvemonkeys.imageio.metadata.psd;
import com.twelvemonkeys.imageio.metadata.AbstractEntry;
import com.twelvemonkeys.lang.StringUtil;
/**
* PhotoshopEntry
@ -38,12 +39,20 @@ import com.twelvemonkeys.imageio.metadata.AbstractEntry;
* @version $Id: PhotoshopEntry.java,v 1.0 04.01.12 11:58 haraldk Exp$
*/
class PSDEntry extends AbstractEntry {
public PSDEntry(final int resourceId, final Object value) {
private final String name;
public PSDEntry(final int resourceId, String name, final Object value) {
super(resourceId, value);
this.name = StringUtil.isEmpty(name) ? null : name;
}
@Override
protected String getNativeIdentifier() {
return String.format("0x%04x", (Integer) getIdentifier());
}
@Override
public String getFieldName() {
return name;
}
}

View File

@ -65,14 +65,14 @@ public final class PSDReader extends MetadataReader {
try {
int type = input.readInt();
if (type != PSDResource.RESOURCE_TYPE) {
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.data()));
entries.add(new PSDEntry(id, resource.name(), resource.data()));
}
catch (EOFException e) {
@ -84,9 +84,6 @@ public final class PSDReader extends MetadataReader {
}
protected static class PSDResource {
static final int RES_IPTC_NAA = 0x0404;
static final int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M';
static String readPascalString(final DataInput pInput) throws IOException {
int length = pInput.readUnsignedByte();
@ -122,7 +119,7 @@ public final class PSDReader extends MetadataReader {
readData(new SubImageInputStream(input, size));
// NOTE: This should never happen, however it's safer to keep it here to
// 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);
}
@ -143,6 +140,10 @@ public final class PSDReader extends MetadataReader {
return data;
}
public String name() {
return name;
}
@Override
public String toString() {
StringBuilder builder = toStringBuilder();

View File

@ -41,6 +41,6 @@ import com.twelvemonkeys.imageio.metadata.EntryAbstractTest;
public class PSDEntryTest extends EntryAbstractTest {
@Override
protected Entry createEntry(final Object value) {
return new PSDEntry(0x404, value);
return new PSDEntry(0x404, "", value);
}
}