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 17 package com.android.gallery3d.exif; 18 19 import android.graphics.Bitmap; 20 import android.graphics.BitmapFactory; 21 import android.util.Log; 22 23 import java.io.ByteArrayInputStream; 24 import java.io.File; 25 import java.io.FileInputStream; 26 import java.io.FileOutputStream; 27 import java.io.InputStream; 28 import java.io.OutputStream; 29 30 public class ExifOutputStreamTest extends ExifXmlDataTestCase { 31 32 private File mTmpFile; 33 34 private ExifInterface mInterface; 35 36 @Override setUp()37 public void setUp() throws Exception { 38 super.setUp(); 39 mTmpFile = File.createTempFile("exif_test", ".jpg"); 40 } 41 ExifOutputStreamTest(int imgRes, int xmlRes)42 public ExifOutputStreamTest(int imgRes, int xmlRes) { 43 super(imgRes, xmlRes); 44 mInterface = new ExifInterface(); 45 } 46 ExifOutputStreamTest(String imgPath, String xmlPath)47 public ExifOutputStreamTest(String imgPath, String xmlPath) { 48 super(imgPath, xmlPath); 49 mInterface = new ExifInterface(); 50 } 51 testExifOutputStream()52 public void testExifOutputStream() throws Exception { 53 InputStream imageInputStream = null; 54 InputStream exifInputStream = null; 55 FileInputStream reDecodeInputStream = null; 56 FileInputStream reParseInputStream = null; 57 58 InputStream dangerInputStream = null; 59 OutputStream dangerOutputStream = null; 60 try { 61 try { 62 byte[] imgData = Util.readToByteArray(getImageInputStream()); 63 imageInputStream = new ByteArrayInputStream(imgData); 64 exifInputStream = new ByteArrayInputStream(imgData); 65 66 // Read the image data 67 Bitmap bmp = BitmapFactory.decodeStream(imageInputStream); 68 // The image is invalid 69 if (bmp == null) { 70 return; 71 } 72 73 // Read exif data 74 ExifData exifData = new ExifReader(mInterface).read(exifInputStream); 75 76 // Encode the image with the exif data 77 FileOutputStream outputStream = new FileOutputStream(mTmpFile); 78 ExifOutputStream exifOutputStream = new ExifOutputStream(outputStream, mInterface); 79 exifOutputStream.setExifData(exifData); 80 bmp.compress(Bitmap.CompressFormat.JPEG, 90, exifOutputStream); 81 exifOutputStream.close(); 82 exifOutputStream = null; 83 84 // Re-decode the temp file and check the data. 85 reDecodeInputStream = new FileInputStream(mTmpFile); 86 Bitmap decodedBmp = BitmapFactory.decodeStream(reDecodeInputStream); 87 assertNotNull(getImageTitle(), decodedBmp); 88 reDecodeInputStream.close(); 89 90 // Re-parse the temp file the check EXIF tag 91 reParseInputStream = new FileInputStream(mTmpFile); 92 ExifData reExifData = new ExifReader(mInterface).read(reParseInputStream); 93 assertEquals(getImageTitle(), exifData, reExifData); 94 reParseInputStream.close(); 95 96 // Try writing exif to file with existing exif. 97 dangerOutputStream = (OutputStream) new FileOutputStream(mTmpFile); 98 exifOutputStream = new ExifOutputStream(dangerOutputStream, mInterface); 99 exifOutputStream.setExifData(exifData); 100 exifOutputStream.write(imgData); 101 // exifOutputStream.write(strippedImgData); 102 exifOutputStream.close(); 103 exifOutputStream = null; 104 105 // Make sure it still can be parsed into a bitmap. 106 dangerInputStream = (InputStream) new FileInputStream(mTmpFile); 107 decodedBmp = null; 108 decodedBmp = BitmapFactory.decodeStream(dangerInputStream); 109 assertNotNull(getImageTitle(), decodedBmp); 110 dangerInputStream.close(); 111 dangerInputStream = null; 112 113 // Make sure exif is still well-formatted. 114 dangerInputStream = (InputStream) new FileInputStream(mTmpFile); 115 reExifData = null; 116 reExifData = new ExifReader(mInterface).read(dangerInputStream); 117 assertEquals(getImageTitle(), exifData, reExifData); 118 dangerInputStream.close(); 119 dangerInputStream = null; 120 121 } finally { 122 Util.closeSilently(imageInputStream); 123 Util.closeSilently(exifInputStream); 124 Util.closeSilently(reDecodeInputStream); 125 Util.closeSilently(reParseInputStream); 126 127 Util.closeSilently(dangerInputStream); 128 Util.closeSilently(dangerOutputStream); 129 } 130 } catch (Exception e) { 131 throw new Exception(getImageTitle(), e); 132 } 133 } 134 testOutputSpeed()135 public void testOutputSpeed() throws Exception { 136 final String LOGTAG = "testOutputSpeed"; 137 InputStream imageInputStream = null; 138 OutputStream imageOutputStream = null; 139 try { 140 try { 141 imageInputStream = getImageInputStream(); 142 // Read the image data 143 Bitmap bmp = BitmapFactory.decodeStream(imageInputStream); 144 // The image is invalid 145 if (bmp == null) { 146 return; 147 } 148 imageInputStream.close(); 149 int nLoops = 20; 150 long totalReadDuration = 0; 151 long totalWriteDuration = 0; 152 for (int i = 0; i < nLoops; i++) { 153 imageInputStream = reopenFileStream(); 154 // Read exif data 155 long startTime = System.nanoTime(); 156 ExifData exifData = new ExifReader(mInterface).read(imageInputStream); 157 long endTime = System.nanoTime(); 158 long duration = endTime - startTime; 159 totalReadDuration += duration; 160 Log.v(LOGTAG, " read time: " + duration); 161 imageInputStream.close(); 162 163 // Encode the image with the exif data 164 imageOutputStream = (OutputStream) new FileOutputStream(mTmpFile); 165 ExifOutputStream exifOutputStream = new ExifOutputStream(imageOutputStream, 166 mInterface); 167 exifOutputStream.setExifData(exifData); 168 startTime = System.nanoTime(); 169 bmp.compress(Bitmap.CompressFormat.JPEG, 90, exifOutputStream); 170 endTime = System.nanoTime(); 171 duration = endTime - startTime; 172 totalWriteDuration += duration; 173 Log.v(LOGTAG, " write time: " + duration); 174 exifOutputStream.close(); 175 } 176 Log.v(LOGTAG, "======================= normal"); 177 Log.v(LOGTAG, "avg read time: " + totalReadDuration / nLoops); 178 Log.v(LOGTAG, "avg write time: " + totalWriteDuration / nLoops); 179 Log.v(LOGTAG, "======================="); 180 } finally { 181 Util.closeSilently(imageInputStream); 182 Util.closeSilently(imageOutputStream); 183 } 184 } catch (Exception e) { 185 throw new Exception(getImageTitle(), e); 186 } 187 } 188 189 @Override tearDown()190 public void tearDown() throws Exception { 191 super.tearDown(); 192 mTmpFile.delete(); 193 } 194 } 195