Home | History | Annotate | Download | only in exif
      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