mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-03 11:35:29 -04:00
Massive metadata cleanup, new test cases and bugfix.
This commit is contained in:
parent
529377aa01
commit
84a2e8b10c
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.twelvemonkeys.lang.Validate.noNullElements;
|
||||
|
||||
/**
|
||||
* AbstractCompoundDirectory
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: AbstractCompoundDirectory.java,v 1.0 02.01.12 12:43 haraldk Exp$
|
||||
*/
|
||||
public abstract class AbstractCompoundDirectory extends AbstractDirectory implements CompoundDirectory {
|
||||
private final List<Directory> directories = new ArrayList<Directory>();
|
||||
|
||||
protected AbstractCompoundDirectory(final Collection<? extends Directory> directories) {
|
||||
super(null);
|
||||
|
||||
if (directories != null) {
|
||||
this.directories.addAll(noNullElements(directories));
|
||||
}
|
||||
}
|
||||
|
||||
public Directory getDirectory(int index) {
|
||||
return directories.get(index);
|
||||
}
|
||||
|
||||
public int directoryCount() {
|
||||
return directories.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entry getEntryById(final Object identifier) {
|
||||
for (Directory directory : directories) {
|
||||
Entry entry = directory.getEntryById(identifier);
|
||||
|
||||
if (entry != null) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entry getEntryByFieldName(final String fieldName) {
|
||||
for (Directory directory : directories) {
|
||||
Entry entry = directory.getEntryByFieldName(fieldName);
|
||||
|
||||
if (entry != null) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Entry> iterator() {
|
||||
return new Iterator<Entry>() {
|
||||
Iterator<Directory> directoryIterator = directories.iterator();
|
||||
Iterator<Entry> current;
|
||||
|
||||
public boolean hasNext() {
|
||||
return current != null && current.hasNext() || directoryIterator.hasNext() && (current = directoryIterator.next().iterator()).hasNext();
|
||||
}
|
||||
|
||||
public Entry next() {
|
||||
hasNext();
|
||||
|
||||
return current.next();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
current.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Define semantics, or leave to subclasses?
|
||||
// Add to first/last directory?
|
||||
// Introduce a "current" directory? And a way to advance/go back
|
||||
// Remove form the first directory that contains entry?
|
||||
@Override
|
||||
public boolean add(final Entry entry) {
|
||||
throw new UnsupportedOperationException("Directory is read-only");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(final Object entry) {
|
||||
throw new UnsupportedOperationException("Directory is read-only");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
int size = 0;
|
||||
|
||||
for (Directory directory : directories) {
|
||||
size += directory.size();
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s%s", getClass().getSimpleName(), directories.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 0;
|
||||
|
||||
for (Directory ifd : directories) {
|
||||
hash ^= ifd.hashCode();
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object pOther) {
|
||||
if (pOther == this) {
|
||||
return true;
|
||||
}
|
||||
if (pOther == null) {
|
||||
return false;
|
||||
}
|
||||
if (pOther.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CompoundDirectory other = (CompoundDirectory) pOther;
|
||||
|
||||
if (directoryCount() != other.directoryCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < directoryCount(); i++) {
|
||||
if (!getDirectory(i).equals(other.getDirectory(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -28,10 +28,9 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.metadata;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static com.twelvemonkeys.lang.Validate.noNullElements;
|
||||
|
||||
/**
|
||||
* AbstractDirectory
|
||||
@ -42,10 +41,11 @@ import java.util.List;
|
||||
*/
|
||||
public abstract class AbstractDirectory implements Directory {
|
||||
private final List<Entry> entries = new ArrayList<Entry>();
|
||||
private final List<Entry> unmodifiable = Collections.unmodifiableList(entries);
|
||||
|
||||
protected AbstractDirectory(final Collection<? extends Entry> pEntries) {
|
||||
if (pEntries != null) {
|
||||
entries.addAll(pEntries);
|
||||
protected AbstractDirectory(final Collection<? extends Entry> entries) {
|
||||
if (entries != null) {
|
||||
this.entries.addAll(noNullElements(entries));
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ public abstract class AbstractDirectory implements Directory {
|
||||
}
|
||||
|
||||
public Iterator<Entry> iterator() {
|
||||
return entries.iterator();
|
||||
return isReadOnly() ? unmodifiable.iterator() : entries.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,7 +127,7 @@ public abstract class AbstractDirectory implements Directory {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (getClass() != pOther.getClass()) {
|
||||
if (pOther == null || getClass() != pOther.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,17 @@ public abstract class AbstractEntry implements Entry {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a format-native identifier.
|
||||
* For example {@code "2:00"} for IPTC "Record Version" field, or {@code "0x040c"} for PSD "Thumbnail" resource.
|
||||
* This default implementation simply returns {@code String.valueOf(getIdentifier())}.
|
||||
*
|
||||
* @return a format-native identifier.
|
||||
*/
|
||||
protected String getNativeIdentifier() {
|
||||
return String.valueOf(getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code null}, meaning unknown or undefined.
|
||||
*
|
||||
@ -109,7 +120,7 @@ public abstract class AbstractEntry implements Entry {
|
||||
return String.valueOf(value) + " (" + valueCount() + ")";
|
||||
}
|
||||
|
||||
if (value.getClass().isArray() && Array.getLength(value) == 1) {
|
||||
if (value != null && value.getClass().isArray() && Array.getLength(value) == 1) {
|
||||
return String.valueOf(Array.get(value, 0));
|
||||
}
|
||||
|
||||
@ -137,7 +148,7 @@ public abstract class AbstractEntry implements Entry {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return identifier.hashCode() + 31 * value.hashCode();
|
||||
return identifier.hashCode() + (value != null ? 31 * value.hashCode() : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -164,6 +175,6 @@ public abstract class AbstractEntry implements Entry {
|
||||
String type = getTypeName();
|
||||
String typeStr = type != null ? " (" + type + ")" : "";
|
||||
|
||||
return String.format("%s%s: %s%s", getIdentifier(), nameStr, getValueAsString(), typeStr);
|
||||
return String.format("%s%s: %s%s", getNativeIdentifier(), nameStr, getValueAsString(), typeStr);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
* CompoundDirectory
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: CompoundDirectory.java,v 1.0 02.01.12 12:37 haraldk Exp$
|
||||
*/
|
||||
public interface CompoundDirectory extends Directory {
|
||||
Directory getDirectory(int index);
|
||||
|
||||
int directoryCount();
|
||||
}
|
@ -39,7 +39,7 @@ public interface Entry {
|
||||
// "tag" identifier from spec
|
||||
Object getIdentifier();
|
||||
|
||||
// Human readable "tag" (field) name from sepc
|
||||
// Human readable "tag" (field) name from spec
|
||||
String getFieldName();
|
||||
|
||||
// The internal "tag" value as stored in the stream, may be a Directory
|
||||
|
@ -28,8 +28,8 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.metadata.exif;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.AbstractDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.AbstractCompoundDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@ -40,8 +40,8 @@ import java.util.Collection;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: EXIFDirectory.java,v 1.0 Nov 11, 2009 5:02:59 PM haraldk Exp$
|
||||
*/
|
||||
final class EXIFDirectory extends AbstractDirectory {
|
||||
EXIFDirectory(final Collection<? extends Entry> entries) {
|
||||
super(entries);
|
||||
final class EXIFDirectory extends AbstractCompoundDirectory {
|
||||
EXIFDirectory(final Collection<? extends Directory> directories) {
|
||||
super(directories);
|
||||
}
|
||||
}
|
||||
|
@ -43,9 +43,9 @@ final class EXIFEntry extends AbstractEntry {
|
||||
EXIFEntry(final int identifier, final Object value, final short type) {
|
||||
super(identifier, value);
|
||||
|
||||
// if (type < 1 || type > TIFF.TYPE_NAMES.length) {
|
||||
// throw new IllegalArgumentException(String.format("Illegal EXIF type: %s", type));
|
||||
// }
|
||||
if (type < 1 || type > TIFF.TYPE_NAMES.length) {
|
||||
throw new IllegalArgumentException(String.format("Illegal EXIF type: %s", type));
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
@ -74,12 +74,20 @@ final class EXIFEntry extends AbstractEntry {
|
||||
return "ImageHeight";
|
||||
case TIFF.TAG_COMPRESSION:
|
||||
return "Compression";
|
||||
case TIFF.TAG_PHOTOMETRIC_INTERPRETATION:
|
||||
return "PhotometricInterpretation";
|
||||
case TIFF.TAG_IMAGE_DESCRIPTION:
|
||||
return "ImageDescription";
|
||||
case TIFF.TAG_ORIENTATION:
|
||||
return "Orientation";
|
||||
case TIFF.TAG_SAMPLES_PER_PIXELS:
|
||||
return "SamplesPerPixels";
|
||||
case TIFF.TAG_X_RESOLUTION:
|
||||
return "XResolution";
|
||||
case TIFF.TAG_Y_RESOLUTION:
|
||||
return "YResolution";
|
||||
case TIFF.TAG_PLANAR_CONFIGURATION:
|
||||
return "PlanarConfiguration";
|
||||
case TIFF.TAG_RESOLUTION_UNIT:
|
||||
return "ResolutionUnit";
|
||||
case TIFF.TAG_JPEG_INTERCHANGE_FORMAT:
|
||||
|
@ -28,10 +28,12 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.metadata.exif;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.AbstractCompoundDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReader;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
@ -40,10 +42,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* EXIFReader
|
||||
@ -53,10 +52,12 @@ import java.util.List;
|
||||
* @version $Id: EXIFReader.java,v 1.0 Nov 13, 2009 5:42:51 PM haraldk Exp$
|
||||
*/
|
||||
public final class EXIFReader extends MetadataReader {
|
||||
static final Collection<Integer> KNOWN_IFDS = Arrays.asList(TIFF.TAG_EXIF_IFD, TIFF.TAG_GPS_IFD, TIFF.TAG_INTEROP_IFD);
|
||||
static final Collection<Integer> KNOWN_IFDS = Collections.unmodifiableCollection(Arrays.asList(TIFF.TAG_EXIF_IFD, TIFF.TAG_GPS_IFD, TIFF.TAG_INTEROP_IFD));
|
||||
|
||||
@Override
|
||||
public Directory read(final ImageInputStream input) throws IOException {
|
||||
Validate.notNull(input, "input");
|
||||
|
||||
byte[] bom = new byte[2];
|
||||
input.readFully(bom);
|
||||
|
||||
@ -82,7 +83,8 @@ public final class EXIFReader extends MetadataReader {
|
||||
return readDirectory(input, directoryOffset);
|
||||
}
|
||||
|
||||
private EXIFDirectory readDirectory(final ImageInputStream pInput, final long pOffset) throws IOException {
|
||||
private Directory readDirectory(final ImageInputStream pInput, final long pOffset) throws IOException {
|
||||
List<IFD> ifds = new ArrayList<IFD>();
|
||||
List<Entry> entries = new ArrayList<Entry>();
|
||||
pInput.seek(pOffset);
|
||||
int entryCount = pInput.readUnsignedShort();
|
||||
@ -95,11 +97,12 @@ public final class EXIFReader extends MetadataReader {
|
||||
|
||||
// Read linked IFDs
|
||||
if (nextOffset != 0) {
|
||||
EXIFDirectory next = readDirectory(pInput, nextOffset);
|
||||
|
||||
for (Entry entry : next) {
|
||||
entries.add(entry);
|
||||
}
|
||||
// TODO: This is probably not okay anymore.. Replace recursion with while loop
|
||||
Directory next = readDirectory(pInput, nextOffset);
|
||||
ifds.add((IFD) ((AbstractCompoundDirectory) next).getDirectory(0));
|
||||
// for (Entry entry : next) {
|
||||
// entries.add(entry);
|
||||
// }
|
||||
}
|
||||
|
||||
// TODO: Make what sub-IFDs to parse optional? Or leave this to client code? At least skip the non-TIFF data?
|
||||
@ -113,7 +116,9 @@ public final class EXIFReader extends MetadataReader {
|
||||
)
|
||||
);
|
||||
|
||||
return new EXIFDirectory(entries);
|
||||
ifds.add(0, new IFD(entries));
|
||||
|
||||
return new EXIFDirectory(ifds);
|
||||
}
|
||||
|
||||
// private Directory readForeignMetadata(final MetadataReader reader, final byte[] bytes) throws IOException {
|
||||
@ -161,7 +166,7 @@ public final class EXIFReader extends MetadataReader {
|
||||
directory = new CompoundDocument(new ByteArrayInputStream((byte[]) entry.getValue())).getRootEntry();
|
||||
}
|
||||
else*/ if (KNOWN_IFDS.contains(tagId)) {
|
||||
directory = readDirectory(input, getPointerOffset(entry));
|
||||
directory = ((AbstractCompoundDirectory) readDirectory(input, getPointerOffset(entry))).getDirectory(0);
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
@ -273,9 +278,11 @@ public final class EXIFReader extends MetadataReader {
|
||||
switch (pType) {
|
||||
case 2: // ASCII
|
||||
// TODO: This might be UTF-8 or ISO-8859-x, even though spec says ASCII
|
||||
// TODO: Fail if unknown chars, try parsing with ISO-8859-1 or file.encoding
|
||||
byte[] ascii = new byte[pCount];
|
||||
pInput.readFully(ascii);
|
||||
return StringUtil.decode(ascii, 0, ascii.length, "UTF-8"); // UTF-8 is ASCII compatible
|
||||
int len = ascii[ascii.length - 1] == 0 ? ascii.length - 1 : ascii.length;
|
||||
return StringUtil.decode(ascii, 0, len, "UTF-8"); // UTF-8 is ASCII compatible
|
||||
case 1: // BYTE
|
||||
if (pCount == 1) {
|
||||
return pInput.readUnsignedByte();
|
||||
@ -399,10 +406,8 @@ public final class EXIFReader extends MetadataReader {
|
||||
return longs;
|
||||
|
||||
default:
|
||||
// Spec says skip unknown values:
|
||||
// TODO: Rather just return null, UNKNOWN_TYPE or new Unknown(type, count, offset) for value?
|
||||
// Spec says skip unknown values
|
||||
return new Unknown(pType, pCount, pos);
|
||||
// throw new IIOException(String.format("Unknown EXIF type '%s' at pos %d", pType, pInput.getStreamPosition()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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.exif;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.AbstractDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* IFD
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: IFD.java,v 1.0 23.12.11 16:24 haraldk Exp$
|
||||
*/
|
||||
final class IFD extends AbstractDirectory {
|
||||
protected IFD(final Collection<? extends Entry> pEntries) {
|
||||
super(pEntries);
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ package com.twelvemonkeys.imageio.metadata.exif;
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: Unknown.java,v 1.0 Oct 8, 2010 3:38:45 PM haraldk Exp$
|
||||
* @see <a href="http://en.wikipedia.org/wiki/There_are_known_knowns">There are known knowns</a>
|
||||
*/
|
||||
final class Unknown {
|
||||
private final short type;
|
||||
@ -24,7 +25,7 @@ final class Unknown {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(final Object other) {
|
||||
if (other != null && other.getClass() == getClass()) {
|
||||
Unknown unknown = (Unknown) other;
|
||||
return pos == unknown.pos && type == unknown.type && count == unknown.count;
|
||||
|
@ -45,6 +45,8 @@ class IPTCEntry extends AbstractEntry {
|
||||
@Override
|
||||
public String getFieldName() {
|
||||
switch ((Integer) getIdentifier()) {
|
||||
case IPTC.TAG_RECORD_VERSION:
|
||||
return "RecordVersion";
|
||||
case IPTC.TAG_SOURCE:
|
||||
return "Source";
|
||||
// TODO: More tags...
|
||||
@ -52,4 +54,10 @@ class IPTCEntry extends AbstractEntry {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNativeIdentifier() {
|
||||
int identifier = (Integer) getIdentifier();
|
||||
return String.format("%d:%02d", identifier >> 8, identifier & 0xff);
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReader;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
@ -62,7 +63,9 @@ public final class IPTCReader extends MetadataReader {
|
||||
|
||||
@Override
|
||||
public Directory read(final ImageInputStream input) throws IOException {
|
||||
final List<Entry> entries = new ArrayList<Entry>();
|
||||
Validate.notNull(input, "input");
|
||||
|
||||
List<Entry> entries = new ArrayList<Entry>();
|
||||
|
||||
// 0x1c identifies start of a tag
|
||||
while (input.read() == 0x1c) {
|
||||
|
@ -43,6 +43,7 @@ public interface JPEG {
|
||||
int APP0 = 0xFFE0;
|
||||
int APP1 = 0xFFE1;
|
||||
int APP2 = 0xFFE2;
|
||||
int APP13 = 0xFFED;
|
||||
int APP14 = 0xFFEE;
|
||||
|
||||
int SOF0 = 0xFFC0;
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.AbstractDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* PhotoshopDirectory
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: PhotoshopDirectory.java,v 1.0 04.01.12 11:58 haraldk Exp$
|
||||
*/
|
||||
final class PSDDirectory extends AbstractDirectory {
|
||||
public PSDDirectory(final Collection<? extends Entry> entries) {
|
||||
super(entries);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.AbstractEntry;
|
||||
|
||||
/**
|
||||
* PhotoshopEntry
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @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) {
|
||||
super(resourceId, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNativeIdentifier() {
|
||||
return String.format("0x%04x", (Integer) getIdentifier());
|
||||
}
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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 <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @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<Segment>
|
||||
|
||||
@Override
|
||||
public Directory read(final ImageInputStream input) throws IOException {
|
||||
Validate.notNull(input, "input");
|
||||
|
||||
List<PSDEntry> entries = new ArrayList<PSDEntry>();
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
int type = input.readInt();
|
||||
|
||||
if (type != PSDResource.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()));
|
||||
|
||||
}
|
||||
catch (EOFException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new PSDDirectory(entries);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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 to
|
||||
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 byte[] data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.xmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.AbstractDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* RDFDescription
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: RDFDescription.java,v 1.0 Nov 17, 2009 9:38:58 PM haraldk Exp$
|
||||
*/
|
||||
final class RDFDescription extends AbstractDirectory {
|
||||
private final String namespace;
|
||||
|
||||
// TODO: Store size of root directory, to allow serializing
|
||||
// TODO: XMPDirectory, maybe not even an AbstractDirectory
|
||||
// - Keeping the Document would allow for easier serialization
|
||||
// TODO: Or use direct SAX parsing
|
||||
public RDFDescription(Collection<? extends Entry> entries) {
|
||||
this(null, entries);
|
||||
}
|
||||
|
||||
public RDFDescription(String key, Collection<? extends Entry> entries) {
|
||||
super(entries);
|
||||
|
||||
namespace = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return namespace != null ?
|
||||
super.toString().replaceAll("^RDFDescription\\[", String.format("%s[%s|%s, ", getClass().getSimpleName(), XMP.DEFAULT_NS_MAPPING.get(namespace), namespace)) :
|
||||
super.toString();
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ package com.twelvemonkeys.imageio.metadata.xmp;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* XMP
|
||||
@ -59,6 +60,10 @@ public interface XMP {
|
||||
|
||||
String NS_XAP_MM = "http://ns.adobe.com/xap/1.0/mm/";
|
||||
|
||||
String NS_X = "adobe:ns:meta/";
|
||||
|
||||
/** Contains the mapping from URI to default namespace prefix. */
|
||||
Map<String, String> DEFAULT_NS_MAPPING = Collections.unmodifiableMap(new XMPNamespaceMapping());
|
||||
Map<String, String> DEFAULT_NS_MAPPING = Collections.unmodifiableMap(new XMPNamespaceMapping(true));
|
||||
|
||||
Set<String> ELEMENTS = Collections.unmodifiableSet(new XMPNamespaceMapping(false).keySet());
|
||||
}
|
||||
|
@ -28,10 +28,10 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.metadata.xmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.AbstractDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.AbstractCompoundDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* XMPDirectory
|
||||
@ -40,12 +40,30 @@ import java.util.List;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: XMPDirectory.java,v 1.0 Nov 17, 2009 9:38:58 PM haraldk Exp$
|
||||
*/
|
||||
final class XMPDirectory extends AbstractDirectory {
|
||||
// TODO: Store size of root directory, to allow serializing
|
||||
final class XMPDirectory extends AbstractCompoundDirectory {
|
||||
// TODO: Allow lookup of directories by namespace?
|
||||
// TODO: Allow merge/sync/comparison with IPTC/EXIF/TIFF metadata
|
||||
// TODO: Store size of root directory, to allow easy serializing (see isReadOnly comment)
|
||||
// TODO: XMPDirectory, maybe not even an AbstractDirectory
|
||||
// - Keeping the Document would allow for easier serialization
|
||||
// TODO: Or use direct SAX parsing
|
||||
public XMPDirectory(List<Entry> entries) {
|
||||
private final String toolkit;
|
||||
|
||||
public XMPDirectory(Collection<? extends Directory> entries, String toolkit) {
|
||||
super(entries);
|
||||
|
||||
this.toolkit = toolkit;
|
||||
}
|
||||
|
||||
// TODO: Expose x:xmptk (getXMPToolkit(): String)
|
||||
/*public*/ String getWriterToolkit() {
|
||||
return toolkit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
// TODO: Depend on <?xpacket end="w"?>/<?xpacket end="r"?> for writable/read-only respectively?
|
||||
// Spec says allow writing (even if "r"), if the container format is understood (ie. single file, known format, update checksums etc)
|
||||
return super.isReadOnly();
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ import com.twelvemonkeys.imageio.metadata.AbstractEntry;
|
||||
final class XMPEntry extends AbstractEntry {
|
||||
private final String fieldName;
|
||||
|
||||
// TODO: Rewrite to use namespace + field instead of identifier (for the nativeIdentifier) method
|
||||
public XMPEntry(final String identifier, final Object pValue) {
|
||||
this(identifier, null, pValue);
|
||||
}
|
||||
@ -49,6 +50,13 @@ final class XMPEntry extends AbstractEntry {
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNativeIdentifier() {
|
||||
String identifier = (String) getIdentifier();
|
||||
String namespace = fieldName != null && identifier.endsWith(fieldName) ? XMP.DEFAULT_NS_MAPPING.get(identifier.substring(0, identifier.length() - fieldName.length())) : null;
|
||||
return namespace != null ? namespace + ":" + fieldName : identifier;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"SuspiciousMethodCalls"})
|
||||
@Override
|
||||
public String getFieldName() {
|
||||
@ -60,6 +68,6 @@ final class XMPEntry extends AbstractEntry {
|
||||
String type = getTypeName();
|
||||
String typeStr = type != null ? " (" + type + ")" : "";
|
||||
|
||||
return String.format("%s: %s%s", getIdentifier(), getValueAsString(), typeStr);
|
||||
return String.format("%s: %s%s", getNativeIdentifier(), getValueAsString(), typeStr);
|
||||
}
|
||||
}
|
||||
|
@ -38,8 +38,12 @@ import java.util.HashMap;
|
||||
* @version $Id: XMPNamespaceMapping.java,v 1.0 Nov 17, 2009 6:35:21 PM haraldk Exp$
|
||||
*/
|
||||
final class XMPNamespaceMapping extends HashMap<String, String> {
|
||||
public XMPNamespaceMapping() {
|
||||
public XMPNamespaceMapping(boolean includeNonElements) {
|
||||
if (includeNonElements) {
|
||||
put(XMP.NS_RDF, "rdf");
|
||||
put(XMP.NS_X, "x");
|
||||
}
|
||||
|
||||
put(XMP.NS_DC, "dc");
|
||||
put(XMP.NS_EXIF, "exif");
|
||||
put(XMP.NS_PHOTOSHOP, "photoshop");
|
||||
|
@ -32,6 +32,7 @@ import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReader;
|
||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
@ -55,17 +56,13 @@ import java.util.*;
|
||||
* @version $Id: XMPReader.java,v 1.0 Nov 14, 2009 11:04:30 PM haraldk Exp$
|
||||
*/
|
||||
public final class XMPReader extends MetadataReader {
|
||||
// See http://www.scribd.com/doc/56852716/XMPSpecificationPart1
|
||||
|
||||
// TODO: Types? Probably defined in XMP/RDF XML schema. Or are we happy that everything is a string?
|
||||
|
||||
@Override
|
||||
public Directory read(final ImageInputStream input) throws IOException {
|
||||
// pInput.mark();
|
||||
//
|
||||
// BufferedReader reader = new BufferedReader(new InputStreamReader(IIOUtil.createStreamAdapter(pInput), Charset.forName("UTF-8")));
|
||||
// String line;
|
||||
// while ((line = reader.readLine()) != null) {
|
||||
// System.out.println(line);
|
||||
// }
|
||||
//
|
||||
// pInput.reset();
|
||||
Validate.notNull(input, "input");
|
||||
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
@ -80,14 +77,11 @@ public final class XMPReader extends MetadataReader {
|
||||
// XMLSerializer serializer = new XMLSerializer(System.err, System.getProperty("file.encoding"));
|
||||
// serializer.serialize(document);
|
||||
|
||||
|
||||
// Each rdf:Description is a Directory (but we can't really rely on that structure.. it's only convention)
|
||||
// - Each element inside the rdf:Desc is an Entry
|
||||
|
||||
String toolkit = getToolkit(document);
|
||||
Node rdfRoot = document.getElementsByTagNameNS(XMP.NS_RDF, "RDF").item(0);
|
||||
NodeList descriptions = document.getElementsByTagNameNS(XMP.NS_RDF, "Description");
|
||||
|
||||
return parseDirectories(rdfRoot, descriptions);
|
||||
return parseDirectories(rdfRoot, descriptions, toolkit);
|
||||
}
|
||||
catch (SAXException e) {
|
||||
throw new IIOException(e.getMessage(), e);
|
||||
@ -97,7 +91,19 @@ public final class XMPReader extends MetadataReader {
|
||||
}
|
||||
}
|
||||
|
||||
private XMPDirectory parseDirectories(final Node pParentNode, NodeList pNodes) {
|
||||
private String getToolkit(Document document) {
|
||||
NodeList xmpmeta = document.getElementsByTagNameNS(XMP.NS_X, "xmpmeta");
|
||||
|
||||
if (xmpmeta == null || xmpmeta.getLength() <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Node toolkit = xmpmeta.item(0).getAttributes().getNamedItemNS(XMP.NS_X, "xmptk");
|
||||
|
||||
return toolkit != null ? toolkit.getNodeValue() : null;
|
||||
}
|
||||
|
||||
private XMPDirectory parseDirectories(final Node pParentNode, NodeList pNodes, String toolkit) {
|
||||
Map<String, List<Entry>> subdirs = new LinkedHashMap<String, List<Entry>>();
|
||||
|
||||
for (Node desc : asIterable(pNodes)) {
|
||||
@ -105,6 +111,9 @@ public final class XMPReader extends MetadataReader {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Support attribute short-hand syntax
|
||||
parseAttributesForKnownElements(subdirs, desc);
|
||||
|
||||
for (Node node : asIterable(desc.getChildNodes())) {
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
@ -121,6 +130,7 @@ public final class XMPReader extends MetadataReader {
|
||||
|
||||
Node parseType = node.getAttributes().getNamedItemNS(XMP.NS_RDF, "parseType");
|
||||
if (parseType != null && "Resource".equals(parseType.getNodeValue())) {
|
||||
// See: http://www.w3.org/TR/REC-rdf-syntax/#section-Syntax-parsetype-resource
|
||||
List<Entry> entries = new ArrayList<Entry>();
|
||||
|
||||
for (Node child : asIterable(node.getChildNodes())) {
|
||||
@ -130,60 +140,119 @@ public final class XMPReader extends MetadataReader {
|
||||
|
||||
entries.add(new XMPEntry(child.getNamespaceURI() + child.getLocalName(), child.getLocalName(), getChildTextValue(child)));
|
||||
}
|
||||
value = new XMPDirectory(entries);
|
||||
|
||||
value = new RDFDescription(entries);
|
||||
}
|
||||
else {
|
||||
// TODO: Support alternative RDF syntax (short-form), using attributes on desc
|
||||
// NamedNodeMap attributes = node.getAttributes();
|
||||
//
|
||||
// for (Node attr : asIterable(attributes)) {
|
||||
// System.out.println("attr.getNodeName(): " + attr.getNodeName());
|
||||
// System.out.println("attr.getNodeValue(): " + attr.getNodeValue());
|
||||
// }
|
||||
// TODO: This method contains loads of duplication an should be cleaned up...
|
||||
// Support attribute short-hand syntax
|
||||
Map<String, List<Entry>> subsubdirs = new LinkedHashMap<String, List<Entry>>();
|
||||
|
||||
value = getChildTextValue(node);
|
||||
}
|
||||
parseAttributesForKnownElements(subsubdirs, node);
|
||||
|
||||
XMPEntry entry = new XMPEntry(node.getNamespaceURI() + node.getLocalName(), node.getLocalName(), value);
|
||||
dir.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Consider flattening the somewhat artificial directory structure
|
||||
if (!subsubdirs.isEmpty()) {
|
||||
List<Entry> entries = new ArrayList<Entry>();
|
||||
|
||||
for (Map.Entry<String, List<Entry>> entry : subsubdirs.entrySet()) {
|
||||
entries.addAll(entry.getValue());
|
||||
}
|
||||
|
||||
value = new RDFDescription(entries);
|
||||
}
|
||||
else {
|
||||
value = getChildTextValue(node);
|
||||
}
|
||||
}
|
||||
|
||||
dir.add(new XMPEntry(node.getNamespaceURI() + node.getLocalName(), node.getLocalName(), value));
|
||||
}
|
||||
}
|
||||
|
||||
List<Directory> entries = new ArrayList<Directory>();
|
||||
|
||||
// TODO: Should we still allow asking for a subdirectory by item id?
|
||||
for (Map.Entry<String, List<Entry>> entry : subdirs.entrySet()) {
|
||||
entries.add(new XMPEntry(entry.getKey(), new XMPDirectory(entry.getValue())));
|
||||
entries.add(new RDFDescription(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
return new XMPDirectory(entries);
|
||||
return new XMPDirectory(entries, toolkit);
|
||||
}
|
||||
|
||||
private void parseAttributesForKnownElements(Map<String, List<Entry>> subdirs, Node desc) {
|
||||
// NOTE: NamedNodeMap does not have any particular order...
|
||||
NamedNodeMap attributes = desc.getAttributes();
|
||||
|
||||
for (Node attr : asIterable(attributes)) {
|
||||
if (!XMP.ELEMENTS.contains(attr.getNamespaceURI())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Entry> dir = subdirs.get(attr.getNamespaceURI());
|
||||
|
||||
if (dir == null) {
|
||||
dir = new ArrayList<Entry>();
|
||||
subdirs.put(attr.getNamespaceURI(), dir);
|
||||
}
|
||||
|
||||
dir.add(new XMPEntry(attr.getNamespaceURI() + attr.getLocalName(), attr.getLocalName(), attr.getNodeValue()));
|
||||
}
|
||||
}
|
||||
|
||||
private Object getChildTextValue(final Node node) {
|
||||
for (Node child : asIterable(node.getChildNodes())) {
|
||||
if (XMP.NS_RDF.equals(child.getNamespaceURI()) && "Alt".equals(child.getLocalName())) {
|
||||
// Support for <rdf:Alt><rdf:li> -> return a Map<String, Object> (keyed on xml:lang?)
|
||||
Map<String, Object> alternatives = new LinkedHashMap<String, Object>();
|
||||
for (Node alternative : asIterable(child.getChildNodes())) {
|
||||
if (XMP.NS_RDF.equals(alternative.getNamespaceURI()) && "li".equals(alternative.getLocalName())) {
|
||||
//return getChildTextValue(alternative);
|
||||
NamedNodeMap attributes = alternative.getAttributes();
|
||||
Node key = attributes.getNamedItem("xml:lang");
|
||||
|
||||
alternatives.put(key.getTextContent(), getChildTextValue(alternative));
|
||||
}
|
||||
}
|
||||
|
||||
return alternatives;
|
||||
}
|
||||
else if (XMP.NS_RDF.equals(child.getNamespaceURI()) && ("Seq".equals(child.getLocalName()) || "Bag".equals(child.getLocalName()))) {
|
||||
// Support for <rdf:Seq><rdf:li> -> return array
|
||||
// Support for <rdf:Bag><rdf:li> -> return array/unordered collection (how can a serialized collection not have order?)
|
||||
List<Object> seq = new ArrayList<Object>();
|
||||
|
||||
for (Node sequence : asIterable(child.getChildNodes())) {
|
||||
if (XMP.NS_RDF.equals(sequence.getNamespaceURI()) && "li".equals(sequence.getLocalName())) {
|
||||
Object value = getChildTextValue(sequence);
|
||||
seq.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Strictly a bag should not be a list, but there's no Bag type (or similar) in Java.
|
||||
// Consider something like Google collections Multiset or Apache commons Bag (the former seems more well-defined)
|
||||
// Note: Collection does not have defined equals() semantics, and so using
|
||||
// Collections.unmodifiableCollection() doesn't work for comparing values (uses Object.equals())
|
||||
return Collections.unmodifiableList(seq);
|
||||
}
|
||||
}
|
||||
|
||||
private Object getChildTextValue(Node node) {
|
||||
Object value;
|
||||
Node child = node.getFirstChild();
|
||||
String strVal = child != null ? child.getNodeValue() : null;
|
||||
|
||||
String strVal = null;
|
||||
if (child != null) {
|
||||
strVal = child.getNodeValue();
|
||||
}
|
||||
|
||||
value = strVal != null ? strVal.trim() : "";
|
||||
return value;
|
||||
return strVal != null ? strVal.trim() : "";
|
||||
}
|
||||
|
||||
private Iterable<? extends Node> asIterable(final NamedNodeMap pNodeList) {
|
||||
return new Iterable<Node>() {
|
||||
public Iterator<Node> iterator() {
|
||||
return new Iterator<Node>() {
|
||||
private int mIndex;
|
||||
private int index;
|
||||
|
||||
public boolean hasNext() {
|
||||
return pNodeList != null && pNodeList.getLength() > mIndex;
|
||||
return pNodeList != null && pNodeList.getLength() > index;
|
||||
}
|
||||
|
||||
public Node next() {
|
||||
return pNodeList.item(mIndex++);
|
||||
return pNodeList.item(index++);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
@ -198,14 +267,14 @@ public final class XMPReader extends MetadataReader {
|
||||
return new Iterable<Node>() {
|
||||
public Iterator<Node> iterator() {
|
||||
return new Iterator<Node>() {
|
||||
private int mIndex;
|
||||
private int index;
|
||||
|
||||
public boolean hasNext() {
|
||||
return pNodeList != null && pNodeList.getLength() > mIndex;
|
||||
return pNodeList != null && pNodeList.getLength() > index;
|
||||
}
|
||||
|
||||
public Node next() {
|
||||
return pNodeList.item(mIndex++);
|
||||
return pNodeList.item(index++);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
@ -215,5 +284,4 @@ public final class XMPReader extends MetadataReader {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -140,8 +140,8 @@ public final class XMPScanner {
|
||||
// UTF 32 BIG endian
|
||||
cs = Charset.forName("UTF-32BE");
|
||||
}
|
||||
else if (bom[0] == (byte) 0xFF && bom[1] == (byte) 0xFE && bom[2] == 0x00 && bom[3] == 0x00) {
|
||||
// TODO: FixMe..
|
||||
else if (bom[0] == 0x00 && bom[1] == 0x00 && bom[2] == 0x00 && bom[3] == (byte) 0xFF && stream.read() == 0xFE) {
|
||||
stream.skipBytes(2); // Alignment
|
||||
// NOTE: 32-bit character set not supported by default
|
||||
// UTF 32 little endian
|
||||
cs = Charset.forName("UTF-32LE");
|
||||
@ -220,8 +220,6 @@ public final class XMPScanner {
|
||||
return -1l;
|
||||
}
|
||||
|
||||
//static public XMPDirectory parse(input);
|
||||
|
||||
public static void main(final String[] pArgs) throws IOException {
|
||||
ImageInputStream stream = ImageIO.createImageInputStream(new File(pArgs[0]));
|
||||
|
||||
@ -236,8 +234,5 @@ public final class XMPScanner {
|
||||
}
|
||||
|
||||
stream.close();
|
||||
// else {
|
||||
// System.err.println("XMP not found");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* AbstractCompoundDirectoryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: AbstractCompoundDirectoryTest.java,v 1.0 02.01.12 15:07 haraldk Exp$
|
||||
*/
|
||||
public class AbstractCompoundDirectoryTest extends CompoundDirectoryAbstractTest {
|
||||
@Override
|
||||
protected CompoundDirectory createCompoundDirectory(final Collection<Directory> directories) {
|
||||
return new AbstractCompoundDirectory(directories) {};
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* AbstractDirectoryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: AbstractDirectoryTest.java,v 1.0 02.01.12 15:07 haraldk Exp$
|
||||
*/
|
||||
public class AbstractDirectoryTest extends DirectoryAbstractTest {
|
||||
@Override
|
||||
protected Directory createDirectory(final Collection<Entry> entries) {
|
||||
return new AbstractDirectory(entries) {};
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* AbstractEntryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: AbstractEntryTest.java,v 1.0 02.01.12 17:22 haraldk Exp$
|
||||
*/
|
||||
public class AbstractEntryTest extends EntryAbstractTest {
|
||||
@Override
|
||||
protected final Entry createEntry(final Object value) {
|
||||
return createEntry("foo", value);
|
||||
}
|
||||
|
||||
private AbstractEntry createEntry(final String identifier, final Object value) {
|
||||
return new AbstractEntry(identifier, value) {};
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateEntryNullId() {
|
||||
createEntry(null, new Object());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAbstractEntry() {
|
||||
Object value = new Object();
|
||||
Entry entry = createEntry("foo", value);
|
||||
|
||||
assertEquals("foo", entry.getIdentifier());
|
||||
assertNull(entry.getFieldName());
|
||||
assertSame(value, entry.getValue());
|
||||
assertNotNull(entry.getValueAsString());
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* CompoundDirectoryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: CompoundDirectoryTest.java,v 1.0 02.01.12 15:07 haraldk Exp$
|
||||
*/
|
||||
public abstract class CompoundDirectoryAbstractTest extends DirectoryAbstractTest {
|
||||
protected abstract CompoundDirectory createCompoundDirectory(Collection<Directory> directories);
|
||||
|
||||
// Override by subclasses that require special kind of directory
|
||||
protected Directory createSingleDirectory(final Collection<Entry> entries) {
|
||||
return new TestDirectory(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final Directory createDirectory(final Collection<Entry> entries) {
|
||||
// A compound directory should behave like a normal directory
|
||||
return createCompoundDirectory(Collections.<Directory>singleton(createSingleDirectory(entries)));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateNullDirectories() {
|
||||
createCompoundDirectory(Collections.<Directory>singleton(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingle() {
|
||||
Directory only = createSingleDirectory(null);
|
||||
|
||||
CompoundDirectory directory = createCompoundDirectory(Collections.<Directory>singleton(only));
|
||||
|
||||
assertEquals(1, directory.directoryCount());
|
||||
assertSame(only, directory.getDirectory(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiple() {
|
||||
Directory one = createSingleDirectory(null);
|
||||
Directory two = createSingleDirectory(null);
|
||||
Directory three = createSingleDirectory(null);
|
||||
|
||||
CompoundDirectory directory = createCompoundDirectory(Arrays.<Directory>asList(one, two, three));
|
||||
|
||||
assertEquals(3, directory.directoryCount());
|
||||
assertSame(one, directory.getDirectory(0));
|
||||
assertSame(two, directory.getDirectory(1));
|
||||
assertSame(three, directory.getDirectory(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntries() {
|
||||
Directory one = createSingleDirectory(null);
|
||||
Directory two = createSingleDirectory(null);
|
||||
Directory three = createSingleDirectory(null);
|
||||
|
||||
CompoundDirectory directory = createCompoundDirectory(Arrays.<Directory>asList(one, two, three));
|
||||
|
||||
assertEquals(3, directory.directoryCount());
|
||||
assertSame(one, directory.getDirectory(0));
|
||||
assertSame(two, directory.getDirectory(1));
|
||||
assertSame(three, directory.getDirectory(2));
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
public void testOutOfBounds() {
|
||||
Directory only = createSingleDirectory(null);
|
||||
CompoundDirectory directory = createCompoundDirectory(Collections.<Directory>singleton(only));
|
||||
|
||||
directory.getDirectory(directory.directoryCount());
|
||||
}
|
||||
|
||||
protected static final class TestDirectory extends AbstractDirectory {
|
||||
public TestDirectory(final Collection<Entry> entries) {
|
||||
super(entries);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.twelvemonkeys.lang.ObjectAbstractTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* DirectoryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: DirectoryTest.java,v 1.0 02.01.12 15:07 haraldk Exp$
|
||||
*/
|
||||
public abstract class DirectoryAbstractTest extends ObjectAbstractTestCase {
|
||||
|
||||
@Override
|
||||
protected Object makeObject() {
|
||||
return createDirectory(Collections.singleton(createEntry("entry", null)));
|
||||
}
|
||||
|
||||
protected abstract Directory createDirectory(Collection<Entry> entries);
|
||||
|
||||
// Override by subclasses that requires special type of entries
|
||||
protected Entry createEntry(final String identifier, final Object value) {
|
||||
return new TestEntry(identifier, value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateNull() {
|
||||
Directory directory = createDirectory(null);
|
||||
|
||||
assertEquals(0, directory.size());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateNullEntries() {
|
||||
createDirectory(Collections.<Entry>singleton(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleEntry() {
|
||||
Entry entry = createEntry("foo", new Object());
|
||||
Directory directory = createDirectory(Collections.singleton(entry));
|
||||
|
||||
assertEquals(1, directory.size());
|
||||
assertSame(entry, directory.getEntryById("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonExistentEntry() {
|
||||
Entry entry = createEntry("foo", new Object());
|
||||
Directory directory = createDirectory(Collections.singleton(entry));
|
||||
assertNull(directory.getEntryById("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleEntries() {
|
||||
Entry one = createEntry("foo", new Object());
|
||||
Entry two = createEntry("bar", new Object());
|
||||
|
||||
Directory directory = createDirectory(Arrays.asList(one, two));
|
||||
|
||||
assertEquals(2, directory.size());
|
||||
|
||||
assertSame(one, directory.getEntryById("foo"));
|
||||
assertSame(two, directory.getEntryById("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyIterator() {
|
||||
Directory directory = createDirectory(null);
|
||||
|
||||
assertEquals(0, directory.size());
|
||||
|
||||
assertFalse(directory.iterator().hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleIterator() {
|
||||
Entry one = createEntry("foo", new Object());
|
||||
|
||||
Directory directory = createDirectory(Arrays.asList(one));
|
||||
|
||||
int count = 0;
|
||||
for (Entry entry : directory) {
|
||||
assertSame(one, entry);
|
||||
count++;
|
||||
}
|
||||
|
||||
assertEquals(1, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIteratorMutability() {
|
||||
Entry one = createEntry("foo", new Object());
|
||||
Entry two = createEntry("bar", new Object());
|
||||
|
||||
Directory directory = createDirectory(Arrays.asList(one, two));
|
||||
|
||||
assertEquals(2, directory.size());
|
||||
|
||||
Iterator<Entry> entries = directory.iterator();
|
||||
if (!directory.isReadOnly()) {
|
||||
while (entries.hasNext()) {
|
||||
entries.next();
|
||||
entries.remove();
|
||||
}
|
||||
|
||||
assertEquals(0, directory.size());
|
||||
}
|
||||
else {
|
||||
while (entries.hasNext()) {
|
||||
try {
|
||||
entries.next();
|
||||
entries.remove();
|
||||
fail("Expected UnsupportedOperationException");
|
||||
}
|
||||
catch (UnsupportedOperationException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(2, directory.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleIterator() {
|
||||
Entry one = createEntry("foo", new Object());
|
||||
Entry two = createEntry("bar", new Object());
|
||||
Entry three = createEntry("baz", new Object());
|
||||
|
||||
List<Entry> all = Arrays.asList(one, two, three);
|
||||
Directory directory = createDirectory(all);
|
||||
|
||||
// Test that each element is contained, and only once
|
||||
List<Entry> entries = new ArrayList<Entry>(all);
|
||||
|
||||
int count = 0;
|
||||
for (Entry entry : directory) {
|
||||
assertTrue(entries.contains(entry));
|
||||
assertTrue(entries.remove(entry));
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
assertTrue(entries.isEmpty());
|
||||
assertEquals(3, count);
|
||||
}
|
||||
|
||||
protected static class TestEntry extends AbstractEntry {
|
||||
public TestEntry(final String identifier, final Object value) {
|
||||
super(identifier, value);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.twelvemonkeys.lang.ObjectAbstractTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* EntryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: EntryTest.java,v 1.0 02.01.12 17:33 haraldk Exp$
|
||||
*/
|
||||
public abstract class EntryAbstractTest extends ObjectAbstractTestCase {
|
||||
@Override
|
||||
protected Object makeObject() {
|
||||
return createEntry(new Object());
|
||||
}
|
||||
|
||||
protected abstract Entry createEntry(Object value);
|
||||
|
||||
@Test
|
||||
public void testCreateEntryNullValue() {
|
||||
Entry foo = createEntry(null);
|
||||
|
||||
assertNotNull(foo.getIdentifier());
|
||||
assertEquals(null, foo.getValue());
|
||||
|
||||
assertEquals("null", foo.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntryStringValue() {
|
||||
Entry foo = createEntry("bar");
|
||||
|
||||
assertNotNull(foo.getIdentifier());
|
||||
assertEquals("bar", foo.getValue());
|
||||
assertEquals("bar", foo.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntryValue() {
|
||||
Entry foo = createEntry(77);
|
||||
|
||||
assertNotNull(foo.getIdentifier());
|
||||
assertEquals(77, foo.getValue());
|
||||
assertEquals("77", foo.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullValueHashCode() {
|
||||
Entry foo = createEntry(null);
|
||||
|
||||
// Doesn't really matter, as long as it doesn't throw NPE, but this should hold for all entries
|
||||
assertNotSame(0, foo.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayValueHashCode() {
|
||||
// Doesn't really matter, as long as it doesn't throw NPE, but this should hold for all entries
|
||||
assertNotSame(0, createEntry(new int[0]).hashCode());
|
||||
assertNotSame(0, createEntry(new int[1]).hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayValue() {
|
||||
int[] array = {42, -1, 77, 99, 55};
|
||||
Entry foo = createEntry(array);
|
||||
|
||||
assertEquals(5, foo.valueCount());
|
||||
assertArrayEquals(array, (int[]) foo.getValue());
|
||||
|
||||
// Not strictly necessary, but nice
|
||||
assertEquals(Arrays.toString(array), foo.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharArrayValue() {
|
||||
char[] array = {'f', '0', '0'};
|
||||
Entry foo = createEntry(array);
|
||||
|
||||
assertEquals(3, foo.valueCount());
|
||||
assertArrayEquals(array, (char[]) foo.getValue());
|
||||
|
||||
// Not strictly necessary, but nice
|
||||
assertEquals("f00", foo.getValueAsString());
|
||||
}
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Test;
|
||||
import org.junit.internal.matchers.TypeSafeMatcher;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* ReaderAbstractTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: ReaderAbstractTest.java,v 1.0 04.01.12 09:40 haraldk Exp$
|
||||
*/
|
||||
public abstract class MetadataReaderAbstractTest {
|
||||
static {
|
||||
IIORegistry.getDefaultInstance().registerServiceProvider(new URLImageInputStreamSpi());
|
||||
}
|
||||
|
||||
protected final URL getResource(final String name) throws IOException {
|
||||
return getClass().getResource(name);
|
||||
}
|
||||
|
||||
protected final ImageInputStream getDataAsIIS() throws IOException {
|
||||
return ImageIO.createImageInputStream(getData());
|
||||
}
|
||||
|
||||
protected abstract InputStream getData() throws IOException;
|
||||
|
||||
protected abstract MetadataReader createReader();
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testReadNull() throws IOException {
|
||||
createReader().read(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead() throws IOException {
|
||||
Directory directory = createReader().read(getDataAsIIS());
|
||||
assertNotNull(directory);
|
||||
}
|
||||
|
||||
protected final Matcher<Entry> hasValue(final Object value) {
|
||||
return new EntryHasValue(value);
|
||||
}
|
||||
|
||||
private static class EntryHasValue extends TypeSafeMatcher<Entry> {
|
||||
private final Object value;
|
||||
|
||||
public EntryHasValue(final Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesSafely(final Entry entry) {
|
||||
return entry != null && (value == null ? entry.getValue() == null : valueEquals(value, entry.getValue()));
|
||||
}
|
||||
|
||||
private static boolean valueEquals(final Object expected, final Object actual) {
|
||||
return expected.getClass().isArray() ? arrayEquals(expected, actual) : expected.equals(actual);
|
||||
}
|
||||
|
||||
private static boolean arrayEquals(final Object expected, final Object actual) {
|
||||
Class<?> componentType = expected.getClass().getComponentType();
|
||||
|
||||
if (actual == null || !actual.getClass().isArray() || actual.getClass().getComponentType() != componentType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return componentType.isPrimitive() ? primitiveArrayEquals(componentType, expected, actual) : Arrays.equals((Object[]) expected, (Object[]) actual);
|
||||
}
|
||||
|
||||
private static boolean primitiveArrayEquals(Class<?> componentType, Object expected, Object actual) {
|
||||
if (componentType == boolean.class) {
|
||||
return Arrays.equals((boolean[]) expected, (boolean[]) actual);
|
||||
}
|
||||
else if (componentType == byte.class) {
|
||||
return Arrays.equals((byte[]) expected, (byte[]) actual);
|
||||
}
|
||||
else if (componentType == char.class) {
|
||||
return Arrays.equals((char[]) expected, (char[]) actual);
|
||||
}
|
||||
else if (componentType == double.class) {
|
||||
return Arrays.equals((double[]) expected, (double[]) actual);
|
||||
}
|
||||
else if (componentType == float.class) {
|
||||
return Arrays.equals((float[]) expected, (float[]) actual);
|
||||
}
|
||||
else if (componentType == int.class) {
|
||||
return Arrays.equals((int[]) expected, (int[]) actual);
|
||||
}
|
||||
else if (componentType == long.class) {
|
||||
return Arrays.equals((long[]) expected, (long[]) actual);
|
||||
}
|
||||
else if (componentType == short.class) {
|
||||
return Arrays.equals((short[]) expected, (short[]) actual);
|
||||
}
|
||||
|
||||
throw new AssertionError("Unsupported type:" + componentType);
|
||||
}
|
||||
|
||||
public void describeTo(final Description description) {
|
||||
description.appendText("has value ");
|
||||
description.appendValue(value);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.exif;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.CompoundDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.CompoundDirectoryAbstractTest;
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* EXIFDirectoryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: EXIFDirectoryTest.java,v 1.0 02.01.12 16:41 haraldk Exp$
|
||||
*/
|
||||
public class EXIFDirectoryTest extends CompoundDirectoryAbstractTest {
|
||||
@Override
|
||||
protected CompoundDirectory createCompoundDirectory(Collection<Directory> directories) {
|
||||
return new EXIFDirectory(directories);
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.exif;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.EntryAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* EXIFEntryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: EXIFEntryTest.java,v 1.0 02.01.12 17:35 haraldk Exp$
|
||||
*/
|
||||
public class EXIFEntryTest extends EntryAbstractTest {
|
||||
@Override
|
||||
protected Entry createEntry(final Object value) {
|
||||
return createEXIFEntry(TIFF.TAG_COPYRIGHT, value, (short) 2);
|
||||
}
|
||||
|
||||
private EXIFEntry createEXIFEntry(final int identifier, final Object value, final int type) {
|
||||
return new EXIFEntry(identifier, value, (short) type);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateEXIFEntryIllegalType() {
|
||||
createEXIFEntry(0, null, -1);
|
||||
}
|
||||
|
||||
// TODO: TIFF/EXIF specific tests
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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.exif;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.CompoundDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReaderAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* EXIFReaderTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: EXIFReaderTest.java,v 1.0 23.12.11 13:50 haraldk Exp$
|
||||
*/
|
||||
public class EXIFReaderTest extends MetadataReaderAbstractTest {
|
||||
@Override
|
||||
protected InputStream getData() throws IOException {
|
||||
return getResource("/exif/exif-jpeg-segment.bin").openStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EXIFReader createReader() {
|
||||
return new EXIFReader();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsCompoundDirectory() throws IOException {
|
||||
Directory exif = createReader().read(getDataAsIIS());
|
||||
assertThat(exif, instanceOf(CompoundDirectory.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectory() throws IOException {
|
||||
CompoundDirectory exif = (CompoundDirectory) createReader().read(getDataAsIIS());
|
||||
|
||||
assertEquals(2, exif.directoryCount());
|
||||
assertNotNull(exif.getDirectory(0));
|
||||
assertNotNull(exif.getDirectory(1));
|
||||
assertEquals(exif.size(), exif.getDirectory(0).size() + exif.getDirectory(1).size());
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
public void testDirectoryOutOfBounds() throws IOException {
|
||||
InputStream data = getData();
|
||||
|
||||
CompoundDirectory exif = (CompoundDirectory) createReader().read(ImageIO.createImageInputStream(data));
|
||||
|
||||
assertEquals(2, exif.directoryCount());
|
||||
assertNotNull(exif.getDirectory(exif.directoryCount()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntries() throws IOException {
|
||||
CompoundDirectory exif = (CompoundDirectory) createReader().read(getDataAsIIS());
|
||||
|
||||
// From IFD0
|
||||
assertNotNull(exif.getEntryById(TIFF.TAG_SOFTWARE));
|
||||
assertEquals("Adobe Photoshop CS2 Macintosh", exif.getEntryById(TIFF.TAG_SOFTWARE).getValue());
|
||||
assertEquals(exif.getEntryById(TIFF.TAG_SOFTWARE), exif.getEntryByFieldName("Software"));
|
||||
|
||||
// From IFD1
|
||||
assertNotNull(exif.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT));
|
||||
assertEquals((long) 418, exif.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT).getValue());
|
||||
assertEquals(exif.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT), exif.getEntryByFieldName("JPEGInterchangeFormat"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIFD0() throws IOException {
|
||||
CompoundDirectory exif = (CompoundDirectory) createReader().read(getDataAsIIS());
|
||||
|
||||
Directory ifd0 = exif.getDirectory(0);
|
||||
assertNotNull(ifd0);
|
||||
|
||||
assertNotNull(ifd0.getEntryById(TIFF.TAG_IMAGE_WIDTH));
|
||||
assertEquals(3601, ifd0.getEntryById(TIFF.TAG_IMAGE_WIDTH).getValue());
|
||||
|
||||
assertNotNull(ifd0.getEntryById(TIFF.TAG_IMAGE_HEIGHT));
|
||||
assertEquals(4176, ifd0.getEntryById(TIFF.TAG_IMAGE_HEIGHT).getValue());
|
||||
|
||||
// Assert 'uncompressed' (there's no TIFF image here, really)
|
||||
assertNotNull(ifd0.getEntryById(TIFF.TAG_COMPRESSION));
|
||||
assertEquals(1, ifd0.getEntryById(TIFF.TAG_COMPRESSION).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIFD1() throws IOException {
|
||||
CompoundDirectory exif = (CompoundDirectory) createReader().read(getDataAsIIS());
|
||||
|
||||
Directory ifd1 = exif.getDirectory(1);
|
||||
assertNotNull(ifd1);
|
||||
|
||||
// Assert 'JPEG compression' (thumbnail only)
|
||||
assertNotNull(ifd1.getEntryById(TIFF.TAG_COMPRESSION));
|
||||
assertEquals(6, ifd1.getEntryById(TIFF.TAG_COMPRESSION).getValue());
|
||||
|
||||
assertNull(ifd1.getEntryById(TIFF.TAG_IMAGE_WIDTH));
|
||||
assertNull(ifd1.getEntryById(TIFF.TAG_IMAGE_HEIGHT));
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.exif;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.DirectoryAbstractTest;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* IFDTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: IFDTest.java,v 1.0 02.01.12 16:42 haraldk Exp$
|
||||
*/
|
||||
public class IFDTest extends DirectoryAbstractTest {
|
||||
@Override
|
||||
protected Directory createDirectory(final Collection<Entry> entries) {
|
||||
return new IFD(entries);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.exif;
|
||||
|
||||
import com.twelvemonkeys.lang.ObjectAbstractTestCase;
|
||||
|
||||
/**
|
||||
* UnknownTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: UnknownTest.java,v 1.0 03.01.12 17:21 haraldk Exp$
|
||||
*/
|
||||
public class UnknownTest extends ObjectAbstractTestCase {
|
||||
@Override
|
||||
protected Object makeObject() {
|
||||
return new Unknown((short) 42, 77, (long) (Math.random() * (long) Integer.MAX_VALUE));
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.iptc;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.DirectoryAbstractTest;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* IPTCDirectoryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: IPTCDirectoryTest.java,v 1.0 03.01.12 09:40 haraldk Exp$
|
||||
*/
|
||||
public class IPTCDirectoryTest extends DirectoryAbstractTest {
|
||||
@Override
|
||||
protected Directory createDirectory(final Collection<Entry> entries) {
|
||||
return new IPTCDirectory(entries);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.iptc;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.EntryAbstractTest;
|
||||
|
||||
/**
|
||||
* IPTCEntryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: IPTCEntryTest.java,v 1.0 03.01.12 09:39 haraldk Exp$
|
||||
*/
|
||||
public class IPTCEntryTest extends EntryAbstractTest {
|
||||
@Override
|
||||
protected Entry createEntry(Object value) {
|
||||
return new IPTCEntry(IPTC.TAG_BY_LINE, value);
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.iptc;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReaderAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* IPTCReaderTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: IPTCReaderTest.java,v 1.0 04.01.12 09:43 haraldk Exp$
|
||||
*/
|
||||
public class IPTCReaderTest extends MetadataReaderAbstractTest {
|
||||
@Override
|
||||
protected InputStream getData() throws IOException {
|
||||
return getResource("/iptc/iptc-jpeg-segment.bin").openStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IPTCReader createReader() {
|
||||
return new IPTCReader();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectoryContent() throws IOException {
|
||||
Directory directory = createReader().read(ImageIO.createImageInputStream(getData()));
|
||||
|
||||
assertEquals(4, directory.size());
|
||||
|
||||
assertThat(directory.getEntryById(IPTC.TAG_RECORD_VERSION), hasValue(2)); // Mandatory
|
||||
assertThat(directory.getEntryById(IPTC.TAG_CAPTION), hasValue("Picture 71146"));
|
||||
assertThat(directory.getEntryById(IPTC.TAG_DATE_CREATED), hasValue("20080701"));
|
||||
|
||||
// Weirdness: An undefined tag 2:56/0x0238 ??
|
||||
// Looks like it should be 2:60/TAG_TIME_CREATED, but doesn't match the time in the corresponding XMP/EXIF tags
|
||||
assertThat(directory.getEntryById(IPTC.APPLICATION_RECORD | 56), hasValue("155029+0100"));
|
||||
}
|
||||
}
|
@ -58,8 +58,6 @@ public class JPEGSegmentUtilTest {
|
||||
IIORegistry.getDefaultInstance().registerServiceProvider(new URLImageInputStreamSpi());
|
||||
}
|
||||
|
||||
// TODO: Test the JPEGSegment class?!
|
||||
|
||||
protected ImageInputStream getData(final String name) throws IOException {
|
||||
return ImageIO.createImageInputStream(getClass().getResource(name));
|
||||
}
|
||||
@ -97,7 +95,7 @@ public class JPEGSegmentUtilTest {
|
||||
|
||||
@Test
|
||||
public void testReadAPP13Photoshop() throws IOException {
|
||||
List<JPEGSegment> segments = JPEGSegmentUtil.readSegments(getData("/jpeg/ts_open_300dpi.jpg"), 0xFFED, "Photoshop 3.0");
|
||||
List<JPEGSegment> segments = JPEGSegmentUtil.readSegments(getData("/jpeg/ts_open_300dpi.jpg"), JPEG.APP13, "Photoshop 3.0");
|
||||
|
||||
assertEquals(1, segments.size());
|
||||
JPEGSegment segment = segments.get(0);
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.DirectoryAbstractTest;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* PhotoshopDirectoryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: PhotoshopDirectoryTest.java,v 1.0 04.01.12 12:01 haraldk Exp$
|
||||
*/
|
||||
public class PSDDirectoryTest extends DirectoryAbstractTest {
|
||||
@Override
|
||||
protected Directory createDirectory(final Collection<Entry> entries) {
|
||||
return new PSDDirectory(entries);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.EntryAbstractTest;
|
||||
|
||||
/**
|
||||
* PhotoshopEntryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: PhotoshopEntryTest.java,v 1.0 04.01.12 12:00 haraldk Exp$
|
||||
*/
|
||||
public class PSDEntryTest extends EntryAbstractTest {
|
||||
@Override
|
||||
protected Entry createEntry(final Object value) {
|
||||
return new PSDEntry(0x404, value);
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReaderAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* PhotoshopReaderTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: PhotoshopReaderTest.java,v 1.0 04.01.12 12:01 haraldk Exp$
|
||||
*/
|
||||
public class PSDReaderTest extends MetadataReaderAbstractTest {
|
||||
@Override
|
||||
protected InputStream getData() throws IOException {
|
||||
return getResource("/psd/psd-jpeg-segment.bin").openStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PSDReader createReader() {
|
||||
return new PSDReader();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPhotoshopDirectoryContents() throws IOException {
|
||||
Directory directory = createReader().read(getDataAsIIS());
|
||||
|
||||
assertEquals(23, directory.size());
|
||||
|
||||
assertNotNull(directory.getEntryById(0x0404));
|
||||
assertNotNull(directory.getEntryById(0x0425));
|
||||
assertNotNull(directory.getEntryById(0x03ea));
|
||||
assertNotNull(directory.getEntryById(0x03e9));
|
||||
assertNotNull(directory.getEntryById(0x03ed));
|
||||
assertNotNull(directory.getEntryById(0x0426));
|
||||
|
||||
// TODO: More
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.xmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.DirectoryAbstractTest;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* XMPDirectoryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: XMPDirectoryTest.java,v 1.0 03.01.12 09:42 haraldk Exp$
|
||||
*/
|
||||
public class RDFDescriptionTest extends DirectoryAbstractTest {
|
||||
@Override
|
||||
protected Directory createDirectory(final Collection<Entry> entries) {
|
||||
return new RDFDescription(entries);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.xmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.CompoundDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.CompoundDirectoryAbstractTest;
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* XMPDirectoryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: XMPDirectoryTest.java,v 1.0 03.01.12 09:42 haraldk Exp$
|
||||
*/
|
||||
public class XMPDirectoryTest extends CompoundDirectoryAbstractTest {
|
||||
@Override
|
||||
protected CompoundDirectory createCompoundDirectory(final Collection<Directory> directories) {
|
||||
return new XMPDirectory(directories, null);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.xmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.EntryAbstractTest;
|
||||
|
||||
/**
|
||||
* XMPEntryTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: XMPEntryTest.java,v 1.0 03.01.12 09:41 haraldk Exp$
|
||||
*/
|
||||
public class XMPEntryTest extends EntryAbstractTest {
|
||||
@Override
|
||||
protected Entry createEntry(Object value) {
|
||||
return new XMPEntry(XMP.NS_XAP + ":foo", value);
|
||||
}
|
||||
}
|
@ -0,0 +1,470 @@
|
||||
/*
|
||||
* 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.xmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.CompoundDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReaderAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* XMPReaderTest
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: XMPReaderTest.java,v 1.0 04.01.12 10:47 haraldk Exp$
|
||||
*/
|
||||
public class XMPReaderTest extends MetadataReaderAbstractTest {
|
||||
|
||||
@Override
|
||||
protected InputStream getData() throws IOException {
|
||||
return getResource("/xmp/xmp-jpeg-example.xml").openStream();
|
||||
}
|
||||
|
||||
private ImageInputStream getResourceAsIIS(final String name) throws IOException {
|
||||
return ImageIO.createImageInputStream(getResource(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XMPReader createReader() {
|
||||
return new XMPReader();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectoryContent() throws IOException {
|
||||
Directory directory = createReader().read(getDataAsIIS());
|
||||
|
||||
assertEquals(29, directory.size());
|
||||
|
||||
// photoshop|http://ns.adobe.com/photoshop/1.0/
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/photoshop/1.0/DateCreated"), hasValue("2008-07-01"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/photoshop/1.0/ColorMode"), hasValue("4"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/photoshop/1.0/ICCProfile"), hasValue("U.S. Web Coated (SWOP) v2"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/photoshop/1.0/History"), hasValue(""));
|
||||
|
||||
// xapMM|http://ns.adobe.com/xap/1.0/mm/
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/DocumentID"), hasValue("uuid:54A8D5F8654711DD9226A85E1241887A"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/InstanceID"), hasValue("uuid:54A8D5F9654711DD9226A85E1241887A"));
|
||||
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/DerivedFrom"), hasValue(
|
||||
new RDFDescription(Arrays.asList(
|
||||
// stRef|http://ns.adobe.com/xap/1.0/sType/ResourceRef#
|
||||
new XMPEntry("http://ns.adobe.com/xap/1.0/sType/ResourceRef#instanceID", "instanceID", "uuid:3B52F3610F49DD118831FCA29C13B8DE"),
|
||||
new XMPEntry("http://ns.adobe.com/xap/1.0/sType/ResourceRef#documentID", "documentID", "uuid:3A52F3610F49DD118831FCA29C13B8DE")
|
||||
))
|
||||
));
|
||||
|
||||
// dc|http://purl.org/dc/elements/1.1/
|
||||
assertThat(directory.getEntryById("http://purl.org/dc/elements/1.1/description"), hasValue(Collections.singletonMap("x-default", "Picture 71146")));
|
||||
assertThat(directory.getEntryById("http://purl.org/dc/elements/1.1/format"), hasValue("image/jpeg"));
|
||||
|
||||
// tiff|http://ns.adobe.com/tiff/1.0/
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/ImageWidth"), hasValue("3601"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/ImageLength"), hasValue("4176"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/BitsPerSample"), hasValue(Arrays.asList("8", "8", "8")));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/Compression"), hasValue("1"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/PhotometricInterpretation"), hasValue("2"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/SamplesPerPixel"), hasValue("3"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/PlanarConfiguration"), hasValue("1"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/XResolution"), hasValue("3000000/10000"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/YResolution"), hasValue("3000000/10000"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/ResolutionUnit"), hasValue("2"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/Orientation"), hasValue("1"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/NativeDigest"), hasValue("256,257,258,259,262,274,277,284,530,531,282,283,296,301,318,319,529,532,306,270,271,272,305,315,33432;C21EE6D33E4CCA3712ECB1F5E9031A49"));
|
||||
|
||||
// xap|http://ns.adobe.com/xap/1.0/
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/ModifyDate"), hasValue("2008-08-06T12:43:05+10:00"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/CreatorTool"), hasValue("Adobe Photoshop CS2 Macintosh"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/CreateDate"), hasValue("2008-08-06T12:43:05+10:00"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/MetadataDate"), hasValue("2008-08-06T12:43:05+10:00"));
|
||||
|
||||
// exif|http://ns.adobe.com/exif/1.0/
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/exif/1.0/ColorSpace"), hasValue("-1")); // SIC
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/exif/1.0/PixelXDimension"), hasValue("3601"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/exif/1.0/PixelYDimension"), hasValue("4176"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/exif/1.0/NativeDigest"), hasValue("36864,40960,40961,37121,37122,40962,40963,37510,40964,36867,36868,33434,33437,34850,34852,34855,34856,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37396,41483,41484,41486,41487,41488,41492,41493,41495,41728,41729,41730,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,42016,0,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,23,24,25,26,27,28,30;297AD344CC15F29D5283460ED026368F"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompoundDirectory() throws IOException {
|
||||
Directory directory = createReader().read(getDataAsIIS());
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
assertEquals(6, compound.directoryCount());
|
||||
|
||||
int size = 0;
|
||||
for (int i = 0; i < compound.directoryCount(); i++) {
|
||||
Directory sub = compound.getDirectory(i);
|
||||
assertNotNull(sub);
|
||||
size += sub.size();
|
||||
}
|
||||
|
||||
assertEquals(directory.size(), size);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompoundDirectoryContentPhotoshop() throws IOException {
|
||||
Directory directory = createReader().read(getDataAsIIS());
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// photoshop|http://ns.adobe.com/photoshop/1.0/
|
||||
Directory photoshop = compound.getDirectory(0);
|
||||
assertEquals(4, photoshop.size());
|
||||
assertThat(photoshop.getEntryById("http://ns.adobe.com/photoshop/1.0/DateCreated"), hasValue("2008-07-01"));
|
||||
assertThat(photoshop.getEntryById("http://ns.adobe.com/photoshop/1.0/ColorMode"), hasValue("4"));
|
||||
assertThat(photoshop.getEntryById("http://ns.adobe.com/photoshop/1.0/ICCProfile"), hasValue("U.S. Web Coated (SWOP) v2"));
|
||||
assertThat(photoshop.getEntryById("http://ns.adobe.com/photoshop/1.0/History"), hasValue(""));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompoundDirectoryContentMM() throws IOException {
|
||||
Directory directory = createReader().read(getDataAsIIS());
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// xapMM|http://ns.adobe.com/xap/1.0/mm/
|
||||
Directory mm = compound.getDirectory(1);
|
||||
assertEquals(3, mm.size());
|
||||
assertThat(mm.getEntryById("http://ns.adobe.com/xap/1.0/mm/DocumentID"), hasValue("uuid:54A8D5F8654711DD9226A85E1241887A"));
|
||||
assertThat(mm.getEntryById("http://ns.adobe.com/xap/1.0/mm/InstanceID"), hasValue("uuid:54A8D5F9654711DD9226A85E1241887A"));
|
||||
assertThat(mm.getEntryById("http://ns.adobe.com/xap/1.0/mm/DerivedFrom"), hasValue(
|
||||
new RDFDescription(Arrays.asList(
|
||||
// stRef|http://ns.adobe.com/xap/1.0/sType/ResourceRef#
|
||||
new XMPEntry("http://ns.adobe.com/xap/1.0/sType/ResourceRef#instanceID", "instanceID", "uuid:3B52F3610F49DD118831FCA29C13B8DE"),
|
||||
new XMPEntry("http://ns.adobe.com/xap/1.0/sType/ResourceRef#documentID", "documentID", "uuid:3A52F3610F49DD118831FCA29C13B8DE")
|
||||
))
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompoundDirectoryContentDC() throws IOException {
|
||||
Directory directory = createReader().read(getDataAsIIS());
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// dc|http://purl.org/dc/elements/1.1/
|
||||
Directory dc = compound.getDirectory(2);
|
||||
assertEquals(2, dc.size());
|
||||
assertThat(dc.getEntryById("http://purl.org/dc/elements/1.1/description"), hasValue(Collections.singletonMap("x-default", "Picture 71146")));
|
||||
assertThat(dc.getEntryById("http://purl.org/dc/elements/1.1/format"), hasValue("image/jpeg"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompoundDirectoryContentTIFF() throws IOException {
|
||||
Directory directory = createReader().read(getDataAsIIS());
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// tiff|http://ns.adobe.com/tiff/1.0/
|
||||
Directory tiff = compound.getDirectory(3);
|
||||
assertEquals(12, tiff.size());
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/ImageWidth"), hasValue("3601"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/ImageLength"), hasValue("4176"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/BitsPerSample"), hasValue(Arrays.asList("8", "8", "8")));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/Compression"), hasValue("1"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/PhotometricInterpretation"), hasValue("2"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/SamplesPerPixel"), hasValue("3"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/PlanarConfiguration"), hasValue("1"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/XResolution"), hasValue("3000000/10000"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/YResolution"), hasValue("3000000/10000"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/ResolutionUnit"), hasValue("2"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/Orientation"), hasValue("1"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/NativeDigest"), hasValue("256,257,258,259,262,274,277,284,530,531,282,283,296,301,318,319,529,532,306,270,271,272,305,315,33432;C21EE6D33E4CCA3712ECB1F5E9031A49"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompoundDirectoryContentXAP() throws IOException {
|
||||
Directory directory = createReader().read(getDataAsIIS());
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// xap|http://ns.adobe.com/xap/1.0/
|
||||
Directory xap = compound.getDirectory(4);
|
||||
assertEquals(4, xap.size());
|
||||
assertThat(xap.getEntryById("http://ns.adobe.com/xap/1.0/ModifyDate"), hasValue("2008-08-06T12:43:05+10:00"));
|
||||
assertThat(xap.getEntryById("http://ns.adobe.com/xap/1.0/CreatorTool"), hasValue("Adobe Photoshop CS2 Macintosh"));
|
||||
assertThat(xap.getEntryById("http://ns.adobe.com/xap/1.0/CreateDate"), hasValue("2008-08-06T12:43:05+10:00"));
|
||||
assertThat(xap.getEntryById("http://ns.adobe.com/xap/1.0/MetadataDate"), hasValue("2008-08-06T12:43:05+10:00"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompoundDirectoryContentEXIF() throws IOException {
|
||||
Directory directory = createReader().read(getDataAsIIS());
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// exif|http://ns.adobe.com/exif/1.0/
|
||||
Directory exif = compound.getDirectory(5);
|
||||
assertEquals(4, exif.size());
|
||||
assertThat(exif.getEntryById("http://ns.adobe.com/exif/1.0/ColorSpace"), hasValue("-1")); // SIC. Same as unsigned short 65535, meaning "uncalibrated"?
|
||||
assertThat(exif.getEntryById("http://ns.adobe.com/exif/1.0/PixelXDimension"), hasValue("3601"));
|
||||
assertThat(exif.getEntryById("http://ns.adobe.com/exif/1.0/PixelYDimension"), hasValue("4176"));
|
||||
assertThat(exif.getEntryById("http://ns.adobe.com/exif/1.0/NativeDigest"), hasValue("36864,40960,40961,37121,37122,40962,40963,37510,40964,36867,36868,33434,33437,34850,34852,34855,34856,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37396,41483,41484,41486,41487,41488,41492,41493,41495,41728,41729,41730,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,42016,0,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,23,24,25,26,27,28,30;297AD344CC15F29D5283460ED026368F"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFBag() throws IOException {
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-bag-example.xml"));
|
||||
|
||||
assertEquals(1, directory.size());
|
||||
assertThat(directory.getEntryById("http://purl.org/dc/elements/1.1/subject"), hasValue(Arrays.asList("XMP", "metadata", "ISO standard"))); // Order does not matter
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFSeq() throws IOException {
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-seq-example.xml"));
|
||||
|
||||
assertEquals(1, directory.size());
|
||||
assertThat(directory.getEntryById("http://purl.org/dc/elements/1.1/subject"), hasValue(Arrays.asList("XMP", "metadata", "ISO standard")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFAlt() throws IOException {
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-alt-example.xml"));
|
||||
|
||||
assertEquals(1, directory.size());
|
||||
assertThat(directory.getEntryById("http://purl.org/dc/elements/1.1/subject"), hasValue(new HashMap<String, String>() {{
|
||||
put("x-default", "One");
|
||||
put("en-us", "One");
|
||||
put("de", "Ein");
|
||||
put("no-nb", "En");
|
||||
}}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFAttributeSyntax() throws IOException {
|
||||
// Alternate RDF syntax, using attribute values instead of nested tags
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-attribute-shorthand.xml"));
|
||||
|
||||
assertEquals(20, directory.size());
|
||||
|
||||
// dc|http://purl.org/dc/elements/1.1/
|
||||
assertThat(directory.getEntryById("http://purl.org/dc/elements/1.1/format"), hasValue("image/jpeg"));
|
||||
|
||||
// xap|http://ns.adobe.com/xap/1.0/
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/ModifyDate"), hasValue("2008-07-16T14:44:49-07:00"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/CreatorTool"), hasValue("Adobe Photoshop CS3 Windows"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/CreateDate"), hasValue("2008-07-16T14:44:49-07:00"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/MetadataDate"), hasValue("2008-07-16T14:44:49-07:00"));
|
||||
|
||||
// tiff|http://ns.adobe.com/tiff/1.0/
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/Orientation"), hasValue("1"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/XResolution"), hasValue("720000/10000"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/YResolution"), hasValue("720000/10000"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/ResolutionUnit"), hasValue("2"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/tiff/1.0/NativeDigest"), hasValue("256,257,258,259,262,274,277,284,530,531,282,283,296,301,318,319,529,532,306,270,271,272,305,315,33432;C08D8E93274C4BEE83E86CF999955A87"));
|
||||
|
||||
// exif|http://ns.adobe.com/exif/1.0/
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/exif/1.0/ColorSpace"), hasValue("-1")); // SIC. Same as unsigned short 65535, meaning "uncalibrated"?
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/exif/1.0/PixelXDimension"), hasValue("426"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/exif/1.0/PixelYDimension"), hasValue("550"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/exif/1.0/NativeDigest"), hasValue("36864,40960,40961,37121,37122,40962,40963,37510,40964,36867,36868,33434,33437,34850,34852,34855,34856,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37396,41483,41484,41486,41487,41488,41492,41493,41495,41728,41729,41730,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,42016,0,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,23,24,25,26,27,28,30;A7F21D25E2C562F152B2C4ECC9E534DA"));
|
||||
|
||||
// photoshop|http://ns.adobe.com/photoshop/1.0/
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/photoshop/1.0/ColorMode"), hasValue("1"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/photoshop/1.0/ICCProfile"), hasValue("Dot Gain 20%"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/photoshop/1.0/History"), hasValue(""));
|
||||
|
||||
// xapMM|http://ns.adobe.com/xap/1.0/mm/
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/DocumentID"), hasValue("uuid:6DCA50CC7D53DD119F20F5A7EA4C9BEC"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/InstanceID"), hasValue("uuid:6ECA50CC7D53DD119F20F5A7EA4C9BEC"));
|
||||
|
||||
// Custom test, as NamedNodeMap does not preserve order (tests can't rely on XML impl specifics)
|
||||
Entry derivedFrom = directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/DerivedFrom");
|
||||
assertNotNull(derivedFrom);
|
||||
assertThat(derivedFrom.getValue(), instanceOf(RDFDescription.class));
|
||||
|
||||
// stRef|http://ns.adobe.com/xap/1.0/sType/ResourceRef#
|
||||
RDFDescription stRef = (RDFDescription) derivedFrom.getValue();
|
||||
assertThat(stRef.getEntryById("http://ns.adobe.com/xap/1.0/sType/ResourceRef#instanceID"), hasValue("uuid:74E1C905B405DD119306A1902BA5AA28"));
|
||||
assertThat(stRef.getEntryById("http://ns.adobe.com/xap/1.0/sType/ResourceRef#documentID"), hasValue("uuid:7A6C79768005DD119306A1902BA5AA28"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFAttributeSyntaxCompound() throws IOException {
|
||||
// Alternate RDF syntax, using attribute values instead of nested tags
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-attribute-shorthand.xml"));
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
assertEquals(6, compound.directoryCount());
|
||||
|
||||
int size = 0;
|
||||
for (int i = 0; i < compound.directoryCount(); i++) {
|
||||
Directory sub = compound.getDirectory(i);
|
||||
assertNotNull(sub);
|
||||
size += sub.size();
|
||||
}
|
||||
|
||||
assertEquals(directory.size(), size);
|
||||
}
|
||||
|
||||
private Directory getDirectoryByNS(final CompoundDirectory compound, final String namespace) {
|
||||
for (int i = 0; i < compound.directoryCount(); i++) {
|
||||
Directory candidate = compound.getDirectory(i);
|
||||
|
||||
Iterator<Entry> entries = candidate.iterator();
|
||||
if (entries.hasNext()) {
|
||||
Entry entry = entries.next();
|
||||
if (entry.getIdentifier() instanceof String && ((String) entry.getIdentifier()).startsWith(namespace)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFAttributeSyntaxCompoundDirectoryContentPhotoshop() throws IOException {
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-attribute-shorthand.xml"));
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// photoshop|http://ns.adobe.com/photoshop/1.0/
|
||||
Directory photoshop = getDirectoryByNS(compound, XMP.NS_PHOTOSHOP);
|
||||
|
||||
assertEquals(3, photoshop.size());
|
||||
assertThat(photoshop.getEntryById("http://ns.adobe.com/photoshop/1.0/ColorMode"), hasValue("1"));
|
||||
assertThat(photoshop.getEntryById("http://ns.adobe.com/photoshop/1.0/ICCProfile"), hasValue("Dot Gain 20%"));
|
||||
assertThat(photoshop.getEntryById("http://ns.adobe.com/photoshop/1.0/History"), hasValue(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFAttributeSyntaxCompoundDirectoryContentMM() throws IOException {
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-attribute-shorthand.xml"));
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// xapMM|http://ns.adobe.com/xap/1.0/mm/
|
||||
Directory mm = getDirectoryByNS(compound, XMP.NS_XAP_MM);
|
||||
assertEquals(3, mm.size());
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/DocumentID"), hasValue("uuid:6DCA50CC7D53DD119F20F5A7EA4C9BEC"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/InstanceID"), hasValue("uuid:6ECA50CC7D53DD119F20F5A7EA4C9BEC"));
|
||||
|
||||
// Custom test, as NamedNodeMap does not preserve order (tests can't rely on XML impl specifics)
|
||||
Entry derivedFrom = directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/DerivedFrom");
|
||||
assertNotNull(derivedFrom);
|
||||
assertThat(derivedFrom.getValue(), instanceOf(RDFDescription.class));
|
||||
|
||||
// stRef|http://ns.adobe.com/xap/1.0/sType/ResourceRef#
|
||||
RDFDescription stRef = (RDFDescription) derivedFrom.getValue();
|
||||
assertThat(stRef.getEntryById("http://ns.adobe.com/xap/1.0/sType/ResourceRef#instanceID"), hasValue("uuid:74E1C905B405DD119306A1902BA5AA28"));
|
||||
assertThat(stRef.getEntryById("http://ns.adobe.com/xap/1.0/sType/ResourceRef#documentID"), hasValue("uuid:7A6C79768005DD119306A1902BA5AA28"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFAttributeSyntaxCompoundDirectoryContentDC() throws IOException {
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-attribute-shorthand.xml"));
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// dc|http://purl.org/dc/elements/1.1/
|
||||
Directory dc = getDirectoryByNS(compound, XMP.NS_DC);
|
||||
assertEquals(1, dc.size());
|
||||
|
||||
assertThat(dc.getEntryById("http://purl.org/dc/elements/1.1/format"), hasValue("image/jpeg"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFAttributeSyntaxCompoundDirectoryContentTIFF() throws IOException {
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-attribute-shorthand.xml"));
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// tiff|http://ns.adobe.com/tiff/1.0/
|
||||
Directory tiff = getDirectoryByNS(compound, XMP.NS_TIFF);
|
||||
assertEquals(5, tiff.size());
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/Orientation"), hasValue("1"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/XResolution"), hasValue("720000/10000"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/YResolution"), hasValue("720000/10000"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/ResolutionUnit"), hasValue("2"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/NativeDigest"), hasValue("256,257,258,259,262,274,277,284,530,531,282,283,296,301,318,319,529,532,306,270,271,272,305,315,33432;C08D8E93274C4BEE83E86CF999955A87"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFAttributeSyntaxCompoundDirectoryContentXAP() throws IOException {
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-attribute-shorthand.xml"));
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// xap|http://ns.adobe.com/xap/1.0/
|
||||
Directory xap = getDirectoryByNS(compound, XMP.NS_XAP);
|
||||
assertEquals(4, xap.size());
|
||||
assertThat(xap.getEntryById("http://ns.adobe.com/xap/1.0/ModifyDate"), hasValue("2008-07-16T14:44:49-07:00"));
|
||||
assertThat(xap.getEntryById("http://ns.adobe.com/xap/1.0/CreatorTool"), hasValue("Adobe Photoshop CS3 Windows"));
|
||||
assertThat(xap.getEntryById("http://ns.adobe.com/xap/1.0/CreateDate"), hasValue("2008-07-16T14:44:49-07:00"));
|
||||
assertThat(xap.getEntryById("http://ns.adobe.com/xap/1.0/MetadataDate"), hasValue("2008-07-16T14:44:49-07:00"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRDFAttributeSyntaxCompoundDirectoryContentEXIF() throws IOException {
|
||||
Directory directory = createReader().read(getResourceAsIIS("/xmp/rdf-attribute-shorthand.xml"));
|
||||
|
||||
assertThat(directory, instanceOf(CompoundDirectory.class));
|
||||
CompoundDirectory compound = (CompoundDirectory) directory;
|
||||
|
||||
// exif|http://ns.adobe.com/exif/1.0/
|
||||
Directory exif = getDirectoryByNS(compound, XMP.NS_EXIF);
|
||||
assertEquals(4, exif.size());
|
||||
assertThat(exif.getEntryById("http://ns.adobe.com/exif/1.0/ColorSpace"), hasValue("-1")); // SIC. Same as unsigned short 65535, meaning "uncalibrated"?
|
||||
assertThat(exif.getEntryById("http://ns.adobe.com/exif/1.0/PixelXDimension"), hasValue("426"));
|
||||
assertThat(exif.getEntryById("http://ns.adobe.com/exif/1.0/PixelYDimension"), hasValue("550"));
|
||||
assertThat(exif.getEntryById("http://ns.adobe.com/exif/1.0/NativeDigest"), hasValue("36864,40960,40961,37121,37122,40962,40963,37510,40964,36867,36868,33434,33437,34850,34852,34855,34856,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37396,41483,41484,41486,41487,41488,41492,41493,41495,41728,41729,41730,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,42016,0,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,23,24,25,26,27,28,30;A7F21D25E2C562F152B2C4ECC9E534DA"));
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.twelvemonkeys.imageio.metadata.xmp;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
@ -8,6 +8,8 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* XMPScannerTestCase
|
||||
*
|
||||
@ -15,8 +17,7 @@ import java.util.Random;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: XMPScannerTestCase.java,v 1.0 Nov 13, 2009 3:59:43 PM haraldk Exp$
|
||||
*/
|
||||
public class XMPScannerTestCase extends TestCase {
|
||||
|
||||
public class XMPScannerTestCase {
|
||||
static final String XMP =
|
||||
"<?xpacket begin=\"\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>" +
|
||||
"<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 4.1-c036 46.276720, Fri Nov 13 2009 15:59:43 \">\n"+
|
||||
@ -33,11 +34,11 @@ public class XMPScannerTestCase extends TestCase {
|
||||
"</x:xmpmeta>" +
|
||||
"<?xpacket end=\"w\"?>";
|
||||
|
||||
final Random mRandom = new Random(4934638567l);
|
||||
final Random random = new Random(4934638567l);
|
||||
|
||||
private InputStream createRandomStream(final int pLength) {
|
||||
byte[] bytes = new byte[pLength];
|
||||
mRandom.nextBytes(bytes);
|
||||
random.nextBytes(bytes);
|
||||
return new ByteArrayInputStream(bytes);
|
||||
}
|
||||
|
||||
@ -60,6 +61,7 @@ public class XMPScannerTestCase extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanForUTF8() throws IOException {
|
||||
InputStream stream = createXMPStream(XMP, "UTF-8");
|
||||
|
||||
@ -68,7 +70,8 @@ public class XMPScannerTestCase extends TestCase {
|
||||
assertNotNull(reader);
|
||||
}
|
||||
|
||||
public void testScanForUTF8singleQuote() throws IOException {
|
||||
@Test
|
||||
public void testScanForUTF8SingleQuote() throws IOException {
|
||||
InputStream stream = createXMPStream(XMP.replace("\"", "'"), "UTF-8");
|
||||
|
||||
Reader reader = XMPScanner.scanForXMPPacket(stream);
|
||||
@ -76,6 +79,7 @@ public class XMPScannerTestCase extends TestCase {
|
||||
assertNotNull(reader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanForUTF16BE() throws IOException {
|
||||
InputStream stream = createXMPStream(XMP, "UTF-16BE");
|
||||
|
||||
@ -84,7 +88,8 @@ public class XMPScannerTestCase extends TestCase {
|
||||
assertNotNull(reader);
|
||||
}
|
||||
|
||||
public void testScanForUTF16BEsingleQuote() throws IOException {
|
||||
@Test
|
||||
public void testScanForUTF16BESingleQuote() throws IOException {
|
||||
InputStream stream = createXMPStream(XMP.replace("\"", "'"), "UTF-16BE");
|
||||
|
||||
Reader reader = XMPScanner.scanForXMPPacket(stream);
|
||||
@ -92,6 +97,7 @@ public class XMPScannerTestCase extends TestCase {
|
||||
assertNotNull(reader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanForUTF16LE() throws IOException {
|
||||
InputStream stream = createXMPStream(XMP, "UTF-16LE");
|
||||
|
||||
@ -100,7 +106,8 @@ public class XMPScannerTestCase extends TestCase {
|
||||
assertNotNull(reader);
|
||||
}
|
||||
|
||||
public void testScanForUTF16LEsingleQuote() throws IOException {
|
||||
@Test
|
||||
public void testScanForUTF16LESingleQuote() throws IOException {
|
||||
InputStream stream = createXMPStream(XMP.replace("\"", "'"), "UTF-16LE");
|
||||
|
||||
Reader reader = XMPScanner.scanForXMPPacket(stream);
|
||||
@ -108,20 +115,31 @@ public class XMPScannerTestCase extends TestCase {
|
||||
assertNotNull(reader);
|
||||
}
|
||||
|
||||
// TODO: Default Java installation on OS X don't seem to have UTF-32 installed. Hmmm..
|
||||
// public void testUTF32BE() throws IOException {
|
||||
// InputStream stream = createXMPStream("UTF-32BE");
|
||||
//
|
||||
// Reader reader = XMPScanner.scanForXMPPacket(stream);
|
||||
//
|
||||
// assertNotNull(reader);
|
||||
// }
|
||||
//
|
||||
// public void testUTF32LE() throws IOException {
|
||||
// InputStream stream = createXMPStream("UTF-32LE");
|
||||
//
|
||||
// Reader reader = XMPScanner.scanForXMPPacket(stream);
|
||||
//
|
||||
// assertNotNull(reader);
|
||||
// }
|
||||
@Test
|
||||
public void testUTF32BE() throws IOException {
|
||||
try {
|
||||
InputStream stream = createXMPStream(XMP, "UTF-32BE");
|
||||
|
||||
Reader reader = XMPScanner.scanForXMPPacket(stream);
|
||||
|
||||
assertNotNull(reader);
|
||||
}
|
||||
catch (UnsupportedCharsetException ignore) {
|
||||
System.err.println("Warning: Unsupported charset. Test skipped. " + ignore);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUTF32LE() throws IOException {
|
||||
try {
|
||||
InputStream stream = createXMPStream(XMP, "UTF-32LE");
|
||||
|
||||
Reader reader = XMPScanner.scanForXMPPacket(stream);
|
||||
|
||||
assertNotNull(reader);
|
||||
}
|
||||
catch (UnsupportedCharsetException ignore) {
|
||||
System.err.println("Warning: Unsupported charset. Test skipped. " + ignore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<rdf:Description rdf:about="">
|
||||
<dc:subject>
|
||||
<rdf:Alt>
|
||||
<rdf:li xml:lang="x-default">One</rdf:li>
|
||||
<rdf:li xml:lang="en-us">One</rdf:li>
|
||||
<rdf:li xml:lang="de">Ein</rdf:li>
|
||||
<rdf:li xml:lang="no-nb">En</rdf:li>
|
||||
</rdf:Alt>
|
||||
</dc:subject>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.1-c036 46.276720, Mon Feb 19 2007 22:40:08 ">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:xap="http://ns.adobe.com/xap/1.0/" xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
|
||||
xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
|
||||
xmlns:tiff="http://ns.adobe.com/tiff/1.0/" xmlns:exif="http://ns.adobe.com/exif/1.0/"
|
||||
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
|
||||
dc:format="image/jpeg"
|
||||
xap:CreatorTool="Adobe Photoshop CS3 Windows"
|
||||
xap:CreateDate="2008-07-16T14:44:49-07:00"
|
||||
xap:ModifyDate="2008-07-16T14:44:49-07:00"
|
||||
xap:MetadataDate="2008-07-16T14:44:49-07:00"
|
||||
xapMM:DocumentID="uuid:6DCA50CC7D53DD119F20F5A7EA4C9BEC"
|
||||
xapMM:InstanceID="uuid:6ECA50CC7D53DD119F20F5A7EA4C9BEC"
|
||||
tiff:Orientation="1"
|
||||
tiff:XResolution="720000/10000"
|
||||
tiff:YResolution="720000/10000"
|
||||
tiff:ResolutionUnit="2"
|
||||
tiff:NativeDigest="256,257,258,259,262,274,277,284,530,531,282,283,296,301,318,319,529,532,306,270,271,272,305,315,33432;C08D8E93274C4BEE83E86CF999955A87"
|
||||
exif:PixelXDimension="426"
|
||||
exif:PixelYDimension="550"
|
||||
exif:ColorSpace="-1"
|
||||
exif:NativeDigest="36864,40960,40961,37121,37122,40962,40963,37510,40964,36867,36868,33434,33437,34850,34852,34855,34856,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37396,41483,41484,41486,41487,41488,41492,41493,41495,41728,41729,41730,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,42016,0,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,23,24,25,26,27,28,30;A7F21D25E2C562F152B2C4ECC9E534DA"
|
||||
photoshop:ColorMode="1"
|
||||
photoshop:ICCProfile="Dot Gain 20%"
|
||||
photoshop:History="">
|
||||
<xapMM:DerivedFrom stRef:instanceID="uuid:74E1C905B405DD119306A1902BA5AA28"
|
||||
stRef:documentID="uuid:7A6C79768005DD119306A1902BA5AA28"/>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<rdf:Description rdf:about="">
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>XMP</rdf:li>
|
||||
<rdf:li>metadata</rdf:li>
|
||||
<rdf:li>ISO standard</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<rdf:Description rdf:about="">
|
||||
<dc:subject>
|
||||
<rdf:Seq>
|
||||
<rdf:li>XMP</rdf:li>
|
||||
<rdf:li>metadata</rdf:li>
|
||||
<rdf:li>ISO standard</rdf:li>
|
||||
</rdf:Seq>
|
||||
</dc:subject>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
@ -0,0 +1,187 @@
|
||||
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="3.1.1-111">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
||||
<photoshop:DateCreated>2008-07-01</photoshop:DateCreated>
|
||||
<photoshop:ColorMode>4</photoshop:ColorMode>
|
||||
<photoshop:ICCProfile>U.S. Web Coated (SWOP) v2</photoshop:ICCProfile>
|
||||
<photoshop:History/>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
|
||||
xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#">
|
||||
<xapMM:DocumentID>uuid:54A8D5F8654711DD9226A85E1241887A</xapMM:DocumentID>
|
||||
<xapMM:InstanceID>uuid:54A8D5F9654711DD9226A85E1241887A</xapMM:InstanceID>
|
||||
<xapMM:DerivedFrom rdf:parseType="Resource">
|
||||
<stRef:instanceID>uuid:3B52F3610F49DD118831FCA29C13B8DE</stRef:instanceID>
|
||||
<stRef:documentID>uuid:3A52F3610F49DD118831FCA29C13B8DE</stRef:documentID>
|
||||
</xapMM:DerivedFrom>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<dc:description>
|
||||
<rdf:Alt>
|
||||
<rdf:li xml:lang="x-default">Picture 71146</rdf:li>
|
||||
</rdf:Alt>
|
||||
</dc:description>
|
||||
<dc:format>image/jpeg</dc:format>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:tiff="http://ns.adobe.com/tiff/1.0/">
|
||||
<tiff:ImageWidth>3601</tiff:ImageWidth>
|
||||
<tiff:ImageLength>4176</tiff:ImageLength>
|
||||
<tiff:BitsPerSample>
|
||||
<rdf:Seq>
|
||||
<rdf:li>8</rdf:li>
|
||||
<rdf:li>8</rdf:li>
|
||||
<rdf:li>8</rdf:li>
|
||||
</rdf:Seq>
|
||||
</tiff:BitsPerSample>
|
||||
<tiff:Compression>1</tiff:Compression>
|
||||
<tiff:PhotometricInterpretation>2</tiff:PhotometricInterpretation>
|
||||
<tiff:SamplesPerPixel>3</tiff:SamplesPerPixel>
|
||||
<tiff:PlanarConfiguration>1</tiff:PlanarConfiguration>
|
||||
<tiff:XResolution>3000000/10000</tiff:XResolution>
|
||||
<tiff:YResolution>3000000/10000</tiff:YResolution>
|
||||
<tiff:ResolutionUnit>2</tiff:ResolutionUnit>
|
||||
<tiff:Orientation>1</tiff:Orientation>
|
||||
<tiff:NativeDigest>256,257,258,259,262,274,277,284,530,531,282,283,296,301,318,319,529,532,306,270,271,272,305,315,33432;C21EE6D33E4CCA3712ECB1F5E9031A49</tiff:NativeDigest>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:xap="http://ns.adobe.com/xap/1.0/">
|
||||
<xap:ModifyDate>2008-08-06T12:43:05+10:00</xap:ModifyDate>
|
||||
<xap:CreatorTool>Adobe Photoshop CS2 Macintosh</xap:CreatorTool>
|
||||
<xap:CreateDate>2008-08-06T12:43:05+10:00</xap:CreateDate>
|
||||
<xap:MetadataDate>2008-08-06T12:43:05+10:00</xap:MetadataDate>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:exif="http://ns.adobe.com/exif/1.0/">
|
||||
<exif:ColorSpace>-1</exif:ColorSpace>
|
||||
<exif:PixelXDimension>3601</exif:PixelXDimension>
|
||||
<exif:PixelYDimension>4176</exif:PixelYDimension>
|
||||
<exif:NativeDigest>36864,40960,40961,37121,37122,40962,40963,37510,40964,36867,36868,33434,33437,34850,34852,34855,34856,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37396,41483,41484,41486,41487,41488,41492,41493,41495,41728,41729,41730,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,42016,0,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,23,24,25,26,27,28,30;297AD344CC15F29D5283460ED026368F</exif:NativeDigest>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<?xpacket end="w"?>
|
Loading…
x
Reference in New Issue
Block a user