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