ExifModifierTest.java revision 6e6a524390d8ddebce5de0dcc8ae258e652ec80a
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 17package com.android.gallery3d.exif; 18 19import java.io.File; 20import java.io.FileInputStream; 21import java.io.FileOutputStream; 22import java.io.InputStream; 23import java.io.RandomAccessFile; 24import java.nio.MappedByteBuffer; 25import java.nio.channels.FileChannel.MapMode; 26import java.util.HashMap; 27import java.util.List; 28import java.util.Map; 29 30public class ExifModifierTest extends ExifXmlDataTestCase { 31 32 private File mTmpFile; 33 private List<Map<Short, List<String>>> mGroundTruth; 34 private ExifInterface mInterface; 35 private Map<Short, ExifTag> mTestTags; 36 ExifTag mVersionTag; 37 ExifTag mGpsVersionTag; 38 ExifTag mModelTag; 39 ExifTag mDateTimeTag; 40 ExifTag mCompressionTag; 41 ExifTag mThumbnailFormatTag; 42 ExifTag mLongitudeTag; 43 ExifTag mShutterTag; 44 45 @Override 46 public void setUp() throws Exception { 47 super.setUp(); 48 mGroundTruth = ExifXmlReader.readXml(getXmlParser()); 49 mTmpFile = File.createTempFile("exif_test", ".jpg"); 50 FileOutputStream os = null; 51 InputStream is = getImageInputStream(); 52 try { 53 os = new FileOutputStream(mTmpFile); 54 byte[] buf = new byte[1024]; 55 int n; 56 while ((n = is.read(buf)) > 0) { 57 os.write(buf, 0, n); 58 } 59 } finally { 60 Util.closeSilently(os); 61 } 62 63 // TYPE_UNDEFINED with 4 components 64 mVersionTag = mInterface.buildTag(ExifInterface.TAG_EXIF_VERSION, new byte[] { 65 1, 2, 3, 4 66 }); 67 // TYPE_UNSIGNED_BYTE with 4 components 68 mGpsVersionTag = mInterface.buildTag(ExifInterface.TAG_GPS_VERSION_ID, new byte[] { 69 4, 3, 2, 1 70 }); 71 // TYPE ASCII with arbitary length 72 mModelTag = mInterface.buildTag(ExifInterface.TAG_MODEL, "end-of-the-world"); 73 // TYPE_ASCII with 20 components 74 mDateTimeTag = mInterface.buildTag(ExifInterface.TAG_DATE_TIME, "2012:12:31 23:59:59"); 75 // TYPE_UNSIGNED_SHORT with 1 components 76 mCompressionTag = mInterface.buildTag(ExifInterface.TAG_COMPRESSION, 100); 77 // TYPE_UNSIGNED_LONG with 1 components 78 mThumbnailFormatTag = 79 mInterface.buildTag(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT, 100); 80 // TYPE_UNSIGNED_RATIONAL with 3 components 81 mLongitudeTag = mInterface.buildTag(ExifInterface.TAG_GPS_LONGITUDE, new Rational[] { 82 new Rational(1, 1), new Rational(10, 10), 83 new Rational(100, 100) 84 }); 85 // TYPE_RATIONAL with 1 components 86 mShutterTag = mInterface 87 .buildTag(ExifInterface.TAG_SHUTTER_SPEED_VALUE, new Rational(1, 1)); 88 89 mTestTags = new HashMap<Short, ExifTag>(); 90 91 mTestTags.put(mVersionTag.getTagId(), mVersionTag); 92 mTestTags.put(mGpsVersionTag.getTagId(), mGpsVersionTag); 93 mTestTags.put(mModelTag.getTagId(), mModelTag); 94 mTestTags.put(mDateTimeTag.getTagId(), mDateTimeTag); 95 mTestTags.put(mCompressionTag.getTagId(), mCompressionTag); 96 mTestTags.put(mThumbnailFormatTag.getTagId(), mThumbnailFormatTag); 97 mTestTags.put(mLongitudeTag.getTagId(), mLongitudeTag); 98 mTestTags.put(mShutterTag.getTagId(), mShutterTag); 99 } 100 101 public ExifModifierTest(int imageRes, int xmlRes) { 102 super(imageRes, xmlRes); 103 mInterface = new ExifInterface(); 104 } 105 106 public ExifModifierTest(String imagePath, String xmlPath) { 107 super(imagePath, xmlPath); 108 mInterface = new ExifInterface(); 109 } 110 111 public void testModify() throws Exception { 112 Map<Short, Boolean> results = new HashMap<Short, Boolean>(); 113 114 RandomAccessFile file = null; 115 try { 116 file = new RandomAccessFile(mTmpFile, "rw"); 117 MappedByteBuffer buf = file.getChannel().map(MapMode.READ_WRITE, 0, file.length()); 118 for (ExifTag tag : mTestTags.values()) { 119 ExifModifier modifier = new ExifModifier(buf, mInterface); 120 modifier.modifyTag(tag); 121 boolean result = modifier.commit(); 122 results.put(tag.getTagId(), result); 123 buf.force(); 124 buf.position(0); 125 126 if (!result) { 127 List<String> value = mGroundTruth.get(tag.getIfd()).get(tag.getTagId()); 128 assertTrue(String.format("Tag %x, ", tag.getTagId()) + getImageTitle(), 129 value == null || tag.getTagId() == ExifInterface.TAG_MODEL); 130 } 131 } 132 } finally { 133 Util.closeSilently(file); 134 } 135 136 // Parse the new file and check the result 137 InputStream is = null; 138 try { 139 is = new FileInputStream(mTmpFile); 140 ExifData data = new ExifReader(mInterface).read(is); 141 for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { 142 checkIfd(data.getIfdData(i), mGroundTruth.get(i), results); 143 } 144 } finally { 145 Util.closeSilently(is); 146 } 147 148 } 149 150 private void checkIfd(IfdData ifd, Map<Short, List<String>> ifdValue, 151 Map<Short, Boolean> results) { 152 if (ifd == null) { 153 assertEquals(getImageTitle(), 0, ifdValue.size()); 154 return; 155 } 156 ExifTag[] tags = ifd.getAllTags(); 157 for (ExifTag tag : tags) { 158 List<String> truth = ifdValue.get(tag.getTagId()); 159 assertNotNull(String.format("Tag %x, ", tag.getTagId()) + getImageTitle(), truth); 160 if (truth.contains(null)) { 161 continue; 162 } 163 164 ExifTag newTag = mTestTags.get(tag.getTagId()); 165 if (newTag != null 166 && results.get(tag.getTagId())) { 167 assertEquals(String.format("Tag %x, ", tag.getTagId()) + getImageTitle(), 168 Util.tagValueToString(newTag), Util.tagValueToString(tag)); 169 } else { 170 assertTrue(String.format("Tag %x, ", tag.getTagId()) + getImageTitle(), 171 truth.contains(Util.tagValueToString(tag).trim())); 172 } 173 } 174 assertEquals(getImageTitle(), ifdValue.size(), tags.length); 175 } 176 177 @Override 178 public void tearDown() throws Exception { 179 super.tearDown(); 180 mTmpFile.delete(); 181 } 182} 183