blob: 312d9aaa875018a7454f7b4ba4eb008c4a005f91 [file] [log] [blame]
Jaesung Chung15ef59e2016-02-25 14:12:32 +00001/*
2 * Copyright (C) 2016 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.mediaframeworktest.unit;
18
19import com.android.mediaframeworktest.R;
20
21import android.content.res.TypedArray;
22import android.graphics.Bitmap;
23import android.graphics.BitmapFactory;
24import android.media.ExifInterface;
25import android.os.Environment;
Jaesung Chung15ef59e2016-02-25 14:12:32 +000026import android.test.AndroidTestCase;
27import android.util.Log;
28import android.system.ErrnoException;
29import android.system.Os;
30import android.system.OsConstants;
31
Jaesung Chung6e08d2b2016-02-25 15:04:56 +090032import java.io.BufferedInputStream;
33import java.io.ByteArrayInputStream;
Jaesung Chung15ef59e2016-02-25 14:12:32 +000034import java.io.File;
35import java.io.FileDescriptor;
36import java.io.FileInputStream;
37import java.io.FileOutputStream;
38import java.io.InputStream;
39import java.io.IOException;
Jaesung Chung15ef59e2016-02-25 14:12:32 +000040
41import libcore.io.IoUtils;
42import libcore.io.Streams;
43
44public class ExifInterfaceTest extends AndroidTestCase {
45 private static final String TAG = ExifInterface.class.getSimpleName();
46 private static final boolean VERBOSE = false; // lots of logging
47
Insun Kang9e175f42016-03-29 11:46:11 +090048 private static final double DIFFERENCE_TOLERANCE = .001;
Jaesung Chung15ef59e2016-02-25 14:12:32 +000049
50 // List of files.
Jaesung Chung6e08d2b2016-02-25 15:04:56 +090051 private static final String EXIF_BYTE_ORDER_II_JPEG = "image_exif_byte_order_ii.jpg";
52 private static final String EXIF_BYTE_ORDER_MM_JPEG = "image_exif_byte_order_mm.jpg";
Jaesung Chung15ef59e2016-02-25 14:12:32 +000053 private static final String LG_G4_ISO_800_DNG = "lg_g4_iso_800.dng";
Jaesung Chungad76dc22016-03-08 22:09:21 +090054 private static final String VOLANTIS_JPEG = "volantis.jpg";
Jaesung Chung15ef59e2016-02-25 14:12:32 +000055 private static final int[] IMAGE_RESOURCES = new int[] {
Jaesung Chungad76dc22016-03-08 22:09:21 +090056 R.raw.image_exif_byte_order_ii, R.raw.image_exif_byte_order_mm, R.raw.lg_g4_iso_800,
57 R.raw.volantis };
Jaesung Chung15ef59e2016-02-25 14:12:32 +000058 private static final String[] IMAGE_FILENAMES = new String[] {
Jaesung Chungad76dc22016-03-08 22:09:21 +090059 EXIF_BYTE_ORDER_II_JPEG, EXIF_BYTE_ORDER_MM_JPEG, LG_G4_ISO_800_DNG, VOLANTIS_JPEG };
Jaesung Chung15ef59e2016-02-25 14:12:32 +000060
61 private static final String[] EXIF_TAGS = {
62 ExifInterface.TAG_MAKE,
63 ExifInterface.TAG_MODEL,
Insun Kang8884af32016-04-01 11:12:06 +090064 ExifInterface.TAG_F_NUMBER,
Jaesung Chung15ef59e2016-02-25 14:12:32 +000065 ExifInterface.TAG_DATETIME,
66 ExifInterface.TAG_EXPOSURE_TIME,
67 ExifInterface.TAG_FLASH,
68 ExifInterface.TAG_FOCAL_LENGTH,
69 ExifInterface.TAG_GPS_ALTITUDE,
70 ExifInterface.TAG_GPS_ALTITUDE_REF,
71 ExifInterface.TAG_GPS_DATESTAMP,
72 ExifInterface.TAG_GPS_LATITUDE,
73 ExifInterface.TAG_GPS_LATITUDE_REF,
74 ExifInterface.TAG_GPS_LONGITUDE,
75 ExifInterface.TAG_GPS_LONGITUDE_REF,
76 ExifInterface.TAG_GPS_PROCESSING_METHOD,
77 ExifInterface.TAG_GPS_TIMESTAMP,
78 ExifInterface.TAG_IMAGE_LENGTH,
79 ExifInterface.TAG_IMAGE_WIDTH,
Insun Kang8884af32016-04-01 11:12:06 +090080 ExifInterface.TAG_ISO_SPEED_RATINGS,
Jaesung Chung15ef59e2016-02-25 14:12:32 +000081 ExifInterface.TAG_ORIENTATION,
82 ExifInterface.TAG_WHITE_BALANCE
83 };
84
85 private static class ExpectedValue {
86 // Thumbnail information.
87 public final boolean hasThumbnail;
88 public final int thumbnailWidth;
89 public final int thumbnailHeight;
90
91 // GPS information.
92 public final boolean hasLatLong;
93 public final float latitude;
94 public final float longitude;
95 public final float altitude;
96
97 // Values.
98 public final String make;
99 public final String model;
100 public final float aperture;
101 public final String datetime;
102 public final float exposureTime;
103 public final float flash;
104 public final String focalLength;
105 public final String gpsAltitude;
106 public final String gpsAltitudeRef;
107 public final String gpsDatestamp;
108 public final String gpsLatitude;
109 public final String gpsLatitudeRef;
110 public final String gpsLongitude;
111 public final String gpsLongitudeRef;
112 public final String gpsProcessingMethod;
113 public final String gpsTimestamp;
Insun Kang9e175f42016-03-29 11:46:11 +0900114 public final int imageLength;
115 public final int imageWidth;
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000116 public final String iso;
Insun Kang9e175f42016-03-29 11:46:11 +0900117 public final int orientation;
118 public final int whiteBalance;
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000119
120 private static String getString(TypedArray typedArray, int index) {
121 String stringValue = typedArray.getString(index);
122 if (stringValue == null || stringValue.equals("")) {
123 return null;
124 }
125 return stringValue.trim();
126 }
127
128 public ExpectedValue(TypedArray typedArray) {
129 // Reads thumbnail information.
130 hasThumbnail = typedArray.getBoolean(0, false);
131 thumbnailWidth = typedArray.getInt(1, 0);
132 thumbnailHeight = typedArray.getInt(2, 0);
133
134 // Reads GPS information.
135 hasLatLong = typedArray.getBoolean(3, false);
136 latitude = typedArray.getFloat(4, 0f);
137 longitude = typedArray.getFloat(5, 0f);
138 altitude = typedArray.getFloat(6, 0f);
139
Insun Kang9e175f42016-03-29 11:46:11 +0900140 // Reads values.
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000141 make = getString(typedArray, 7);
142 model = getString(typedArray, 8);
143 aperture = typedArray.getFloat(9, 0f);
144 datetime = getString(typedArray, 10);
145 exposureTime = typedArray.getFloat(11, 0f);
146 flash = typedArray.getFloat(12, 0f);
147 focalLength = getString(typedArray, 13);
148 gpsAltitude = getString(typedArray, 14);
149 gpsAltitudeRef = getString(typedArray, 15);
150 gpsDatestamp = getString(typedArray, 16);
151 gpsLatitude = getString(typedArray, 17);
152 gpsLatitudeRef = getString(typedArray, 18);
153 gpsLongitude = getString(typedArray, 19);
154 gpsLongitudeRef = getString(typedArray, 20);
155 gpsProcessingMethod = getString(typedArray, 21);
156 gpsTimestamp = getString(typedArray, 22);
Insun Kang9e175f42016-03-29 11:46:11 +0900157 imageLength = typedArray.getInt(23, 0);
158 imageWidth = typedArray.getInt(24, 0);
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000159 iso = getString(typedArray, 25);
Insun Kang9e175f42016-03-29 11:46:11 +0900160 orientation = typedArray.getInt(26, 0);
161 whiteBalance = typedArray.getInt(27, 0);
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000162
163 typedArray.recycle();
164 }
165 }
166
167 @Override
168 protected void setUp() throws Exception {
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000169 for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
170 String outputPath = new File(Environment.getExternalStorageDirectory(),
171 IMAGE_FILENAMES[i]).getAbsolutePath();
172 try (InputStream inputStream = getContext().getResources().openRawResource(
173 IMAGE_RESOURCES[i])) {
174 try (FileOutputStream outputStream = new FileOutputStream(outputPath)) {
175 Streams.copy(inputStream, outputStream);
176 }
177 }
178 }
179 super.setUp();
180 }
181
182 @Override
183 protected void tearDown() throws Exception {
184 for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
185 String imageFilePath = new File(Environment.getExternalStorageDirectory(),
186 IMAGE_FILENAMES[i]).getAbsolutePath();
187 File imageFile = new File(imageFilePath);
188 if (imageFile.exists()) {
189 imageFile.delete();
190 }
191 }
192
193 super.tearDown();
194 }
195
196 private void printExifTagsAndValues(String fileName, ExifInterface exifInterface) {
197 // Prints thumbnail information.
198 if (exifInterface.hasThumbnail()) {
199 byte[] thumbnailBytes = exifInterface.getThumbnail();
200 if (thumbnailBytes != null) {
201 Log.v(TAG, fileName + " Thumbnail size = " + thumbnailBytes.length);
202 Bitmap bitmap = BitmapFactory.decodeByteArray(
203 thumbnailBytes, 0, thumbnailBytes.length);
204 if (bitmap == null) {
205 Log.e(TAG, fileName + " Corrupted thumbnail!");
206 } else {
207 Log.v(TAG, fileName + " Thumbnail size: " + bitmap.getWidth() + ", "
208 + bitmap.getHeight());
209 }
210 } else {
Insun Kang9e175f42016-03-29 11:46:11 +0900211 Log.e(TAG, fileName + " Unexpected result: No thumbnails were found. "
212 + "A thumbnail is expected.");
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000213 }
214 } else {
215 if (exifInterface.getThumbnail() != null) {
Insun Kang9e175f42016-03-29 11:46:11 +0900216 Log.e(TAG, fileName + " Unexpected result: A thumbnail was found. "
217 + "No thumbnail is expected.");
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000218 } else {
219 Log.v(TAG, fileName + " No thumbnail");
220 }
221 }
222
223 // Prints GPS information.
224 Log.v(TAG, fileName + " Altitude = " + exifInterface.getAltitude(.0));
225
226 float[] latLong = new float[2];
227 if (exifInterface.getLatLong(latLong)) {
228 Log.v(TAG, fileName + " Latitude = " + latLong[0]);
229 Log.v(TAG, fileName + " Longitude = " + latLong[1]);
230 } else {
Insun Kang9e175f42016-03-29 11:46:11 +0900231 Log.v(TAG, fileName + " No latlong data");
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000232 }
233
234 // Prints values.
235 for (String tagKey : EXIF_TAGS) {
236 String tagValue = exifInterface.getAttribute(tagKey);
Insun Kang9e175f42016-03-29 11:46:11 +0900237 Log.v(TAG, fileName + " Key{" + tagKey + "} = '" + tagValue + "'");
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000238 }
239 }
240
Insun Kang9e175f42016-03-29 11:46:11 +0900241 private void assertIntTag(ExifInterface exifInterface, String tag, int expectedValue) {
242 int intValue = exifInterface.getAttributeInt(tag, 0);
243 assertEquals(expectedValue, intValue);
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000244 }
245
Insun Kang9e175f42016-03-29 11:46:11 +0900246 private void assertFloatTag(ExifInterface exifInterface, String tag, float expectedValue) {
247 double doubleValue = exifInterface.getAttributeDouble(tag, 0.0);
248 assertEquals(expectedValue, doubleValue, DIFFERENCE_TOLERANCE);
249 }
250
251 private void assertStringTag(ExifInterface exifInterface, String tag, String expectedValue) {
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000252 String stringValue = exifInterface.getAttribute(tag);
253 if (stringValue != null) {
254 stringValue = stringValue.trim();
255 }
256
257 assertEquals(expectedValue, stringValue);
258 }
259
260 private void compareWithExpectedValue(ExifInterface exifInterface,
Insun Kang9e175f42016-03-29 11:46:11 +0900261 ExpectedValue expectedValue, String verboseTag) {
262 if (VERBOSE) {
263 printExifTagsAndValues(verboseTag, exifInterface);
264 }
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000265 // Checks a thumbnail image.
266 assertEquals(expectedValue.hasThumbnail, exifInterface.hasThumbnail());
267 if (expectedValue.hasThumbnail) {
268 byte[] thumbnailBytes = exifInterface.getThumbnail();
269 assertNotNull(thumbnailBytes);
270 Bitmap thumbnailBitmap =
271 BitmapFactory.decodeByteArray(thumbnailBytes, 0, thumbnailBytes.length);
272 assertNotNull(thumbnailBitmap);
273 assertEquals(expectedValue.thumbnailWidth, thumbnailBitmap.getWidth());
274 assertEquals(expectedValue.thumbnailHeight, thumbnailBitmap.getHeight());
275 } else {
276 assertNull(exifInterface.getThumbnail());
277 }
278
279 // Checks GPS information.
280 float[] latLong = new float[2];
281 assertEquals(expectedValue.hasLatLong, exifInterface.getLatLong(latLong));
282 if (expectedValue.hasLatLong) {
283 assertEquals(expectedValue.latitude, latLong[0], DIFFERENCE_TOLERANCE);
284 assertEquals(expectedValue.longitude, latLong[1], DIFFERENCE_TOLERANCE);
285 }
286 assertEquals(expectedValue.altitude, exifInterface.getAltitude(.0), DIFFERENCE_TOLERANCE);
287
288 // Checks values.
Insun Kang9e175f42016-03-29 11:46:11 +0900289 assertStringTag(exifInterface, ExifInterface.TAG_MAKE, expectedValue.make);
290 assertStringTag(exifInterface, ExifInterface.TAG_MODEL, expectedValue.model);
Insun Kang8884af32016-04-01 11:12:06 +0900291 assertFloatTag(exifInterface, ExifInterface.TAG_F_NUMBER, expectedValue.aperture);
Insun Kang9e175f42016-03-29 11:46:11 +0900292 assertStringTag(exifInterface, ExifInterface.TAG_DATETIME, expectedValue.datetime);
293 assertFloatTag(exifInterface, ExifInterface.TAG_EXPOSURE_TIME, expectedValue.exposureTime);
294 assertFloatTag(exifInterface, ExifInterface.TAG_FLASH, expectedValue.flash);
295 assertStringTag(exifInterface, ExifInterface.TAG_FOCAL_LENGTH, expectedValue.focalLength);
296 assertStringTag(exifInterface, ExifInterface.TAG_GPS_ALTITUDE, expectedValue.gpsAltitude);
297 assertStringTag(exifInterface, ExifInterface.TAG_GPS_ALTITUDE_REF,
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000298 expectedValue.gpsAltitudeRef);
Insun Kang9e175f42016-03-29 11:46:11 +0900299 assertStringTag(exifInterface, ExifInterface.TAG_GPS_DATESTAMP, expectedValue.gpsDatestamp);
300 assertStringTag(exifInterface, ExifInterface.TAG_GPS_LATITUDE, expectedValue.gpsLatitude);
301 assertStringTag(exifInterface, ExifInterface.TAG_GPS_LATITUDE_REF,
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000302 expectedValue.gpsLatitudeRef);
Insun Kang9e175f42016-03-29 11:46:11 +0900303 assertStringTag(exifInterface, ExifInterface.TAG_GPS_LONGITUDE, expectedValue.gpsLongitude);
304 assertStringTag(exifInterface, ExifInterface.TAG_GPS_LONGITUDE_REF,
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000305 expectedValue.gpsLongitudeRef);
Insun Kang9e175f42016-03-29 11:46:11 +0900306 assertStringTag(exifInterface, ExifInterface.TAG_GPS_PROCESSING_METHOD,
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000307 expectedValue.gpsProcessingMethod);
Insun Kang9e175f42016-03-29 11:46:11 +0900308 assertStringTag(exifInterface, ExifInterface.TAG_GPS_TIMESTAMP, expectedValue.gpsTimestamp);
309 assertIntTag(exifInterface, ExifInterface.TAG_IMAGE_LENGTH, expectedValue.imageLength);
310 assertIntTag(exifInterface, ExifInterface.TAG_IMAGE_WIDTH, expectedValue.imageWidth);
Insun Kang8884af32016-04-01 11:12:06 +0900311 assertStringTag(exifInterface, ExifInterface.TAG_ISO_SPEED_RATINGS, expectedValue.iso);
Insun Kang9e175f42016-03-29 11:46:11 +0900312 assertIntTag(exifInterface, ExifInterface.TAG_ORIENTATION, expectedValue.orientation);
313 assertIntTag(exifInterface, ExifInterface.TAG_WHITE_BALANCE, expectedValue.whiteBalance);
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000314 }
315
Jaesung Chung6e08d2b2016-02-25 15:04:56 +0900316 private void testExifInterfaceCommon(File imageFile, ExpectedValue expectedValue)
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000317 throws IOException {
Insun Kang9e175f42016-03-29 11:46:11 +0900318 String verboseTag = imageFile.getName();
319
320 // Creates via path.
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000321 ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath());
Insun Kang9e175f42016-03-29 11:46:11 +0900322 compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
Jaesung Chung6e08d2b2016-02-25 15:04:56 +0900323
Insun Kang9e175f42016-03-29 11:46:11 +0900324 // Creates from an asset file.
325 InputStream in = null;
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000326 try {
Insun Kang9e175f42016-03-29 11:46:11 +0900327 in = mContext.getAssets().open(imageFile.getName());
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000328 exifInterface = new ExifInterface(in);
Insun Kang9e175f42016-03-29 11:46:11 +0900329 compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000330 } finally {
331 IoUtils.closeQuietly(in);
332 }
333
Insun Kang9e175f42016-03-29 11:46:11 +0900334 // Creates via InputStream.
335 in = null;
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000336 try {
Insun Kang9e175f42016-03-29 11:46:11 +0900337 in = new BufferedInputStream(new FileInputStream(imageFile.getAbsolutePath()));
338 exifInterface = new ExifInterface(in);
339 compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
340 } finally {
341 IoUtils.closeQuietly(in);
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000342 }
Insun Kang9e175f42016-03-29 11:46:11 +0900343
344 // Creates via FileDescriptor.
345 FileDescriptor fd = null;
346 try {
347 fd = Os.open(imageFile.getAbsolutePath(), OsConstants.O_RDONLY, 0600);
348 exifInterface = new ExifInterface(fd);
349 compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
350 } catch (ErrnoException e) {
351 throw e.rethrowAsIOException();
352 } finally {
353 IoUtils.closeQuietly(fd);
354 }
355 }
356
357 private void testSaveAttributes_withFileName(File imageFile, ExpectedValue expectedValue)
358 throws IOException {
359 String verboseTag = imageFile.getName();
360
361 ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath());
362 exifInterface.saveAttributes();
363 exifInterface = new ExifInterface(imageFile.getAbsolutePath());
364 compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
365
366 // Test for modifying one attribute.
367 String backupValue = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
368 exifInterface.setAttribute(ExifInterface.TAG_MAKE, "abc");
369 exifInterface.saveAttributes();
370 exifInterface = new ExifInterface(imageFile.getAbsolutePath());
371 assertEquals("abc", exifInterface.getAttribute(ExifInterface.TAG_MAKE));
372 // Restore the backup value.
373 exifInterface.setAttribute(ExifInterface.TAG_MAKE, backupValue);
374 exifInterface.saveAttributes();
375 exifInterface = new ExifInterface(imageFile.getAbsolutePath());
376 compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
377 }
378
379 private void testSaveAttributes_withFileDescriptor(File imageFile, ExpectedValue expectedValue)
380 throws IOException {
381 String verboseTag = imageFile.getName();
382
383 FileDescriptor fd = null;
384 try {
385 fd = Os.open(imageFile.getAbsolutePath(), OsConstants.O_RDWR, 0600);
386 ExifInterface exifInterface = new ExifInterface(fd);
387 exifInterface.saveAttributes();
388 Os.lseek(fd, 0, OsConstants.SEEK_SET);
389 exifInterface = new ExifInterface(fd);
390 compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
391
392 // Test for modifying one attribute.
393 String backupValue = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
394 exifInterface.setAttribute(ExifInterface.TAG_MAKE, "abc");
395 exifInterface.saveAttributes();
396 Os.lseek(fd, 0, OsConstants.SEEK_SET);
397 exifInterface = new ExifInterface(fd);
398 assertEquals("abc", exifInterface.getAttribute(ExifInterface.TAG_MAKE));
399 // Restore the backup value.
400 exifInterface.setAttribute(ExifInterface.TAG_MAKE, backupValue);
401 exifInterface.saveAttributes();
402 Os.lseek(fd, 0, OsConstants.SEEK_SET);
403 exifInterface = new ExifInterface(fd);
404 compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
405 } catch (ErrnoException e) {
406 throw e.rethrowAsIOException();
407 } finally {
408 IoUtils.closeQuietly(fd);
409 }
410 }
411
412 private void testSaveAttributes_withInputStream(File imageFile, ExpectedValue expectedValue)
413 throws IOException {
414 InputStream in = null;
415 try {
416 in = getContext().getAssets().open(imageFile.getName());
417 ExifInterface exifInterface = new ExifInterface(in);
418 exifInterface.saveAttributes();
419 } catch (UnsupportedOperationException e) {
420 // Expected. saveAttributes is not supported with an ExifInterface object which was
421 // created with InputStream.
422 return;
423 } finally {
424 IoUtils.closeQuietly(in);
425 }
426 fail("Should not reach here!");
Jaesung Chung6e08d2b2016-02-25 15:04:56 +0900427 }
428
429 private void testExifInterfaceForJpeg(String fileName, int typedArrayResourceId)
430 throws IOException {
431 ExpectedValue expectedValue = new ExpectedValue(
432 getContext().getResources().obtainTypedArray(typedArrayResourceId));
433 File imageFile = new File(Environment.getExternalStorageDirectory(), fileName);
434
435 // Test for reading from various inputs.
436 testExifInterfaceCommon(imageFile, expectedValue);
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000437
438 // Test for saving attributes.
Insun Kang9e175f42016-03-29 11:46:11 +0900439 testSaveAttributes_withFileName(imageFile, expectedValue);
440 testSaveAttributes_withFileDescriptor(imageFile, expectedValue);
441 testSaveAttributes_withInputStream(imageFile, expectedValue);
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000442 }
443
444 private void testExifInterfaceForRaw(String fileName, int typedArrayResourceId)
445 throws IOException {
446 ExpectedValue expectedValue = new ExpectedValue(
447 getContext().getResources().obtainTypedArray(typedArrayResourceId));
448 File imageFile = new File(Environment.getExternalStorageDirectory(), fileName);
449
Jaesung Chung6e08d2b2016-02-25 15:04:56 +0900450 // Test for reading from various inputs.
451 testExifInterfaceCommon(imageFile, expectedValue);
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000452
Jaesung Chung6e08d2b2016-02-25 15:04:56 +0900453 // Since ExifInterface does not support for saving attributes for RAW files, do not test
454 // about writing back in here.
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000455 }
456
457 public void testReadExifDataFromExifByteOrderIIJpeg() throws Throwable {
458 testExifInterfaceForJpeg(EXIF_BYTE_ORDER_II_JPEG, R.array.exifbyteorderii_jpg);
459 }
460
461 public void testReadExifDataFromExifByteOrderMMJpeg() throws Throwable {
462 testExifInterfaceForJpeg(EXIF_BYTE_ORDER_MM_JPEG, R.array.exifbyteordermm_jpg);
463 }
464
465 public void testReadExifDataFromLgG4Iso800Dng() throws Throwable {
466 testExifInterfaceForRaw(LG_G4_ISO_800_DNG, R.array.lg_g4_iso_800_dng);
467 }
Jaesung Chung6e08d2b2016-02-25 15:04:56 +0900468
Jaesung Chung42ac0d02016-03-22 11:43:11 -0700469 public void testDoNotFailOnCorruptedImage() throws Throwable {
470 // To keep the compatibility with old versions of ExifInterface, even on a corrupted image,
471 // it shouldn't raise any exceptions except an IOException when unable to open a file.
Jaesung Chung6e08d2b2016-02-25 15:04:56 +0900472 byte[] bytes = new byte[1024];
473 try {
474 new ExifInterface(new ByteArrayInputStream(bytes));
Jaesung Chung42ac0d02016-03-22 11:43:11 -0700475 // Always success
Jaesung Chung6e08d2b2016-02-25 15:04:56 +0900476 } catch (IOException e) {
Jaesung Chung42ac0d02016-03-22 11:43:11 -0700477 fail("Should not reach here!");
Jaesung Chung6e08d2b2016-02-25 15:04:56 +0900478 }
479 }
Jaesung Chungad76dc22016-03-08 22:09:21 +0900480
481 public void testReadExifDataFromVolantisJpg() throws Throwable {
482 // Test if it is possible to parse the volantis generated JPEG smoothly.
483 testExifInterfaceForJpeg(VOLANTIS_JPEG, R.array.volantis_jpg);
484 }
Jaesung Chung15ef59e2016-02-25 14:12:32 +0000485}