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.BitmapFactory; 20 21 import java.util.List; 22 import java.util.Map; 23 24 public class ExifReaderTest extends ExifXmlDataTestCase { 25 private static final String TAG = "ExifReaderTest"; 26 27 private ExifInterface mInterface; 28 private List<Map<Short, List<String>>> mGroundTruth; 29 30 @Override 31 public void setUp() throws Exception { 32 super.setUp(); 33 mGroundTruth = ExifXmlReader.readXml(getXmlParser()); 34 } 35 36 public ExifReaderTest(int imgRes, int xmlRes) { 37 super(imgRes, xmlRes); 38 mInterface = new ExifInterface(); 39 } 40 41 public ExifReaderTest(String imgPath, String xmlPath) { 42 super(imgPath, xmlPath); 43 mInterface = new ExifInterface(); 44 } 45 46 public void testRead() throws Exception { 47 try { 48 ExifReader reader = new ExifReader(mInterface); 49 ExifData exifData = reader.read(getImageInputStream()); 50 for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { 51 checkIfd(exifData.getIfdData(i), mGroundTruth.get(i)); 52 } 53 checkThumbnail(exifData); 54 } catch (Exception e) { 55 throw new Exception(getImageTitle(), e); 56 } 57 } 58 59 private void checkThumbnail(ExifData exifData) { 60 Map<Short, List<String>> ifd1Truth = mGroundTruth.get(IfdId.TYPE_IFD_1); 61 62 List<String> typeTagValue = ifd1Truth.get(ExifInterface.TAG_COMPRESSION); 63 if (typeTagValue == null) 64 return; 65 66 IfdData ifd1 = exifData.getIfdData(IfdId.TYPE_IFD_1); 67 if (ifd1 == null) 68 fail(getImageTitle() + ": failed to find IFD1"); 69 70 String typeTagTruth = typeTagValue.get(0); 71 72 int type = (int) ifd1.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_COMPRESSION)) 73 .getValueAt(0); 74 75 if (String.valueOf(ExifInterface.Compression.JPEG).equals(typeTagTruth)) { 76 assertTrue(getImageTitle(), type == ExifInterface.Compression.JPEG); 77 assertTrue(getImageTitle(), exifData.hasCompressedThumbnail()); 78 byte[] thumbnail = exifData.getCompressedThumbnail(); 79 assertTrue(getImageTitle(), 80 BitmapFactory.decodeByteArray(thumbnail, 0, thumbnail.length) != null); 81 } else if (String.valueOf(ExifInterface.Compression.UNCOMPRESSION).equals(typeTagTruth)) { 82 assertTrue(getImageTitle(), type == ExifInterface.Compression.UNCOMPRESSION); 83 // Try to check the strip count with the formula provided by EXIF spec. 84 int planarType = ExifInterface.PlanarConfiguration.CHUNKY; 85 ExifTag planarTag = ifd1.getTag(ExifInterface 86 .getTrueTagKey(ExifInterface.TAG_PLANAR_CONFIGURATION)); 87 if (planarTag != null) { 88 planarType = (int) planarTag.getValueAt(0); 89 } 90 91 if (!ifd1Truth.containsKey(ExifInterface.TAG_IMAGE_LENGTH) || 92 !ifd1Truth.containsKey(ExifInterface.TAG_ROWS_PER_STRIP)) { 93 return; 94 } 95 96 ExifTag heightTag = ifd1.getTag(ExifInterface 97 .getTrueTagKey(ExifInterface.TAG_IMAGE_LENGTH)); 98 ExifTag rowPerStripTag = ifd1.getTag(ExifInterface 99 .getTrueTagKey(ExifInterface.TAG_ROWS_PER_STRIP)); 100 101 // Fail the test if required tags are missing 102 if (heightTag == null || rowPerStripTag == null) { 103 fail(getImageTitle()); 104 } 105 106 int imageLength = (int) heightTag.getValueAt(0); 107 int rowsPerStrip = (int) rowPerStripTag.getValueAt(0); 108 int stripCount = ifd1.getTag( 109 ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_OFFSETS)) 110 .getComponentCount(); 111 112 if (planarType == ExifInterface.PlanarConfiguration.CHUNKY) { 113 assertTrue(getImageTitle(), 114 stripCount == (imageLength + rowsPerStrip - 1) / rowsPerStrip); 115 } else { 116 if (!ifd1Truth.containsKey(ExifInterface.TAG_SAMPLES_PER_PIXEL)) { 117 return; 118 } 119 ExifTag samplePerPixelTag = ifd1.getTag(ExifInterface 120 .getTrueTagKey(ExifInterface.TAG_SAMPLES_PER_PIXEL)); 121 int samplePerPixel = (int) samplePerPixelTag.getValueAt(0); 122 assertTrue(getImageTitle(), 123 stripCount == 124 (imageLength + rowsPerStrip - 1) / rowsPerStrip * samplePerPixel); 125 } 126 127 if (!ifd1Truth.containsKey(ExifInterface.TAG_STRIP_BYTE_COUNTS)) { 128 return; 129 } 130 ExifTag byteCountTag = ifd1.getTag(ExifInterface 131 .getTrueTagKey(ExifInterface.TAG_STRIP_BYTE_COUNTS)); 132 short byteCountDataType = byteCountTag.getDataType(); 133 for (int i = 0; i < stripCount; i++) { 134 if (byteCountDataType == ExifTag.TYPE_UNSIGNED_SHORT) { 135 assertEquals(getImageTitle(), 136 byteCountTag.getValueAt(i), exifData.getStrip(i).length); 137 } else { 138 assertEquals(getImageTitle(), 139 byteCountTag.getValueAt(i), exifData.getStrip(i).length); 140 } 141 } 142 } 143 } 144 145 private void checkIfd(IfdData ifd, Map<Short, List<String>> ifdValue) { 146 if (ifd == null) { 147 assertEquals(getImageTitle(), 0, ifdValue.size()); 148 return; 149 } 150 ExifTag[] tags = ifd.getAllTags(); 151 for (ExifTag tag : tags) { 152 List<String> truth = ifdValue.get(tag.getTagId()); 153 assertNotNull(String.format("Tag %x, ", tag.getTagId()) + getImageTitle(), truth); 154 if (truth.contains(null)) { 155 continue; 156 } 157 assertTrue(String.format("Tag %x, ", tag.getTagId()) + getImageTitle(), 158 truth.contains(Util.tagValueToString(tag).trim())); 159 } 160 assertEquals(getImageTitle(), ifdValue.size(), tags.length); 161 } 162 } 163