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.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