/* * 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 java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel.MapMode; import java.util.HashMap; import java.util.List; import java.util.Map; public class ExifModifierTest extends ExifXmlDataTestCase { private File mTmpFile; private List>> mGroundTruth; private ExifInterface mInterface; private Map mTestTags; ExifTag mVersionTag; ExifTag mGpsVersionTag; ExifTag mModelTag; ExifTag mDateTimeTag; ExifTag mCompressionTag; ExifTag mThumbnailFormatTag; ExifTag mLongitudeTag; ExifTag mShutterTag; @Override public void setUp() throws Exception { super.setUp(); mGroundTruth = ExifXmlReader.readXml(getXmlParser()); mTmpFile = File.createTempFile("exif_test", ".jpg"); FileOutputStream os = null; InputStream is = getImageInputStream(); try { os = new FileOutputStream(mTmpFile); byte[] buf = new byte[1024]; int n; while ((n = is.read(buf)) > 0) { os.write(buf, 0, n); } } finally { Util.closeSilently(os); } // TYPE_UNDEFINED with 4 components mVersionTag = mInterface.buildTag(ExifInterface.TAG_EXIF_VERSION, new byte[] { 1, 2, 3, 4 }); // TYPE_UNSIGNED_BYTE with 4 components mGpsVersionTag = mInterface.buildTag(ExifInterface.TAG_GPS_VERSION_ID, new byte[] { 4, 3, 2, 1 }); // TYPE ASCII with arbitary length mModelTag = mInterface.buildTag(ExifInterface.TAG_MODEL, "end-of-the-world"); // TYPE_ASCII with 20 components mDateTimeTag = mInterface.buildTag(ExifInterface.TAG_DATE_TIME, "2012:12:31 23:59:59"); // 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(1, 1), new Rational(10, 10), new Rational(100, 100) }); // TYPE_RATIONAL with 1 components mShutterTag = mInterface .buildTag(ExifInterface.TAG_SHUTTER_SPEED_VALUE, new Rational(1, 1)); mTestTags = new HashMap(); mTestTags.put(mVersionTag.getTagId(), mVersionTag); mTestTags.put(mGpsVersionTag.getTagId(), mGpsVersionTag); mTestTags.put(mModelTag.getTagId(), mModelTag); mTestTags.put(mDateTimeTag.getTagId(), mDateTimeTag); mTestTags.put(mCompressionTag.getTagId(), mCompressionTag); mTestTags.put(mThumbnailFormatTag.getTagId(), mThumbnailFormatTag); mTestTags.put(mLongitudeTag.getTagId(), mLongitudeTag); mTestTags.put(mShutterTag.getTagId(), mShutterTag); } public ExifModifierTest(int imageRes, int xmlRes) { super(imageRes, xmlRes); mInterface = new ExifInterface(); } public ExifModifierTest(String imagePath, String xmlPath) { super(imagePath, xmlPath); mInterface = new ExifInterface(); } public void testModify() throws Exception { Map results = new HashMap(); RandomAccessFile file = null; try { file = new RandomAccessFile(mTmpFile, "rw"); MappedByteBuffer buf = file.getChannel().map(MapMode.READ_WRITE, 0, file.length()); for (ExifTag tag : mTestTags.values()) { ExifModifier modifier = new ExifModifier(buf, mInterface); modifier.modifyTag(tag); boolean result = modifier.commit(); results.put(tag.getTagId(), result); buf.force(); buf.position(0); if (!result) { List value = mGroundTruth.get(tag.getIfd()).get(tag.getTagId()); assertTrue(String.format("Tag %x, ", tag.getTagId()) + getImageTitle(), value == null || tag.getTagId() == ExifInterface.TAG_MODEL); } } } finally { Util.closeSilently(file); } // Parse the new file and check the result InputStream is = null; try { is = new FileInputStream(mTmpFile); ExifData data = new ExifReader(mInterface).read(is); for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { checkIfd(data.getIfdData(i), mGroundTruth.get(i), results); } } finally { Util.closeSilently(is); } } private void checkIfd(IfdData ifd, Map> ifdValue, Map results) { if (ifd == null) { assertEquals(getImageTitle(), 0, ifdValue.size()); return; } ExifTag[] tags = ifd.getAllTags(); for (ExifTag tag : tags) { List truth = ifdValue.get(tag.getTagId()); assertNotNull(String.format("Tag %x, ", tag.getTagId()) + getImageTitle(), truth); if (truth.contains(null)) { continue; } ExifTag newTag = mTestTags.get(tag.getTagId()); if (newTag != null && results.get(tag.getTagId())) { assertEquals(String.format("Tag %x, ", tag.getTagId()) + getImageTitle(), Util.tagValueToString(newTag), Util.tagValueToString(tag)); } else { assertTrue(String.format("Tag %x, ", tag.getTagId()) + getImageTitle(), truth.contains(Util.tagValueToString(tag).trim())); } } assertEquals(getImageTitle(), ifdValue.size(), tags.length); } @Override public void tearDown() throws Exception { super.tearDown(); mTmpFile.delete(); } }