diff options
author | Sungsoo Lim <sungsoo@google.com> | 2016-07-12 14:50:00 +0900 |
---|---|---|
committer | gitbuildkicker <android-build@google.com> | 2016-07-21 17:03:39 -0700 |
commit | eb62f8b1f7da73783bd22f72492e33cf975c5f99 (patch) | |
tree | 6f623fbcc1af9fbda650c5ba9e0e190456e6ce9b | |
parent | c238e74d3a39270ef6b2a62636d6da8c7474db4a (diff) | |
download | cts-marshmallow-dr1.6-release.tar.gz |
DO NOT MERGE: Add CTS for ExifInterfaceTestandroid-6.0.1_r68android-6.0.1_r67marshmallow-dr1.6-release
Bug: 29270469
Change-Id: I774f0544084475bd0caaf3f1a49a48de7f4edfaa
-rw-r--r-- | tests/tests/media/res/raw/image_exif_byte_order_ii.jpg | bin | 0 -> 105271 bytes | |||
-rw-r--r-- | tests/tests/media/res/raw/image_exif_byte_order_mm.jpg | bin | 0 -> 8610 bytes | |||
-rw-r--r-- | tests/tests/media/res/raw/image_exif_malformed.jpg | bin | 0 -> 7736 bytes | |||
-rw-r--r-- | tests/tests/media/res/raw/lg_g4_iso_800.dng | bin | 0 -> 129312 bytes | |||
-rw-r--r-- | tests/tests/media/res/values/exifinterface.xml | 74 | ||||
-rw-r--r-- | tests/tests/media/src/android/media/cts/ExifInterfaceTest.java | 393 |
6 files changed, 467 insertions, 0 deletions
diff --git a/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg b/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg Binary files differnew file mode 100644 index 00000000000..477cd3a574c --- /dev/null +++ b/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg diff --git a/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg b/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg Binary files differnew file mode 100644 index 00000000000..78ac703850a --- /dev/null +++ b/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg diff --git a/tests/tests/media/res/raw/image_exif_malformed.jpg b/tests/tests/media/res/raw/image_exif_malformed.jpg Binary files differnew file mode 100644 index 00000000000..5b1fb7e14ce --- /dev/null +++ b/tests/tests/media/res/raw/image_exif_malformed.jpg diff --git a/tests/tests/media/res/raw/lg_g4_iso_800.dng b/tests/tests/media/res/raw/lg_g4_iso_800.dng Binary files differnew file mode 100644 index 00000000000..5fcc720a5f8 --- /dev/null +++ b/tests/tests/media/res/raw/lg_g4_iso_800.dng diff --git a/tests/tests/media/res/values/exifinterface.xml b/tests/tests/media/res/values/exifinterface.xml new file mode 100644 index 00000000000..0bb1bfd2c0e --- /dev/null +++ b/tests/tests/media/res/values/exifinterface.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 The Android Open Source Project + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <array name="exifbyteorderii_jpg"> + <item>true</item> + <item>512</item> + <item>288</item> + <item>false</item> + <item>0.0</item> + <item>0.0</item> + <item>0.0</item> + <item>SAMSUNG</item> + <item>SM-N900S</item> + <item>2.200</item> + <item>2016:01:29 18:32:27</item> + <item>0.033</item> + <item>0</item> + <item>413/100</item> + <item /> + <item /> + <item /> + <item /> + <item /> + <item /> + <item /> + <item /> + <item /> + <item>480</item> + <item>640</item> + <item>50</item> + <item>6</item> + <item>0</item> + </array> + <array name="exifbyteordermm_jpg"> + <item>false</item> + <item>0</item> + <item>0</item> + <item>true</item> + <item>0.0</item> + <item>0.0</item> + <item>0.0</item> + <item>LGE</item> + <item>Nexus 5</item> + <item>2.400</item> + <item>2016:01:29 15:44:58</item> + <item>0.017</item> + <item>0</item> + <item>3970/1000</item> + <item>0/1000</item> + <item>0</item> + <item>1970:01:01</item> + <item>0/1,0/1,0/10000</item> + <item>N</item> + <item>0/1,0/1,0/10000</item> + <item>E</item> + <item>GPS</item> + <item>00:00:00</item> + <item>176</item> + <item>144</item> + <item>146</item> + <item>0</item> + <item>0</item> + </array> +</resources>
\ No newline at end of file diff --git a/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java new file mode 100644 index 00000000000..68f4e733bfc --- /dev/null +++ b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.cts; + +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.media.ExifInterface; +import android.os.Environment; +import android.test.AndroidTestCase; +import android.util.Log; +import android.system.ErrnoException; +import android.system.Os; +import android.system.OsConstants; + +import com.android.cts.media.R; + +import libcore.io.Streams; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.lang.reflect.Type; + +public class ExifInterfaceTest extends AndroidTestCase { + private static final String TAG = ExifInterface.class.getSimpleName(); + private static final boolean VERBOSE = false; // lots of logging + + private static final double DIFFERENCE_TOLERANCE = .001; + + // List of files. + private static final String EXIF_BYTE_ORDER_II_JPEG = "image_exif_byte_order_ii.jpg"; + private static final String EXIF_BYTE_ORDER_MM_JPEG = "image_exif_byte_order_mm.jpg"; + private static final String EXIF_MALFORMED_JPEG = "image_exif_malformed.jpg"; + private static final int[] IMAGE_RESOURCES = new int[] { R.raw.image_exif_byte_order_ii, + R.raw.image_exif_byte_order_mm, R.raw.image_exif_malformed }; + private static final String[] IMAGE_FILENAMES = new String[] { EXIF_BYTE_ORDER_II_JPEG, + EXIF_BYTE_ORDER_MM_JPEG, EXIF_MALFORMED_JPEG }; + + private static final String[] EXIF_TAGS = { + ExifInterface.TAG_MAKE, + ExifInterface.TAG_MODEL, + ExifInterface.TAG_APERTURE, + ExifInterface.TAG_DATETIME, + ExifInterface.TAG_EXPOSURE_TIME, + ExifInterface.TAG_FLASH, + ExifInterface.TAG_FOCAL_LENGTH, + ExifInterface.TAG_GPS_ALTITUDE, + ExifInterface.TAG_GPS_ALTITUDE_REF, + ExifInterface.TAG_GPS_DATESTAMP, + ExifInterface.TAG_GPS_LATITUDE, + ExifInterface.TAG_GPS_LATITUDE_REF, + ExifInterface.TAG_GPS_LONGITUDE, + ExifInterface.TAG_GPS_LONGITUDE_REF, + ExifInterface.TAG_GPS_PROCESSING_METHOD, + ExifInterface.TAG_GPS_TIMESTAMP, + ExifInterface.TAG_IMAGE_LENGTH, + ExifInterface.TAG_IMAGE_WIDTH, + ExifInterface.TAG_ISO, + ExifInterface.TAG_ORIENTATION, + ExifInterface.TAG_WHITE_BALANCE + }; + + private static class ExpectedValue { + // Thumbnail information. + public final boolean hasThumbnail; + public final int thumbnailWidth; + public final int thumbnailHeight; + + // GPS information. + public final boolean hasLatLong; + public final float latitude; + public final float longitude; + public final float altitude; + + // Values. + public final String make; + public final String model; + public final float aperture; + public final String datetime; + public final float exposureTime; + public final float flash; + public final String focalLength; + public final String gpsAltitude; + public final String gpsAltitudeRef; + public final String gpsDatestamp; + public final String gpsLatitude; + public final String gpsLatitudeRef; + public final String gpsLongitude; + public final String gpsLongitudeRef; + public final String gpsProcessingMethod; + public final String gpsTimestamp; + public final int imageLength; + public final int imageWidth; + public final String iso; + public final int orientation; + public final int whiteBalance; + + private static String getString(TypedArray typedArray, int index) { + String stringValue = typedArray.getString(index); + if (stringValue == null || stringValue.equals("")) { + return null; + } + return stringValue.trim(); + } + + public ExpectedValue(TypedArray typedArray) { + // Reads thumbnail information. + hasThumbnail = typedArray.getBoolean(0, false); + thumbnailWidth = typedArray.getInt(1, 0); + thumbnailHeight = typedArray.getInt(2, 0); + + // Reads GPS information. + hasLatLong = typedArray.getBoolean(3, false); + latitude = typedArray.getFloat(4, 0f); + longitude = typedArray.getFloat(5, 0f); + altitude = typedArray.getFloat(6, 0f); + + // Reads values. + make = getString(typedArray, 7); + model = getString(typedArray, 8); + aperture = typedArray.getFloat(9, 0f); + datetime = getString(typedArray, 10); + exposureTime = typedArray.getFloat(11, 0f); + flash = typedArray.getFloat(12, 0f); + focalLength = getString(typedArray, 13); + gpsAltitude = getString(typedArray, 14); + gpsAltitudeRef = getString(typedArray, 15); + gpsDatestamp = getString(typedArray, 16); + gpsLatitude = getString(typedArray, 17); + gpsLatitudeRef = getString(typedArray, 18); + gpsLongitude = getString(typedArray, 19); + gpsLongitudeRef = getString(typedArray, 20); + gpsProcessingMethod = getString(typedArray, 21); + gpsTimestamp = getString(typedArray, 22); + imageLength = typedArray.getInt(23, 0); + imageWidth = typedArray.getInt(24, 0); + iso = getString(typedArray, 25); + orientation = typedArray.getInt(26, 0); + whiteBalance = typedArray.getInt(27, 0); + + typedArray.recycle(); + } + } + + @Override + protected void setUp() throws Exception { + for (int i = 0; i < IMAGE_RESOURCES.length; ++i) { + String outputPath = new File(Environment.getExternalStorageDirectory(), + IMAGE_FILENAMES[i]).getAbsolutePath(); + try (InputStream inputStream = getContext().getResources().openRawResource( + IMAGE_RESOURCES[i])) { + try (FileOutputStream outputStream = new FileOutputStream(outputPath)) { + Streams.copy(inputStream, outputStream); + } + } + } + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + for (int i = 0; i < IMAGE_RESOURCES.length; ++i) { + String imageFilePath = new File(Environment.getExternalStorageDirectory(), + IMAGE_FILENAMES[i]).getAbsolutePath(); + File imageFile = new File(imageFilePath); + if (imageFile.exists()) { + imageFile.delete(); + } + } + + super.tearDown(); + } + + public void testReadExifDataFromExifByteOrderIIJpeg() throws Throwable { + ExpectedValue expectedValue = new ExpectedValue( + getContext().getResources().obtainTypedArray(R.array.exifbyteorderii_jpg)); + File imageFile = new File( + Environment.getExternalStorageDirectory(), EXIF_BYTE_ORDER_II_JPEG); + + try { + // Test for reading from various inputs. + testExifInterfaceCommon(imageFile, expectedValue); + + // Test for saving attributes. + testSaveAttributes(imageFile, expectedValue); + } catch (Exception e) { + assertTrue(false); + } + } + + public void testReadExifDataFromExifByteOrderMMJpeg() throws Throwable { + ExpectedValue expectedValue = new ExpectedValue( + getContext().getResources().obtainTypedArray(R.array.exifbyteordermm_jpg)); + File imageFile = new File( + Environment.getExternalStorageDirectory(), EXIF_BYTE_ORDER_MM_JPEG); + + try { + // Test for reading from various inputs. + testExifInterfaceCommon(imageFile, expectedValue); + + // Test for saving attributes. + testSaveAttributes(imageFile, expectedValue); + } catch (Exception e) { + assertTrue(false); + } + } + + public void testReadExifDataFromMalformedJpeg() throws Throwable { + File imageFile = new File(Environment.getExternalStorageDirectory(), EXIF_MALFORMED_JPEG); + try { + ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath()); + } catch (Exception e) { + assertTrue(false); + } + } + + private void printExifTagsAndValues(String fileName, ExifInterface exifInterface) { + // Prints thumbnail information. + if (exifInterface.hasThumbnail()) { + byte[] thumbnailBytes = exifInterface.getThumbnail(); + if (thumbnailBytes != null) { + Log.v(TAG, fileName + " Thumbnail size = " + thumbnailBytes.length); + Bitmap bitmap = BitmapFactory.decodeByteArray( + thumbnailBytes, 0, thumbnailBytes.length); + if (bitmap == null) { + Log.e(TAG, fileName + " Corrupted thumbnail!"); + } else { + Log.v(TAG, fileName + " Thumbnail size: " + bitmap.getWidth() + ", " + + bitmap.getHeight()); + } + } else { + Log.e(TAG, fileName + " Unexpected result: No thumbnails were found. " + + "A thumbnail is expected."); + } + } else { + if (exifInterface.getThumbnail() != null) { + Log.e(TAG, fileName + " Unexpected result: A thumbnail was found. " + + "No thumbnail is expected."); + } else { + Log.v(TAG, fileName + " No thumbnail"); + } + } + + // Prints GPS information. + Log.v(TAG, fileName + " Altitude = " + exifInterface.getAltitude(.0)); + + float[] latLong = new float[2]; + if (exifInterface.getLatLong(latLong)) { + Log.v(TAG, fileName + " Latitude = " + latLong[0]); + Log.v(TAG, fileName + " Longitude = " + latLong[1]); + } else { + Log.v(TAG, fileName + " No latlong data"); + } + + // Prints values. + for (String tagKey : EXIF_TAGS) { + String tagValue = exifInterface.getAttribute(tagKey); + Log.v(TAG, fileName + " Key{" + tagKey + "} = '" + tagValue + "'"); + } + } + + private void assertIntTag(ExifInterface exifInterface, String tag, int expectedValue) { + int intValue = exifInterface.getAttributeInt(tag, 0); + assertEquals(expectedValue, intValue); + } + + private void assertFloatTag(ExifInterface exifInterface, String tag, float expectedValue) { + double doubleValue = exifInterface.getAttributeDouble(tag, expectedValue - 10); + if (doubleValue == expectedValue - 10) { + try { + doubleValue = Double.parseDouble(exifInterface.getAttribute(tag)); + } catch (Exception e) { + doubleValue = 0.0; + } + } + assertEquals(expectedValue, doubleValue, DIFFERENCE_TOLERANCE); + } + + private void assertStringTag(ExifInterface exifInterface, String tag, String expectedValue) { + String stringValue = exifInterface.getAttribute(tag); + if (stringValue != null) { + stringValue = stringValue.trim(); + } + assertEquals(expectedValue, stringValue); + } + + private void compareWithExpectedValue(ExifInterface exifInterface, + ExpectedValue expectedValue, String verboseTag) { + if (VERBOSE) { + printExifTagsAndValues(verboseTag, exifInterface); + } + // Checks a thumbnail image. + assertEquals(expectedValue.hasThumbnail, exifInterface.hasThumbnail()); + if (expectedValue.hasThumbnail) { + byte[] thumbnailBytes = exifInterface.getThumbnail(); + assertNotNull(thumbnailBytes); + Bitmap thumbnailBitmap = + BitmapFactory.decodeByteArray(thumbnailBytes, 0, thumbnailBytes.length); + assertNotNull(thumbnailBitmap); + assertEquals(expectedValue.thumbnailWidth, thumbnailBitmap.getWidth()); + assertEquals(expectedValue.thumbnailHeight, thumbnailBitmap.getHeight()); + } else { + assertNull(exifInterface.getThumbnail()); + } + + // Checks GPS information. + float[] latLong = new float[2]; + assertEquals(expectedValue.hasLatLong, exifInterface.getLatLong(latLong)); + if (expectedValue.hasLatLong) { + assertEquals(expectedValue.latitude, latLong[0], DIFFERENCE_TOLERANCE); + assertEquals(expectedValue.longitude, latLong[1], DIFFERENCE_TOLERANCE); + } + assertEquals(expectedValue.altitude, exifInterface.getAltitude(.0), DIFFERENCE_TOLERANCE); + + // Checks values. + assertStringTag(exifInterface, ExifInterface.TAG_MAKE, expectedValue.make); + assertStringTag(exifInterface, ExifInterface.TAG_MODEL, expectedValue.model); + assertFloatTag(exifInterface, ExifInterface.TAG_APERTURE, expectedValue.aperture); + assertStringTag(exifInterface, ExifInterface.TAG_DATETIME, expectedValue.datetime); + assertFloatTag(exifInterface, ExifInterface.TAG_EXPOSURE_TIME, expectedValue.exposureTime); + assertFloatTag(exifInterface, ExifInterface.TAG_FLASH, expectedValue.flash); + assertStringTag(exifInterface, ExifInterface.TAG_FOCAL_LENGTH, expectedValue.focalLength); + assertStringTag(exifInterface, ExifInterface.TAG_GPS_ALTITUDE, expectedValue.gpsAltitude); + assertStringTag(exifInterface, ExifInterface.TAG_GPS_ALTITUDE_REF, + expectedValue.gpsAltitudeRef); + assertStringTag(exifInterface, ExifInterface.TAG_GPS_DATESTAMP, expectedValue.gpsDatestamp); + assertStringTag(exifInterface, ExifInterface.TAG_GPS_LATITUDE, expectedValue.gpsLatitude); + assertStringTag(exifInterface, ExifInterface.TAG_GPS_LATITUDE_REF, + expectedValue.gpsLatitudeRef); + assertStringTag(exifInterface, ExifInterface.TAG_GPS_LONGITUDE, expectedValue.gpsLongitude); + assertStringTag(exifInterface, ExifInterface.TAG_GPS_LONGITUDE_REF, + expectedValue.gpsLongitudeRef); + assertStringTag(exifInterface, ExifInterface.TAG_GPS_PROCESSING_METHOD, + expectedValue.gpsProcessingMethod); + assertStringTag(exifInterface, ExifInterface.TAG_GPS_TIMESTAMP, expectedValue.gpsTimestamp); + assertIntTag(exifInterface, ExifInterface.TAG_IMAGE_LENGTH, expectedValue.imageLength); + assertIntTag(exifInterface, ExifInterface.TAG_IMAGE_WIDTH, expectedValue.imageWidth); + assertStringTag(exifInterface, ExifInterface.TAG_ISO, expectedValue.iso); + assertIntTag(exifInterface, ExifInterface.TAG_ORIENTATION, expectedValue.orientation); + assertIntTag(exifInterface, ExifInterface.TAG_WHITE_BALANCE, expectedValue.whiteBalance); + } + + private void testExifInterfaceCommon(File imageFile, ExpectedValue expectedValue) + throws IOException { + String verboseTag = imageFile.getName(); + + // Creates via path. + ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath()); + assertNotNull(exifInterface); + compareWithExpectedValue(exifInterface, expectedValue, verboseTag); + } + + private void testSaveAttributes(File imageFile, ExpectedValue expectedValue) + throws IOException { + String verboseTag = imageFile.getName(); + + ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath()); + exifInterface.saveAttributes(); + exifInterface = new ExifInterface(imageFile.getAbsolutePath()); + compareWithExpectedValue(exifInterface, expectedValue, verboseTag); + + // Test for modifying one attribute. + String backupValue = exifInterface.getAttribute(ExifInterface.TAG_MAKE); + exifInterface.setAttribute(ExifInterface.TAG_MAKE, "abc"); + exifInterface.saveAttributes(); + exifInterface = new ExifInterface(imageFile.getAbsolutePath()); + assertEquals("abc", exifInterface.getAttribute(ExifInterface.TAG_MAKE)); + // Restore the backup value. + exifInterface.setAttribute(ExifInterface.TAG_MAKE, backupValue); + exifInterface.saveAttributes(); + exifInterface = new ExifInterface(imageFile.getAbsolutePath()); + compareWithExpectedValue(exifInterface, expectedValue, verboseTag); + } +} |