diff options
8 files changed, 284 insertions, 184 deletions
diff --git a/src/com/android/gallery3d/exif/ExifData.java b/src/com/android/gallery3d/exif/ExifData.java index 39eb57455..7f7971384 100644 --- a/src/com/android/gallery3d/exif/ExifData.java +++ b/src/com/android/gallery3d/exif/ExifData.java @@ -216,7 +216,8 @@ public class ExifData { } /** - * Adds a tag with the given tag ID. The original tag will be replaced by the new tag. For tags + * Adds a tag with the given tag ID. If the tag of the given ID already exists, + * the original tag will be returned. Otherwise, a new ExifTag will be created. For tags * related to interoperability or thumbnail, call {@link #addInteroperabilityTag(short)} or * {@link #addThumbnailTag(short)} respectively. * @exception IllegalArgumentException if the tag ID is invalid. @@ -224,32 +225,43 @@ public class ExifData { public ExifTag addTag(short tagId) { int ifdId = ExifTag.getIfdIdFromTagId(tagId); IfdData ifdData = getOrCreateIfdData(ifdId); - ExifTag tag = ExifTag.buildTag(tagId); - ifdData.setTag(tag); + ExifTag tag = ifdData.getTag(tagId); + if (tag == null) { + tag = ExifTag.buildTag(tagId); + ifdData.setTag(tag); + } return tag; } /** - * Adds a thumbnail-related tag with the given tag ID. The original tag will be replaced - * by the new tag. + * Adds a thumbnail-related tag with the given tag ID. If the tag of the given ID + * already exists, the original tag will be returned. Otherwise, a new ExifTag will + * be created. * @exception IllegalArgumentException if the tag ID is invalid. */ public ExifTag addThumbnailTag(short tagId) { IfdData ifdData = getOrCreateIfdData(IfdId.TYPE_IFD_1); - ExifTag tag = ExifTag.buildThumbnailTag(tagId); - ifdData.setTag(tag); + ExifTag tag = ifdData.getTag(tagId); + if (tag == null) { + tag = ExifTag.buildThumbnailTag(tagId); + ifdData.setTag(tag); + } return tag; } /** - * Adds an interoperability-related tag with the given tag ID. The original tag will be - * replaced by the new tag. + * Adds an interoperability-related tag with the given tag ID. If the tag of the given ID + * already exists, the original tag will be returned. Otherwise, a new ExifTag will + * be created. * @exception IllegalArgumentException if the tag ID is invalid. */ public ExifTag addInteroperabilityTag(short tagId) { IfdData ifdData = getOrCreateIfdData(IfdId.TYPE_IFD_INTEROPERABILITY); - ExifTag tag = ExifTag.buildInteroperabilityTag(tagId); - ifdData.setTag(tag); + ExifTag tag = ifdData.getTag(tagId); + if (tag == null) { + tag = ExifTag.buildInteroperabilityTag(tagId); + ifdData.setTag(tag); + } return tag; } @@ -258,4 +270,4 @@ public class ExifData { mStripBytes.clear(); mIfdDatas[IfdId.TYPE_IFD_1] = null; } -}
\ No newline at end of file +} diff --git a/src/com/android/gallery3d/exif/ExifTag.java b/src/com/android/gallery3d/exif/ExifTag.java index 49cb6edbc..86ac7be74 100644 --- a/src/com/android/gallery3d/exif/ExifTag.java +++ b/src/com/android/gallery3d/exif/ExifTag.java @@ -1361,9 +1361,10 @@ public class ExifTag { StringBuilder sbuilder = new StringBuilder(); switch (getDataType()) { case ExifTag.TYPE_UNDEFINED: + sbuilder.append(new String((byte[]) mValue)); + break; case ExifTag.TYPE_UNSIGNED_BYTE: - byte buf[] = new byte[getComponentCount()]; - getBytes(buf); + byte buf[] = (byte[]) mValue; for(int i = 0, n = getComponentCount(); i < n; i++) { if(i != 0) sbuilder.append(" "); sbuilder.append(String.format("%02x", buf[i])); @@ -1415,6 +1416,15 @@ public class ExifTag { || tagId == TAG_INTEROPERABILITY_IFD; } + /** + * Returns true if the ID is one of the following: {@link #TAG_EXIF_IFD}, + * {@link #TAG_GPS_IFD}, {@link #TAG_INTEROPERABILITY_IFD} + */ + static boolean isSubIfdOffsetTag(short tagId) { + return tagId == TAG_EXIF_IFD + || tagId == TAG_GPS_IFD + || tagId == TAG_INTEROPERABILITY_IFD; + } @Override public boolean equals(Object obj) { if (obj instanceof ExifTag) { diff --git a/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java b/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java index ad603df39..1950c7e86 100644 --- a/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java +++ b/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java @@ -19,32 +19,39 @@ package com.android.gallery3d.exif; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.List; +import java.util.Map; public class ExifOutputStreamTest extends ExifXmlDataTestCase { - public ExifOutputStreamTest(int imageResourceId, int xmlResourceId) { - super(imageResourceId, xmlResourceId); + public ExifOutputStreamTest(int imgRes, int xmlRes) { + super(imgRes, xmlRes); } - public void testExifOutputStream() throws IOException, ExifInvalidFormatException { + public ExifOutputStreamTest(String imgPath, String xmlPath) { + super(imgPath, xmlPath); + } + + public void testExifOutputStream() throws Exception { File file = File.createTempFile("exif_test", ".jpg"); InputStream imageInputStream = null; InputStream exifInputStream = null; FileInputStream reDecodeInputStream = null; FileInputStream reParseInputStream = null; try { - // Read the image - imageInputStream = getInstrumentation() - .getContext().getResources().openRawResource(mImageResourceId); - Bitmap bmp = BitmapFactory.decodeStream(imageInputStream); + byte[] imgData = readToByteArray(getImageInputStream()); + imageInputStream = new ByteArrayInputStream(imgData); + exifInputStream = new ByteArrayInputStream(imgData); + // Read the image data + Bitmap bmp = BitmapFactory.decodeStream(imageInputStream); // Read exif data - exifInputStream = getInstrumentation() - .getContext().getResources().openRawResource(mImageResourceId); ExifData exifData = new ExifReader().read(exifInputStream); // Encode the image with the exif data @@ -70,4 +77,15 @@ public class ExifOutputStreamTest extends ExifXmlDataTestCase { Util.closeSilently(reParseInputStream); } } -}
\ No newline at end of file + + private byte[] readToByteArray(InputStream is) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + int len; + byte[] buf = new byte[1024]; + while ((len = is.read(buf)) > -1) { + bos.write(buf, 0, len); + } + bos.flush(); + return bos.toByteArray(); + } +} diff --git a/tests/src/com/android/gallery3d/exif/ExifParserTest.java b/tests/src/com/android/gallery3d/exif/ExifParserTest.java index c1ad8341b..f89ac29ff 100644 --- a/tests/src/com/android/gallery3d/exif/ExifParserTest.java +++ b/tests/src/com/android/gallery3d/exif/ExifParserTest.java @@ -16,43 +16,34 @@ package com.android.gallery3d.exif; -import android.content.res.XmlResourceParser; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; +import java.util.List; +import java.util.Map; public class ExifParserTest extends ExifXmlDataTestCase { private static final String TAG = "ExifParserTest"; - private HashMap<Short, String> mIfd0Value = new HashMap<Short, String>(); - private HashMap<Short, String> mIfd1Value = new HashMap<Short, String>(); - private HashMap<Short, String> mExifIfdValue = new HashMap<Short, String>(); - private HashMap<Short, String> mInteroperabilityIfdValue = new HashMap<Short, String>(); - - private InputStream mImageInputStream; - - public ExifParserTest(int imageResourceId, int xmlResourceId) { - super(imageResourceId, xmlResourceId); + public ExifParserTest(int imgRes, int xmlRes) { + super(imgRes, xmlRes); } - @Override - protected void setUp() throws Exception { - mImageInputStream = getInstrumentation() - .getContext().getResources().openRawResource(mImageResourceId); + public ExifParserTest(String imgPath, String xmlPath) { + super(imgPath, xmlPath); + } - XmlResourceParser parser = - getInstrumentation().getContext().getResources().getXml(mXmlResourceId); + private List<Map<Short, String>> mGroundTruth; - ExifXmlReader.readXml(parser, mIfd0Value, mIfd1Value, mExifIfdValue - , mInteroperabilityIfdValue); - parser.close(); + @Override + public void setUp() throws Exception { + super.setUp(); + mGroundTruth = ExifXmlReader.readXml(getXmlParser()); } - public void testParse() throws IOException, ExifInvalidFormatException { - ExifParser parser = ExifParser.parse(mImageInputStream); + public void testParse() throws Exception { + ExifParser parser = ExifParser.parse(getImageInputStream()); int event = parser.next(); while (event != ExifParser.EVENT_END) { switch (event) { @@ -81,34 +72,25 @@ public class ExifParserTest extends ExifXmlDataTestCase { } private void checkTag(ExifTag tag) { - HashMap<Short, String> truth = null; - switch (tag.getIfd()) { - case IfdId.TYPE_IFD_0: - truth = mIfd0Value; - break; - case IfdId.TYPE_IFD_1: - truth = mIfd1Value; - break; - case IfdId.TYPE_IFD_EXIF: - truth = mExifIfdValue; - break; - case IfdId.TYPE_IFD_INTEROPERABILITY: - truth = mInteroperabilityIfdValue; - break; - } + // Ignore offset tags since the ground-truth from exiftool doesn't have it. + // We can verify it by examining the sub-IFD or thumbnail itself. + if (ExifTag.isSubIfdOffsetTag(tag.getTagId())) return; + + String truthString = mGroundTruth.get(tag.getIfd()).get(tag.getTagId()); - String truthString = truth.get(tag.getTagId()); - String dataString = tag.valueToString().trim(); if (truthString == null) { fail(String.format("Unknown Tag %02x", tag.getTagId())); } + + String dataString = tag.valueToString().trim(); assertEquals(String.format("Tag %02x", tag.getTagId()), truthString, dataString); } - private void parseOneIfd(int ifd, int options, HashMap<Short, String> expectedResult) + private void parseOneIfd(int ifd, int options) throws IOException, ExifInvalidFormatException { + Map<Short, String> expectedResult = mGroundTruth.get(ifd); int numOfTag = 0; - ExifParser parser = ExifParser.parse(mImageInputStream, options); + ExifParser parser = ExifParser.parse(getImageInputStream(), options); int event = parser.next(); while(event != ExifParser.EVENT_END) { switch (event) { @@ -116,8 +98,8 @@ public class ExifParserTest extends ExifXmlDataTestCase { assertEquals(ifd, parser.getCurrentIfd()); break; case ExifParser.EVENT_NEW_TAG: - numOfTag++; ExifTag tag = parser.getTag(); + if (!ExifTag.isSubIfdOffsetTag(tag.getTagId())) numOfTag++; if (tag.hasValue()) { checkTag(tag); } else { @@ -143,25 +125,24 @@ public class ExifParserTest extends ExifXmlDataTestCase { assertEquals(expectedResult.size(), numOfTag); } - public void testOnlyExifIfd() throws IOException, ExifInvalidFormatException { - parseOneIfd(IfdId.TYPE_IFD_EXIF, ExifParser.OPTION_IFD_EXIF, mExifIfdValue); + public void testOnlyExifIfd() throws Exception { + parseOneIfd(IfdId.TYPE_IFD_EXIF, ExifParser.OPTION_IFD_EXIF); } - public void testOnlyIfd0() throws IOException, ExifInvalidFormatException { - parseOneIfd(IfdId.TYPE_IFD_0, ExifParser.OPTION_IFD_0, mIfd0Value); + public void testOnlyIfd0() throws Exception { + parseOneIfd(IfdId.TYPE_IFD_0, ExifParser.OPTION_IFD_0); } - public void testOnlyIfd1() throws IOException, ExifInvalidFormatException { - parseOneIfd(IfdId.TYPE_IFD_1, ExifParser.OPTION_IFD_1, mIfd1Value); + public void testOnlyIfd1() throws Exception { + parseOneIfd(IfdId.TYPE_IFD_1, ExifParser.OPTION_IFD_1); } - public void testOnlyInteroperabilityIfd() throws IOException, ExifInvalidFormatException { - parseOneIfd(IfdId.TYPE_IFD_INTEROPERABILITY, ExifParser.OPTION_IFD_INTEROPERABILITY - , mInteroperabilityIfdValue); + public void testOnlyInteroperabilityIfd() throws Exception { + parseOneIfd(IfdId.TYPE_IFD_INTEROPERABILITY, ExifParser.OPTION_IFD_INTEROPERABILITY); } - public void testOnlyReadSomeTag() throws IOException, ExifInvalidFormatException { - ExifParser parser = ExifParser.parse(mImageInputStream, ExifParser.OPTION_IFD_0); + public void testOnlyReadSomeTag() throws Exception { + ExifParser parser = ExifParser.parse(getImageInputStream(), ExifParser.OPTION_IFD_0); int event = parser.next(); boolean isTagFound = false; while (event != ExifParser.EVENT_END) { @@ -193,8 +174,8 @@ public class ExifParserTest extends ExifXmlDataTestCase { assertTrue(isTagFound); } - public void testReadThumbnail() throws ExifInvalidFormatException, IOException { - ExifParser parser = ExifParser.parse(mImageInputStream, + public void testReadThumbnail() throws Exception { + ExifParser parser = ExifParser.parse(getImageInputStream(), ExifParser.OPTION_IFD_1 | ExifParser.OPTION_THUMBNAIL); int event = parser.next(); @@ -223,12 +204,4 @@ public class ExifParserTest extends ExifXmlDataTestCase { assertNotNull(bmp); } } - - @Override - protected void tearDown() throws IOException { - mImageInputStream.close(); - mIfd0Value.clear(); - mIfd1Value.clear(); - mExifIfdValue.clear(); - } -}
\ No newline at end of file +} diff --git a/tests/src/com/android/gallery3d/exif/ExifReaderTest.java b/tests/src/com/android/gallery3d/exif/ExifReaderTest.java index 269120870..3a78e091b 100644 --- a/tests/src/com/android/gallery3d/exif/ExifReaderTest.java +++ b/tests/src/com/android/gallery3d/exif/ExifReaderTest.java @@ -16,48 +16,29 @@ package com.android.gallery3d.exif; -import android.content.res.XmlResourceParser; import android.graphics.BitmapFactory; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; +import java.util.List; +import java.util.Map; public class ExifReaderTest extends ExifXmlDataTestCase { private static final String TAG = "ExifReaderTest"; - private final HashMap<Short, String> mIfd0Value = new HashMap<Short, String>(); - private final HashMap<Short, String> mIfd1Value = new HashMap<Short, String>(); - private final HashMap<Short, String> mExifIfdValue = new HashMap<Short, String>(); - private final HashMap<Short, String> mInteroperabilityIfdValue = new HashMap<Short, String>(); - - private InputStream mImageInputStream; - - public ExifReaderTest(int imageResourceId, int xmlResourceId) { - super(imageResourceId, xmlResourceId); + public ExifReaderTest(int imgRes, int xmlRes) { + super(imgRes, xmlRes); } - @Override - public void setUp() throws Exception { - mImageInputStream = getInstrumentation() - .getContext().getResources().openRawResource(mImageResourceId); - - XmlResourceParser parser = - getInstrumentation().getContext().getResources().getXml(mXmlResourceId); - - ExifXmlReader.readXml(parser, mIfd0Value, mIfd1Value, mExifIfdValue - , mInteroperabilityIfdValue); - parser.close(); + public ExifReaderTest(String imgPath, String xmlPath) { + super(imgPath, xmlPath); } - public void testRead() throws ExifInvalidFormatException, IOException { + public void testRead() throws Exception { ExifReader reader = new ExifReader(); - ExifData exifData = reader.read(mImageInputStream); - checkIfd(exifData.getIfdData(IfdId.TYPE_IFD_0), mIfd0Value); - checkIfd(exifData.getIfdData(IfdId.TYPE_IFD_1), mIfd1Value); - checkIfd(exifData.getIfdData(IfdId.TYPE_IFD_EXIF), mExifIfdValue); - checkIfd(exifData.getIfdData(IfdId.TYPE_IFD_INTEROPERABILITY), - mInteroperabilityIfdValue); + ExifData exifData = reader.read(getImageInputStream()); + List<Map<Short, String>> groundTruth = ExifXmlReader.readXml(getXmlParser()); + for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { + checkIfd(exifData.getIfdData(i), groundTruth.get(i)); + } checkThumbnail(exifData); } @@ -115,20 +96,18 @@ public class ExifReaderTest extends ExifXmlDataTestCase { } } - private void checkIfd(IfdData ifd, HashMap<Short, String> ifdValue) { + private void checkIfd(IfdData ifd, Map<Short, String> ifdValue) { if (ifd == null) { assertEquals(0 ,ifdValue.size()); return; } ExifTag[] tags = ifd.getAllTags(); + int size = 0; for (ExifTag tag : tags) { + if (ExifTag.isSubIfdOffsetTag(tag.getTagId())) continue; assertEquals(ifdValue.get(tag.getTagId()), tag.valueToString().trim()); + size++; } - assertEquals(ifdValue.size(), tags.length); - } - - @Override - public void tearDown() throws Exception { - mImageInputStream.close(); + assertEquals(ifdValue.size(), size); } } diff --git a/tests/src/com/android/gallery3d/exif/ExifTestRunner.java b/tests/src/com/android/gallery3d/exif/ExifTestRunner.java index 57a7111ad..519e87107 100644 --- a/tests/src/com/android/gallery3d/exif/ExifTestRunner.java +++ b/tests/src/com/android/gallery3d/exif/ExifTestRunner.java @@ -16,6 +16,8 @@ package com.android.gallery3d.exif; +import android.content.Context; +import android.os.Environment; import android.test.InstrumentationTestRunner; import android.test.InstrumentationTestSuite; import android.util.Log; @@ -25,8 +27,11 @@ import com.android.gallery3d.tests.R; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; public class ExifTestRunner extends InstrumentationTestRunner { private static final String TAG = "ExifTestRunner"; @@ -34,12 +39,17 @@ public class ExifTestRunner extends InstrumentationTestRunner { private static final int[] IMG_RESOURCE = { R.raw.galaxy_nexus }; + private static final int[] EXIF_DATA_RESOURCE = { R.xml.galaxy_nexus }; + private static List<String> mTestImgPath = new ArrayList<String>(); + private static List<String> mTestXmlPath = new ArrayList<String>(); + @Override public TestSuite getAllTests() { + getTestImagePath(); TestSuite suite = new InstrumentationTestSuite(this); suite.addTestSuite(ExifDataTest.class); suite.addTestSuite(ExifTagTest.class); @@ -49,6 +59,25 @@ public class ExifTestRunner extends InstrumentationTestRunner { return suite; } + private void getTestImagePath() { + Context context = getContext(); + File imgDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); + File xmlDir = new File(context.getExternalFilesDir(null).getPath(), "Xml"); + + if (imgDir != null && xmlDir != null) { + String[] imgs = imgDir.list(); + if (imgs == null) return; + for (String imgName: imgs) { + String xmlName = imgName.substring(0, imgName.lastIndexOf('.')) + ".xml"; + File xmlFile = new File(xmlDir, xmlName); + if (xmlFile.exists()) { + mTestImgPath.add(new File(imgDir, imgName).getAbsolutePath()); + mTestXmlPath.add(xmlFile.getAbsolutePath()); + } + } + } + } + private void addAllTestsFromExifTestCase(Class<? extends ExifXmlDataTestCase> testClass, TestSuite suite) { for (Method method : testClass.getDeclaredMethods()) { @@ -72,6 +101,25 @@ public class ExifTestRunner extends InstrumentationTestRunner { Log.e(TAG, "Failed to create test case", e); } } + for (int i = 0, n = mTestImgPath.size(); i < n; i++) { + TestCase test; + try { + test = testClass.getDeclaredConstructor(String.class, String.class). + newInstance(mTestImgPath.get(i), mTestXmlPath.get(i)); + test.setName(method.getName()); + suite.addTest(test); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Failed to create test case", e); + } catch (InstantiationException e) { + Log.e(TAG, "Failed to create test case", e); + } catch (IllegalAccessException e) { + Log.e(TAG, "Failed to create test case", e); + } catch (InvocationTargetException e) { + Log.e(TAG, "Failed to create test case", e); + } catch (NoSuchMethodException e) { + Log.e(TAG, "Failed to create test case", e); + } + } } } } diff --git a/tests/src/com/android/gallery3d/exif/ExifXmlDataTestCase.java b/tests/src/com/android/gallery3d/exif/ExifXmlDataTestCase.java index 41b315181..16a7c6821 100644 --- a/tests/src/com/android/gallery3d/exif/ExifXmlDataTestCase.java +++ b/tests/src/com/android/gallery3d/exif/ExifXmlDataTestCase.java @@ -17,14 +17,65 @@ package com.android.gallery3d.exif; +import android.content.res.Resources; import android.test.InstrumentationTestCase; +import android.util.Xml; + +import org.xmlpull.v1.XmlPullParser; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; public class ExifXmlDataTestCase extends InstrumentationTestCase { - protected final int mImageResourceId; - protected final int mXmlResourceId; + + private InputStream mImageInputStream; + private InputStream mXmlInputStream; + private XmlPullParser mXmlParser; + private final String mImagePath; + private final String mXmlPath; + private final int mImageResourceId; + private final int mXmlResourceId; public ExifXmlDataTestCase(int imageRes, int xmlRes) { + mImagePath = null; + mXmlPath = null; mImageResourceId = imageRes; mXmlResourceId = xmlRes; } + + public ExifXmlDataTestCase(String imagePath, String xmlPath) { + mImagePath = imagePath; + mXmlPath = xmlPath; + mImageResourceId = 0; + mXmlResourceId = 0; + } + + protected InputStream getImageInputStream() { + return mImageInputStream; + } + + protected XmlPullParser getXmlParser() { + return mXmlParser; + } + + @Override + public void setUp() throws Exception { + if (mImagePath != null) { + mImageInputStream = new FileInputStream(mImagePath); + mXmlInputStream = new FileInputStream(mXmlPath); + mXmlParser = Xml.newPullParser(); + mXmlParser.setInput(new InputStreamReader(mXmlInputStream)); + } else { + Resources res = getInstrumentation().getContext().getResources(); + mImageInputStream = res.openRawResource(mImageResourceId); + mXmlParser = res.getXml(mXmlResourceId); + } + } + + @Override + public void tearDown() throws Exception { + Util.closeSilently(mImageInputStream); + Util.closeSilently(mXmlInputStream); + } } diff --git a/tests/src/com/android/gallery3d/exif/ExifXmlReader.java b/tests/src/com/android/gallery3d/exif/ExifXmlReader.java index 72dd31373..139b0ca47 100644 --- a/tests/src/com/android/gallery3d/exif/ExifXmlReader.java +++ b/tests/src/com/android/gallery3d/exif/ExifXmlReader.java @@ -20,78 +20,87 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; public class ExifXmlReader { + private static final String TAG_EXIF = "exif"; + private static final String TAG_TAG = "tag"; - private static final String XML_EXIF_TAG = "exif"; - private static final String XML_IFD_TAG = "ifd"; - private static final String XML_IFD_NAME = "name"; - private static final String XML_TAG = "tag"; - private static final String XML_IFD0 = "ifd0"; - private static final String XML_IFD1 = "ifd1"; - private static final String XML_EXIF_IFD = "exif-ifd"; - private static final String XML_INTEROPERABILITY_IFD = "interoperability-ifd"; - private static final String XML_TAG_ID = "id"; - - public static void readXml(XmlPullParser parser, HashMap<Short, String> ifd0, - HashMap<Short, String> ifd1, HashMap<Short, String> exifIfd, - HashMap<Short, String> interoperabilityIfd) throws XmlPullParserException, - IOException { + private static final String IFD0 = "IFD0"; + private static final String EXIF_IFD = "ExifIFD"; + private static final String GPS_IFD = "GPS"; + private static final String IFD1 = "IFD1"; + private static final String INTEROP_IFD = "InteropIFD"; + + private static final String ATTR_ID = "id"; + private static final String ATTR_IFD = "ifd"; + + /** + * This function read the ground truth XML. + * + * @throws XmlPullParserException + * @throws IOException + */ + static public List<Map<Short, String>> readXml(XmlPullParser parser) + throws XmlPullParserException, IOException { + + List<Map<Short, String>> exifData = + new ArrayList<Map<Short, String>>(IfdId.TYPE_IFD_COUNT); + for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { + exifData.add(new HashMap<Short, String>()); + } while (parser.next() != XmlPullParser.END_DOCUMENT) { if (parser.getEventType() == XmlPullParser.START_TAG) { break; } } + parser.require(XmlPullParser.START_TAG, null, TAG_EXIF); - assert(parser.getName().equals(XML_EXIF_TAG)); - - parser.require(XmlPullParser.START_TAG, null, XML_EXIF_TAG); while (parser.next() != XmlPullParser.END_TAG) { - if (parser.getEventType() == XmlPullParser.START_TAG) { - readXmlIfd(parser, ifd0, ifd1, exifIfd, interoperabilityIfd); + if (parser.getEventType() != XmlPullParser.START_TAG) { + continue; } - } - parser.require(XmlPullParser.END_TAG, null, XML_EXIF_TAG); - } - private static void readXmlIfd(XmlPullParser parser, HashMap<Short, String> ifd0, - HashMap<Short, String> ifd1, HashMap<Short, String> exifIfd, - HashMap<Short, String> interoperabilityIfd) throws XmlPullParserException, - IOException { - parser.require(XmlPullParser.START_TAG, null, XML_IFD_TAG); - String name = parser.getAttributeValue(null, XML_IFD_NAME); - HashMap<Short, String> ifdData = null; - if (XML_IFD0.equals(name)) { - ifdData = ifd0; - } else if (XML_IFD1.equals(name)) { - ifdData = ifd1; - } else if (XML_EXIF_IFD.equals(name)) { - ifdData = exifIfd; - } else if (XML_INTEROPERABILITY_IFD.equals(name)) { - ifdData = interoperabilityIfd; - } else { - throw new RuntimeException("Unknown IFD name in xml file: " + name); - } - while (parser.next() != XmlPullParser.END_TAG) { - if (parser.getEventType() == XmlPullParser.START_TAG) { - readXmlTag(parser, ifdData); + parser.require(XmlPullParser.START_TAG, null, TAG_TAG); + + int ifdId = getIfdIdFromString(parser.getAttributeValue(null, ATTR_IFD)); + short id = Integer.decode(parser.getAttributeValue(null, ATTR_ID)).shortValue(); + + String value = ""; + if (parser.next() == XmlPullParser.TEXT) { + value = parser.getText(); + parser.next(); } + + if (ifdId < 0) { + // TODO: the MarkerNote segment. + } else { + exifData.get(ifdId).put(id, value); + } + + parser.require(XmlPullParser.END_TAG, null, null); } - parser.require(XmlPullParser.END_TAG, null, XML_IFD_TAG); + return exifData; } - private static void readXmlTag(XmlPullParser parser, HashMap<Short, String> data) - throws XmlPullParserException, IOException { - parser.require(XmlPullParser.START_TAG, null, XML_TAG); - short id = Integer.decode(parser.getAttributeValue(null, XML_TAG_ID)).shortValue(); - String value = ""; - if (parser.next() == XmlPullParser.TEXT) { - value = parser.getText(); - parser.next(); + static private int getIfdIdFromString(String prefix) { + if (IFD0.equals(prefix)) { + return IfdId.TYPE_IFD_0; + } else if (EXIF_IFD.equals(prefix)) { + return IfdId.TYPE_IFD_EXIF; + } else if (GPS_IFD.equals(prefix)) { + return IfdId.TYPE_IFD_GPS; + } else if (IFD1.equals(prefix)) { + return IfdId.TYPE_IFD_1; + } else if (INTEROP_IFD.equals(prefix)) { + return IfdId.TYPE_IFD_INTEROPERABILITY; + } else { + assert(false); + return -1; } - data.put(id, value); - parser.require(XmlPullParser.END_TAG, null, XML_TAG); } -}
\ No newline at end of file +} |