1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.gallery3d.exif; 18 19 import org.xmlpull.v1.XmlPullParser; 20 import org.xmlpull.v1.XmlPullParserException; 21 22 import java.io.IOException; 23 import java.util.ArrayList; 24 import java.util.HashMap; 25 import java.util.List; 26 import java.util.Map; 27 28 public class ExifXmlReader { 29 private static final String TAG_EXIF = "exif"; 30 private static final String TAG_TAG = "tag"; 31 32 private static final String IFD0 = "IFD0"; 33 private static final String EXIF_IFD = "ExifIFD"; 34 private static final String GPS_IFD = "GPS"; 35 private static final String IFD1 = "IFD1"; 36 private static final String INTEROP_IFD = "InteropIFD"; 37 38 private static final String ATTR_ID = "id"; 39 private static final String ATTR_IFD = "ifd"; 40 41 private static final String NO_VALUE = "NO_VALUE"; 42 43 /** 44 * This function read the ground truth XML. 45 * 46 * @throws XmlPullParserException 47 * @throws IOException 48 */ 49 static public List<Map<Short, List<String>>> readXml(XmlPullParser parser) 50 throws XmlPullParserException, IOException { 51 52 List<Map<Short, List<String>>> exifData = 53 new ArrayList<Map<Short, List<String>>>(IfdId.TYPE_IFD_COUNT); 54 for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { 55 exifData.add(new HashMap<Short, List<String>>()); 56 } 57 58 while (parser.next() != XmlPullParser.END_DOCUMENT) { 59 if (parser.getEventType() == XmlPullParser.START_TAG) { 60 break; 61 } 62 } 63 parser.require(XmlPullParser.START_TAG, null, TAG_EXIF); 64 65 while (parser.next() != XmlPullParser.END_TAG) { 66 if (parser.getEventType() != XmlPullParser.START_TAG) { 67 continue; 68 } 69 70 parser.require(XmlPullParser.START_TAG, null, TAG_TAG); 71 72 int ifdId = getIfdIdFromString(parser.getAttributeValue(null, ATTR_IFD)); 73 short id = Integer.decode(parser.getAttributeValue(null, ATTR_ID)).shortValue(); 74 75 String value = ""; 76 if (parser.next() == XmlPullParser.TEXT) { 77 value = parser.getText(); 78 parser.next(); 79 } 80 81 if (ifdId < 0) { 82 // TODO: the MarkerNote segment. 83 } else { 84 List<String> tagData = exifData.get(ifdId).get(id); 85 if (tagData == null) { 86 tagData = new ArrayList<String>(); 87 exifData.get(ifdId).put(id, tagData); 88 } 89 if (NO_VALUE.equals(value)) { 90 tagData.add(null); 91 } else { 92 tagData.add(value.trim()); 93 } 94 } 95 96 parser.require(XmlPullParser.END_TAG, null, null); 97 } 98 return exifData; 99 } 100 101 static private int getIfdIdFromString(String prefix) { 102 if (IFD0.equals(prefix)) { 103 return IfdId.TYPE_IFD_0; 104 } else if (EXIF_IFD.equals(prefix)) { 105 return IfdId.TYPE_IFD_EXIF; 106 } else if (GPS_IFD.equals(prefix)) { 107 return IfdId.TYPE_IFD_GPS; 108 } else if (IFD1.equals(prefix)) { 109 return IfdId.TYPE_IFD_1; 110 } else if (INTEROP_IFD.equals(prefix)) { 111 return IfdId.TYPE_IFD_INTEROPERABILITY; 112 } else { 113 assert (false); 114 return -1; 115 } 116 } 117 118 static public int getTrueTagNumber(Map<Short, List<String>> ifdData) { 119 int size = 0; 120 for (List<String> tag : ifdData.values()) { 121 size += tag.size(); 122 } 123 return size; 124 } 125 } 126