/* * Copyright (C) 2012 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 com.android.gallery3d.exif; import junit.framework.TestCase; import java.util.HashMap; import java.util.Map; public class ExifTagTest extends TestCase { private static long MAX_UNSIGNED_LONG = (1L << 32) - 1; private static int MAX_LONG = Integer.MAX_VALUE; private static int MIN_LONG = Integer.MIN_VALUE; Map mTestTags; ExifInterface mInterface; private ExifTag mVersionTag; private ExifTag mGpsVersionTag; private ExifTag mModelTag; private ExifTag mDateTimeTag; private ExifTag mCompressionTag; private ExifTag mThumbnailFormatTag; private ExifTag mLongitudeTag; private ExifTag mShutterTag; private ExifTag mInteropIndex; @Override public void setUp() throws Exception { super.setUp(); mInterface = new ExifInterface(); // TYPE_UNDEFINED with 4 components mVersionTag = mInterface.buildTag(ExifInterface.TAG_EXIF_VERSION, new byte[] { 5, 4, 3, 2 }); // TYPE_UNSIGNED_BYTE with 4 components mGpsVersionTag = mInterface.buildTag(ExifInterface.TAG_GPS_VERSION_ID, new byte[] { 6, 7, 8, 9 }); // TYPE ASCII with arbitrary length mModelTag = mInterface.buildTag(ExifInterface.TAG_MODEL, "helloworld"); // TYPE_ASCII with 20 components mDateTimeTag = mInterface.buildTag(ExifInterface.TAG_DATE_TIME, "2013:02:11 20:20:20"); // TYPE_UNSIGNED_SHORT with 1 components mCompressionTag = mInterface.buildTag(ExifInterface.TAG_COMPRESSION, 100); // TYPE_UNSIGNED_LONG with 1 components mThumbnailFormatTag = mInterface.buildTag(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT, 100); // TYPE_UNSIGNED_RATIONAL with 3 components mLongitudeTag = mInterface.buildTag(ExifInterface.TAG_GPS_LONGITUDE, new Rational[] { new Rational(2, 2), new Rational(11, 11), new Rational(102, 102) }); // TYPE_RATIONAL with 1 components mShutterTag = mInterface .buildTag(ExifInterface.TAG_SHUTTER_SPEED_VALUE, new Rational(4, 6)); // TYPE_ASCII with arbitrary length mInteropIndex = mInterface.buildTag(ExifInterface.TAG_INTEROPERABILITY_INDEX, "foo"); mTestTags = new HashMap(); mTestTags.put(ExifInterface.TAG_EXIF_VERSION, mVersionTag); mTestTags.put(ExifInterface.TAG_GPS_VERSION_ID, mGpsVersionTag); mTestTags.put(ExifInterface.TAG_MODEL, mModelTag); mTestTags.put(ExifInterface.TAG_DATE_TIME, mDateTimeTag); mTestTags.put(ExifInterface.TAG_COMPRESSION, mCompressionTag); mTestTags.put(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT, mThumbnailFormatTag); mTestTags.put(ExifInterface.TAG_GPS_LONGITUDE, mLongitudeTag); mTestTags.put(ExifInterface.TAG_SHUTTER_SPEED_VALUE, mShutterTag); mTestTags.put(ExifInterface.TAG_INTEROPERABILITY_INDEX, mInteropIndex); } @Override public void tearDown() throws Exception { super.tearDown(); mInterface = null; mTestTags = null; } public void testValueType() { for (ExifTag tag : mTestTags.values()) { assertTrue(tag != null); int count = tag.getComponentCount(); int intBuf[] = new int[count]; long longBuf[] = new long[count]; byte byteBuf[] = new byte[count]; Rational rationalBuf[] = new Rational[count]; StringBuilder sb = new StringBuilder(); for (int i = 0; i < count; i++) { intBuf[i] = 0; longBuf[i] = 0; byteBuf[i] = 0; rationalBuf[i] = new Rational(0, 0); // The string size should equal to component count - 1 if (i != count - 1) { sb.append("*"); } else { sb.append("\0"); } } String strBuf = sb.toString(); checkTypeByte(tag, byteBuf); checkTypeAscii(tag, strBuf); checkTypeUnsignedShort(tag, intBuf); checkTypeUnsignedLong(tag, intBuf, longBuf); checkTypeLong(tag, intBuf); checkTypeRational(tag, rationalBuf); checkTypeUnsignedRational(tag, rationalBuf); } } private void checkTypeByte(ExifTag tag, byte[] buf) { short type = tag.getDataType(); assertFalse("\nTag: " + tag.toString(), tag.setValue(buf) ^ (type == ExifTag.TYPE_UNDEFINED || type == ExifTag.TYPE_UNSIGNED_BYTE)); } private void checkTypeAscii(ExifTag tag, String str) { short type = tag.getDataType(); assertFalse("\nTag: " + tag.toString(), tag.setValue(str) ^ (type == ExifTag.TYPE_ASCII || type == ExifTag.TYPE_UNDEFINED)); } private void checkTypeUnsignedShort(ExifTag tag, int[] intBuf) { short type = tag.getDataType(); assertFalse("\nTag: " + tag.toString(), tag.setValue(intBuf) ^ (type == ExifTag.TYPE_UNSIGNED_SHORT || type == ExifTag.TYPE_UNSIGNED_LONG || type == ExifTag.TYPE_LONG)); } private void checkTypeUnsignedLong(ExifTag tag, int[] intBuf, long[] longBuf) { // Test value only for unsigned long. int count = intBuf.length; intBuf[count - 1] = MAX_LONG; tag.setValue(intBuf); longBuf[count - 1] = MAX_UNSIGNED_LONG; assertFalse("\nTag: " + tag.toString(), tag.setValue(longBuf) ^ (tag.getDataType() == ExifTag.TYPE_UNSIGNED_LONG)); intBuf[count - 1] = 0; // Test invalid value for all type. longBuf[count - 1] = MAX_UNSIGNED_LONG + 1; assertFalse(tag.setValue(longBuf)); longBuf[count - 1] = 0; } private void checkTypeLong(ExifTag tag, int[] intBuf) { int count = intBuf.length; intBuf[count - 1] = MAX_LONG; tag.setValue(intBuf); intBuf[count - 1] = MIN_LONG; assertFalse("\nTag: " + tag.toString(), tag.setValue(intBuf) ^ (tag.getDataType() == ExifTag.TYPE_LONG)); intBuf[count - 1] = 0; } private void checkTypeRational(ExifTag tag, Rational rationalBuf[]) { int count = rationalBuf.length; Rational r = rationalBuf[count - 1]; rationalBuf[count - 1] = new Rational(MAX_LONG, MIN_LONG); assertFalse("\nTag: " + tag.toString(), tag.setValue(rationalBuf) ^ (tag.getDataType() == ExifTag.TYPE_RATIONAL)); if (tag.getDataType() == ExifTag.TYPE_RATIONAL) { // check overflow rationalBuf[count - 1] = new Rational(MAX_LONG + 1L, MIN_LONG); assertFalse(tag.setValue(rationalBuf)); rationalBuf[count - 1] = new Rational(MAX_LONG, MIN_LONG - 1L); assertFalse(tag.setValue(rationalBuf)); } rationalBuf[count - 1] = r; } private void checkTypeUnsignedRational(ExifTag tag, Rational rationalBuf[]) { int count = rationalBuf.length; Rational r = rationalBuf[count - 1]; rationalBuf[count - 1] = new Rational(MAX_UNSIGNED_LONG, MAX_UNSIGNED_LONG); assertFalse("\nTag: " + tag.toString(), tag.setValue(rationalBuf) ^ (tag.getDataType() == ExifTag.TYPE_UNSIGNED_RATIONAL)); if (tag.getDataType() == ExifTag.TYPE_UNSIGNED_RATIONAL) { // check overflow rationalBuf[count - 1] = new Rational(MAX_UNSIGNED_LONG + 1, 0); assertFalse(tag.setValue(rationalBuf)); rationalBuf[count - 1] = new Rational(MAX_UNSIGNED_LONG, -1); assertFalse(tag.setValue(rationalBuf)); } rationalBuf[count - 1] = r; } }