Subversion Repositories general

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1267 → Rev 1268

/contrib/metadata-extractor/trunk/src/com/drew/metadata/iptc/IptcDirectory.java
0,0 → 1,97
/*
* This is public domain software - that is, you can do whatever you want
* with it, and include it software that is licensed under the GNU or the
* BSD license, or whatever other licence you choose, including proprietary
* closed source licenses. I do ask that you leave this header in tact.
*
* If you make modifications to this code that you think would benefit the
* wider community, please send me a copy and I'll post it on my site.
*
* If you make use of this code, I'd appreciate hearing about it.
* drew@drewnoakes.com
* Latest version of this software kept at
* http://drewnoakes.com/
*
* Created by dnoakes on 26-Nov-2002 01:26:39 using IntelliJ IDEA.
*/
package com.drew.metadata.iptc;
 
import com.drew.metadata.Directory;
 
import java.util.HashMap;
 
/**
*
*/
public class IptcDirectory extends Directory
{
public static final int TAG_RECORD_VERSION = 0x0200;
public static final int TAG_CAPTION = 0x0278;
public static final int TAG_WRITER = 0x027a;
public static final int TAG_HEADLINE = 0x0269;
public static final int TAG_SPECIAL_INSTRUCTIONS = 0x0228;
public static final int TAG_BY_LINE = 0x0250;
public static final int TAG_BY_LINE_TITLE = 0x0255;
public static final int TAG_CREDIT = 0x026e;
public static final int TAG_SOURCE = 0x0273;
public static final int TAG_OBJECT_NAME = 0x0205;
public static final int TAG_DATE_CREATED = 0x0237;
public static final int TAG_CITY = 0x025a;
public static final int TAG_PROVINCE_OR_STATE = 0x025f;
public static final int TAG_COUNTRY_OR_PRIMARY_LOCATION = 0x0265;
public static final int TAG_ORIGINAL_TRANSMISSION_REFERENCE = 0x0267;
public static final int TAG_CATEGORY = 0x020f;
public static final int TAG_SUPPLEMENTAL_CATEGORIES = 0x0214;
public static final int TAG_URGENCY = 0x0200 | 10;
public static final int TAG_KEYWORDS = 0x0200 | 25;
public static final int TAG_COPYRIGHT_NOTICE = 0x0274;
public static final int TAG_RELEASE_DATE = 0x0200 | 30;
public static final int TAG_RELEASE_TIME = 0x0200 | 35;
public static final int TAG_TIME_CREATED = 0x0200 | 60;
public static final int TAG_ORIGINATING_PROGRAM = 0x0200 | 65;
 
protected static final HashMap tagNameMap = new HashMap();
 
static
{
tagNameMap.put(new Integer(TAG_RECORD_VERSION), "Directory Version");
tagNameMap.put(new Integer(TAG_CAPTION), "Caption/Abstract");
tagNameMap.put(new Integer(TAG_WRITER), "Writer/Editor");
tagNameMap.put(new Integer(TAG_HEADLINE), "Headline");
tagNameMap.put(new Integer(TAG_SPECIAL_INSTRUCTIONS), "Special Instructions");
tagNameMap.put(new Integer(TAG_BY_LINE), "By-line");
tagNameMap.put(new Integer(TAG_BY_LINE_TITLE), "By-line Title");
tagNameMap.put(new Integer(TAG_CREDIT), "Credit");
tagNameMap.put(new Integer(TAG_SOURCE), "Source");
tagNameMap.put(new Integer(TAG_OBJECT_NAME), "Object Name");
tagNameMap.put(new Integer(TAG_DATE_CREATED), "Date Created");
tagNameMap.put(new Integer(TAG_CITY), "City");
tagNameMap.put(new Integer(TAG_PROVINCE_OR_STATE), "Province/State");
tagNameMap.put(new Integer(TAG_COUNTRY_OR_PRIMARY_LOCATION), "Country/Primary Location");
tagNameMap.put(new Integer(TAG_ORIGINAL_TRANSMISSION_REFERENCE), "Original Transmission Reference");
tagNameMap.put(new Integer(TAG_CATEGORY), "Category");
tagNameMap.put(new Integer(TAG_SUPPLEMENTAL_CATEGORIES), "Supplemental Category(s)");
tagNameMap.put(new Integer(TAG_URGENCY), "Urgency");
tagNameMap.put(new Integer(TAG_KEYWORDS), "Keywords");
tagNameMap.put(new Integer(TAG_COPYRIGHT_NOTICE), "Copyright Notice");
tagNameMap.put(new Integer(TAG_RELEASE_DATE), "Release Date");
tagNameMap.put(new Integer(TAG_RELEASE_TIME), "Release Time");
tagNameMap.put(new Integer(TAG_TIME_CREATED), "Time Created");
tagNameMap.put(new Integer(TAG_ORIGINATING_PROGRAM), "Originating Program");
}
 
public IptcDirectory()
{
this.setDescriptor(new IptcDescriptor(this));
}
 
public String getName()
{
return "Iptc";
}
 
protected HashMap getTagNameMap()
{
return tagNameMap;
}
}
/contrib/metadata-extractor/trunk/src/com/drew/metadata/iptc/IptcProcessingException.java
0,0 → 1,51
/*
* ExifProcessingException.java
*
* This class is public domain software - that is, you can do whatever you want
* with it, and include it software that is licensed under the GNU or the
* BSD license, or whatever other licence you choose, including proprietary
* closed source licenses. I do ask that you leave this header in tact.
*
* If you make modifications to this code that you think would benefit the
* wider community, please send me a copy and I'll post it on my site.
*
* If you make use of this code, I'd appreciate hearing about it.
* drew@drewnoakes.com
* Latest version of this software kept at
* http://drewnoakes.com/
*
* Created on 29 April 2002, 00:33
*/
 
package com.drew.metadata.iptc;
 
import com.drew.metadata.MetadataException;
 
/**
* The exception type raised during reading of Iptc data in the instance of
* unexpected data conditions.
* @author Drew Noakes http://drewnoakes.com
*/
public class IptcProcessingException extends MetadataException
{
/**
* Constructs an instance of <code>ExifProcessingException</code> with the
* specified detail message.
* @param message the detail message
*/
public IptcProcessingException(String message)
{
super(message);
}
 
/**
* Constructs an instance of <code>IptcProcessingException</code> with the
* specified detail message and inner exception.
* @param message the detail message
* @param cause an inner exception
*/
public IptcProcessingException(String message, Throwable cause)
{
super(message, cause);
}
}
/contrib/metadata-extractor/trunk/src/com/drew/metadata/iptc/IptcDescriptor.java
0,0 → 1,36
/*
* This is public domain software - that is, you can do whatever you want
* with it, and include it software that is licensed under the GNU or the
* BSD license, or whatever other licence you choose, including proprietary
* closed source licenses. I do ask that you leave this header in tact.
*
* If you make modifications to this code that you think would benefit the
* wider community, please send me a copy and I'll post it on my site.
*
* If you make use of this code, I'd appreciate hearing about it.
* drew@drewnoakes.com
* Latest version of this software kept at
* http://drewnoakes.com/
*
* Created by dnoakes on 21-Nov-2002 17:58:19 using IntelliJ IDEA.
*/
package com.drew.metadata.iptc;
 
import com.drew.metadata.Directory;
import com.drew.metadata.TagDescriptor;
 
/**
*
*/
public class IptcDescriptor extends TagDescriptor
{
public IptcDescriptor(Directory directory)
{
super(directory);
}
 
public String getDescription(int tagType)
{
return _directory.getString(tagType);
}
}
/contrib/metadata-extractor/trunk/src/com/drew/metadata/iptc/test/withIptc.jpg
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/metadata-extractor/trunk/src/com/drew/metadata/iptc/test/IptcReaderTest.java
0,0 → 1,69
/*
* This is public domain software - that is, you can do whatever you want
* with it, and include it software that is licensed under the GNU or the
* BSD license, or whatever other licence you choose, including proprietary
* closed source licenses. I do ask that you leave this header in tact.
*
* If you make modifications to this code that you think would benefit the
* wider community, please send me a copy and I'll post it on my site.
*
* If you make use of this code, I'd appreciate hearing about it.
* drew@drewnoakes.com
* Latest version of this software kept at
* http://drewnoakes.com/
*
* Created by dnoakes on 22-Nov-2002 08:26:26 using IntelliJ IDEA.
*/
package com.drew.metadata.iptc.test;
 
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.MetadataReader;
import com.drew.metadata.iptc.IptcDirectory;
import com.drew.metadata.iptc.IptcReader;
import junit.framework.TestCase;
 
import java.io.File;
 
/**
*
*/
public class IptcReaderTest extends TestCase
{
public IptcReaderTest(String s)
{
super(s);
}
 
public void testDescription_City() throws Exception
{
File iptcFile = new File("src/com/drew/metadata/iptc/test/withIptc.jpg");
MetadataReader reader = new IptcReader(iptcFile);
Metadata metadata = reader.extract();
assertTrue(metadata.containsDirectory(IptcDirectory.class));
Directory directory = metadata.getDirectory(IptcDirectory.class);
assertEquals("City", directory.getDescription(IptcDirectory.TAG_CITY));
}
 
public void testDescription_Caption() throws Exception
{
File iptcFile = new File("src/com/drew/metadata/iptc/test/withIptc.jpg");
MetadataReader reader = new IptcReader(iptcFile);
Metadata metadata = reader.extract();
assertTrue(metadata.containsDirectory(IptcDirectory.class));
Directory directory = metadata.getDirectory(IptcDirectory.class);
assertEquals("Caption", directory.getDescription(IptcDirectory.TAG_CAPTION));
}
 
public void testDescription_Category() throws Exception
{
File iptcFile = new File("src/com/drew/metadata/iptc/test/withIptc.jpg");
MetadataReader reader = new IptcReader(iptcFile);
Metadata metadata = reader.extract();
assertTrue(metadata.containsDirectory(IptcDirectory.class));
Directory directory = metadata.getDirectory(IptcDirectory.class);
assertEquals("Supl. Category2 Supl. Category1 Cat", directory.getDescription(IptcDirectory.TAG_CATEGORY));
}
 
// TODO Wrap more tests around the Iptc reader
}
/contrib/metadata-extractor/trunk/src/com/drew/metadata/iptc/test/withIptcPhotoshop6.jpg
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/metadata-extractor/trunk/src/com/drew/metadata/iptc/IptcReader.java
0,0 → 1,225
/*
* This is public domain software - that is, you can do whatever you want
* with it, and include it software that is licensed under the GNU or the
* BSD license, or whatever other licence you choose, including proprietary
* closed source licenses. I do ask that you leave this header in tact.
*
* If you make modifications to this code that you think would benefit the
* wider community, please send me a copy and I'll post it on my site.
*
* If you make use of this code, I'd appreciate hearing about it.
* drew@drewnoakes.com
* Latest version of this software kept at
* http://drewnoakes.com/
*
* Created by dnoakes on 12-Nov-2002 19:00:03 using IntelliJ IDEA.
*/
package com.drew.metadata.iptc;
 
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.imaging.jpeg.JpegSegmentReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.MetadataException;
import com.drew.metadata.MetadataReader;
 
import java.io.File;
import java.io.InputStream;
import java.util.Date;
 
/**
*
*/
public class IptcReader implements MetadataReader
{
/*
public static final int DIRECTORY_IPTC = 2;
 
public static final int ENVELOPE_RECORD = 1;
public static final int APPLICATION_RECORD_2 = 2;
public static final int APPLICATION_RECORD_3 = 3;
public static final int APPLICATION_RECORD_4 = 4;
public static final int APPLICATION_RECORD_5 = 5;
public static final int APPLICATION_RECORD_6 = 6;
public static final int PRE_DATA_RECORD = 7;
public static final int DATA_RECORD = 8;
public static final int POST_DATA_RECORD = 9;
*/
/**
* The Iptc data segment.
*/
private final byte[] _data;
 
/**
* Creates a new IptcReader for the specified Jpeg jpegFile.
*/
public IptcReader(File jpegFile) throws JpegProcessingException
{
this(new JpegSegmentReader(jpegFile).readSegment(JpegSegmentReader.SEGMENT_APPD));
}
 
/** Creates an IptcReader for a JPEG stream.
*
* @param is JPEG stream. Stream will be closed.
*/
public IptcReader(InputStream is) throws JpegProcessingException
{
this(new JpegSegmentReader(is).readSegment(JpegSegmentReader.SEGMENT_APPD));
}
 
public IptcReader(byte[] data)
{
_data = data;
}
 
/**
* Performs the Exif data extraction, returning a new instance of <code>Metadata</code>.
*/
public Metadata extract()
{
return extract(new Metadata());
}
 
/**
* Performs the Exif data extraction, adding found values to the specified
* instance of <code>Metadata</code>.
*/
public Metadata extract(Metadata metadata)
{
if (_data == null) {
return metadata;
}
 
Directory directory = metadata.getDirectory(IptcDirectory.class);
 
// find start of data
int offset = 0;
try {
while (offset < _data.length - 1 && get32Bits(offset) != 0x1c02) {
offset++;
}
} catch (MetadataException e) {
directory.addError("Couldn't find start of Iptc data (invalid segment)");
return metadata;
}
 
// for each tag
while (offset < _data.length) {
// identifies start of a tag
if (_data[offset] != 0x1c) {
break;
}
// we need at least five bytes left to read a tag
if ((offset + 5) >= _data.length) {
break;
}
 
offset++;
 
int directoryType;
int tagType;
int tagByteCount;
try {
directoryType = _data[offset++];
tagType = _data[offset++];
tagByteCount = get32Bits(offset);
} catch (MetadataException e) {
directory.addError("Iptc data segment ended mid-way through tag descriptor");
return metadata;
}
offset += 2;
if ((offset + tagByteCount) > _data.length) {
directory.addError("data for tag extends beyond end of iptc segment");
break;
}
 
processTag(directory, directoryType, tagType, offset, tagByteCount);
offset += tagByteCount;
}
 
return metadata;
}
 
/**
* Returns an int calculated from two bytes of data at the specified offset (MSB, LSB).
* @param offset position within the data buffer to read first byte
* @return the 32 bit int value, between 0x0000 and 0xFFFF
*/
private int get32Bits(int offset) throws MetadataException
{
if (offset >= _data.length) {
throw new MetadataException("Attempt to read bytes from outside Iptc data buffer");
}
return ((_data[offset] & 255) << 8) | (_data[offset + 1] & 255);
}
 
/**
* This method serves as marsheller of objects for dataset. It converts from IPTC
* octets to relevant java object.
*/
private void processTag(Directory directory, int directoryType, int tagType, int offset, int tagByteCount)
{
int tagIdentifier = tagType | (directoryType << 8);
 
switch (tagIdentifier) {
case IptcDirectory.TAG_RECORD_VERSION:
// short
short shortValue = (short)((_data[offset] << 8) | _data[offset + 1]);
directory.setInt(tagIdentifier, shortValue);
return;
case IptcDirectory.TAG_URGENCY:
// byte
directory.setInt(tagIdentifier, _data[offset]);
return;
case IptcDirectory.TAG_RELEASE_DATE:
case IptcDirectory.TAG_DATE_CREATED:
// Date object
if (tagByteCount >= 8) {
String dateStr = new String(_data, offset, tagByteCount);
try {
int year = Integer.parseInt(dateStr.substring(0, 4));
int month = Integer.parseInt(dateStr.substring(4, 6)) - 1;
int day = Integer.parseInt(dateStr.substring(6, 8));
Date date = (new java.util.GregorianCalendar(year, month, day)).getTime();
directory.setDate(tagIdentifier, date);
return;
} catch (NumberFormatException e) {
// fall through and we'll store whatever was there as a String
}
}
case IptcDirectory.TAG_RELEASE_TIME:
case IptcDirectory.TAG_TIME_CREATED:
// time...
default:
// fall through
}
// If no special handling by now, treat it as a string
String str;
if (tagByteCount < 1) {
str = "";
} else {
str = new String(_data, offset, tagByteCount);
}
if (directory.containsTag(tagIdentifier)) {
String[] oldStrings;
String[] newStrings;
try {
oldStrings = directory.getStringArray(tagIdentifier);
} catch (MetadataException e) {
oldStrings = null;
}
if (oldStrings == null) {
newStrings = new String[1];
} else {
newStrings = new String[oldStrings.length + 1];
for (int i = 0; i < oldStrings.length; i++) {
newStrings[i] = oldStrings[i];
}
}
newStrings[newStrings.length - 1] = str;
directory.setStringArray(tagIdentifier, newStrings);
} else {
directory.setString(tagIdentifier, str);
}
}
}