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 android.graphics.Bitmap;
     20 import android.graphics.BitmapFactory;
     21 
     22 import java.util.List;
     23 import java.util.Map;
     24 
     25 public class ExifParserTest extends ExifXmlDataTestCase {
     26     private static final String TAG = "ExifParserTest";
     27 
     28     private ExifInterface mInterface;
     29 
     30     public ExifParserTest(int imgRes, int xmlRes) {
     31         super(imgRes, xmlRes);
     32         mInterface = new ExifInterface();
     33     }
     34 
     35     public ExifParserTest(String imgPath, String xmlPath) {
     36         super(imgPath, xmlPath);
     37         mInterface = new ExifInterface();
     38     }
     39 
     40     private List<Map<Short, List<String>>> mGroundTruth;
     41 
     42     @Override
     43     public void setUp() throws Exception {
     44         super.setUp();
     45         mGroundTruth = ExifXmlReader.readXml(getXmlParser());
     46     }
     47 
     48     public void testParse() throws Exception {
     49         try {
     50             ExifParser parser = ExifParser.parse(getImageInputStream(), mInterface);
     51             int event = parser.next();
     52             while (event != ExifParser.EVENT_END) {
     53                 switch (event) {
     54                     case ExifParser.EVENT_START_OF_IFD:
     55                         break;
     56                     case ExifParser.EVENT_NEW_TAG:
     57                         ExifTag tag = parser.getTag();
     58                         if (!tag.hasValue()) {
     59                             parser.registerForTagValue(tag);
     60                         } else {
     61                             checkTag(tag);
     62                         }
     63                         break;
     64                     case ExifParser.EVENT_VALUE_OF_REGISTERED_TAG:
     65                         tag = parser.getTag();
     66                         if (tag.getDataType() == ExifTag.TYPE_UNDEFINED) {
     67                             byte[] buf = new byte[tag.getComponentCount()];
     68                             parser.read(buf);
     69                             assertTrue(TAG, tag.setValue(buf));
     70                         }
     71                         checkTag(tag);
     72                         break;
     73                 }
     74                 event = parser.next();
     75             }
     76         } catch (Exception e) {
     77             throw new Exception(getImageTitle(), e);
     78         }
     79     }
     80 
     81     private void checkTag(ExifTag tag) {
     82         List<String> truth = mGroundTruth.get(tag.getIfd()).get(tag.getTagId());
     83 
     84         if (truth == null) {
     85             fail(String.format("Unknown Tag %02x", tag.getTagId()) + ", " + getImageTitle());
     86         }
     87 
     88         // No value from exiftool.
     89         if (truth.contains(null)) {
     90             return;
     91         }
     92 
     93         String dataString = Util.tagValueToString(tag).trim();
     94         assertTrue(String.format("Tag %02x", tag.getTagId()) + ", " + getImageTitle()
     95                 + ": " + dataString,
     96                 truth.contains(dataString));
     97     }
     98 
     99     private void parseOneIfd(int ifd, int options) throws Exception {
    100         try {
    101             Map<Short, List<String>> expectedResult = mGroundTruth.get(ifd);
    102             int numOfTag = 0;
    103             ExifParser parser = ExifParser.parse(getImageInputStream(), options, mInterface);
    104             int event = parser.next();
    105             while (event != ExifParser.EVENT_END) {
    106                 switch (event) {
    107                     case ExifParser.EVENT_START_OF_IFD:
    108                         assertEquals(getImageTitle(), ifd, parser.getCurrentIfd());
    109                         break;
    110                     case ExifParser.EVENT_NEW_TAG:
    111                         ExifTag tag = parser.getTag();
    112                         numOfTag++;
    113                         if (tag.hasValue()) {
    114                             checkTag(tag);
    115                         } else {
    116                             parser.registerForTagValue(tag);
    117                         }
    118                         break;
    119                     case ExifParser.EVENT_VALUE_OF_REGISTERED_TAG:
    120                         tag = parser.getTag();
    121                         if (tag.getDataType() == ExifTag.TYPE_UNDEFINED) {
    122                             byte[] buf = new byte[tag.getComponentCount()];
    123                             parser.read(buf);
    124                             tag.setValue(buf);
    125                         }
    126                         checkTag(tag);
    127                         break;
    128                     case ExifParser.EVENT_COMPRESSED_IMAGE:
    129                     case ExifParser.EVENT_UNCOMPRESSED_STRIP:
    130                         fail("Invalid Event type: " + event + ", " + getImageTitle());
    131                         break;
    132                 }
    133                 event = parser.next();
    134             }
    135             assertEquals(getImageTitle(), ExifXmlReader.getTrueTagNumber(expectedResult), numOfTag);
    136         } catch (Exception e) {
    137             throw new Exception(getImageTitle(), e);
    138         }
    139     }
    140 
    141     public void testOnlyExifIfd() throws Exception {
    142         parseOneIfd(IfdId.TYPE_IFD_EXIF, ExifParser.OPTION_IFD_EXIF);
    143     }
    144 
    145     public void testOnlyIfd0() throws Exception {
    146         parseOneIfd(IfdId.TYPE_IFD_0, ExifParser.OPTION_IFD_0);
    147     }
    148 
    149     public void testOnlyIfd1() throws Exception {
    150         parseOneIfd(IfdId.TYPE_IFD_1, ExifParser.OPTION_IFD_1);
    151     }
    152 
    153     public void testOnlyInteroperabilityIfd() throws Exception {
    154         parseOneIfd(IfdId.TYPE_IFD_INTEROPERABILITY, ExifParser.OPTION_IFD_INTEROPERABILITY);
    155     }
    156 
    157     public void testOnlyReadSomeTag() throws Exception {
    158         // Do not do this test if there is no model tag.
    159         if (mGroundTruth.get(IfdId.TYPE_IFD_0).get(ExifInterface.TAG_MODEL) == null) {
    160             return;
    161         }
    162 
    163         try {
    164             ExifParser parser = ExifParser.parse(getImageInputStream(), ExifParser.OPTION_IFD_0,
    165                     mInterface);
    166             int event = parser.next();
    167             boolean isTagFound = false;
    168             while (event != ExifParser.EVENT_END) {
    169                 switch (event) {
    170                     case ExifParser.EVENT_START_OF_IFD:
    171                         assertEquals(getImageTitle(), IfdId.TYPE_IFD_0, parser.getCurrentIfd());
    172                         break;
    173                     case ExifParser.EVENT_NEW_TAG:
    174                         ExifTag tag = parser.getTag();
    175                         if (tag.getTagId() == ExifInterface.TAG_MODEL) {
    176                             if (tag.hasValue()) {
    177                                 isTagFound = true;
    178                                 checkTag(tag);
    179                             } else {
    180                                 parser.registerForTagValue(tag);
    181                             }
    182                             parser.skipRemainingTagsInCurrentIfd();
    183                         }
    184                         break;
    185                     case ExifParser.EVENT_VALUE_OF_REGISTERED_TAG:
    186                         tag = parser.getTag();
    187                         assertEquals(getImageTitle(), ExifInterface.TAG_MODEL, tag.getTagId());
    188                         checkTag(tag);
    189                         isTagFound = true;
    190                         break;
    191                 }
    192                 event = parser.next();
    193             }
    194             assertTrue(getImageTitle(), isTagFound);
    195         } catch (Exception e) {
    196             throw new Exception(getImageTitle(), e);
    197         }
    198     }
    199 
    200     public void testReadThumbnail() throws Exception {
    201         try {
    202             ExifParser parser = ExifParser.parse(getImageInputStream(),
    203                     ExifParser.OPTION_IFD_1 | ExifParser.OPTION_THUMBNAIL, mInterface);
    204 
    205             int event = parser.next();
    206             Bitmap bmp = null;
    207             boolean mIsContainCompressedImage = false;
    208             while (event != ExifParser.EVENT_END) {
    209                 switch (event) {
    210                     case ExifParser.EVENT_NEW_TAG:
    211                         ExifTag tag = parser.getTag();
    212                         if (tag.getTagId() == ExifInterface.TAG_COMPRESSION) {
    213                             if (tag.getValueAt(0) == ExifInterface.Compression.JPEG) {
    214                                 mIsContainCompressedImage = true;
    215                             }
    216                         }
    217                         break;
    218                     case ExifParser.EVENT_COMPRESSED_IMAGE:
    219                         int imageSize = parser.getCompressedImageSize();
    220                         byte buf[] = new byte[imageSize];
    221                         parser.read(buf);
    222                         bmp = BitmapFactory.decodeByteArray(buf, 0, imageSize);
    223                         break;
    224                 }
    225                 event = parser.next();
    226             }
    227             if (mIsContainCompressedImage) {
    228                 assertNotNull(getImageTitle(), bmp);
    229             }
    230         } catch (Exception e) {
    231             throw new Exception(getImageTitle(), e);
    232         }
    233     }
    234 }
    235