OSDN Git Service

Speed improvements for ExifOutputStream.
authorRuben Brunk <rubenbrunk@google.com>
Tue, 2 Apr 2013 20:15:57 +0000 (13:15 -0700)
committerRuben Brunk <rubenbrunk@google.com>
Tue, 2 Apr 2013 22:39:41 +0000 (15:39 -0700)
Change-Id: I7d3ee9c157aefe67734e7b49cfa7868254c134ef

gallerycommon/src/com/android/gallery3d/exif/ExifInterface.java
gallerycommon/src/com/android/gallery3d/exif/ExifOutputStream.java
tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java
tests/src/com/android/gallery3d/exif/ExifXmlDataTestCase.java

index 2fef9ed..a1cf0fc 100644 (file)
@@ -20,6 +20,7 @@ import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.util.SparseIntArray;
 
+import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
@@ -758,7 +759,7 @@ public class ExifInterface {
         }
         InputStream is = null;
         try {
-            is = (InputStream) new FileInputStream(inFileName);
+            is = (InputStream) new BufferedInputStream(new FileInputStream(inFileName));
             readExif(is);
         } catch (IOException e) {
             closeSilently(is);
@@ -800,6 +801,7 @@ public class ExifInterface {
         }
         OutputStream s = getExifWriterStream(exifOutStream);
         s.write(jpeg, 0, jpeg.length);
+        s.flush();
     }
 
     /**
@@ -817,6 +819,7 @@ public class ExifInterface {
         }
         OutputStream s = getExifWriterStream(exifOutStream);
         bmap.compress(Bitmap.CompressFormat.JPEG, 90, s);
+        s.flush();
     }
 
     /**
@@ -834,6 +837,7 @@ public class ExifInterface {
         }
         OutputStream s = getExifWriterStream(exifOutStream);
         doExifStreamIO(jpegStream, s);
+        s.flush();
     }
 
     /**
@@ -1010,7 +1014,7 @@ public class ExifInterface {
         boolean ret;
         try {
             File temp = new File(filename);
-            is = new FileInputStream(temp);
+            is = new BufferedInputStream(new FileInputStream(temp));
 
             // Parse beginning of APP1 in exif to find size of exif header.
             ExifParser parser = null;
index e5a5bf0..96672e8 100644 (file)
@@ -18,6 +18,7 @@ package com.android.gallery3d.exif;
 
 import android.util.Log;
 
+import java.io.BufferedOutputStream;
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -58,6 +59,7 @@ import java.nio.ByteOrder;
 class ExifOutputStream extends FilterOutputStream {
     private static final String TAG = "ExifOutputStream";
     private static final boolean DEBUG = false;
+    private static final int STREAMBUFFER_SIZE = 0x00010000; // 64Kb
 
     private static final int STATE_SOI = 0;
     private static final int STATE_FRAME_HEADER = 1;
@@ -79,7 +81,7 @@ class ExifOutputStream extends FilterOutputStream {
     private final ExifInterface mInterface;
 
     protected ExifOutputStream(OutputStream ou, ExifInterface iRef) {
-        super(ou);
+        super(new BufferedOutputStream(ou, STREAMBUFFER_SIZE));
         mInterface = iRef;
     }
 
index 8c4fc3d..1286c58 100644 (file)
@@ -18,6 +18,7 @@ package com.android.gallery3d.exif;
 
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.util.Log;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -131,6 +132,60 @@ public class ExifOutputStreamTest extends ExifXmlDataTestCase {
         }
     }
 
+    public void testOutputSpeed() throws Exception {
+        final String LOGTAG = "testOutputSpeed";
+        InputStream imageInputStream = null;
+        OutputStream imageOutputStream = null;
+        try {
+            try {
+                imageInputStream = getImageInputStream();
+                // Read the image data
+                Bitmap bmp = BitmapFactory.decodeStream(imageInputStream);
+                // The image is invalid
+                if (bmp == null) {
+                    return;
+                }
+                imageInputStream.close();
+                int nLoops = 20;
+                long totalReadDuration = 0;
+                long totalWriteDuration = 0;
+                for (int i = 0; i < nLoops; i++) {
+                    imageInputStream = reopenFileStream();
+                    // Read exif data
+                    long startTime = System.nanoTime();
+                    ExifData exifData = new ExifReader(mInterface).read(imageInputStream);
+                    long endTime = System.nanoTime();
+                    long duration = endTime - startTime;
+                    totalReadDuration += duration;
+                    Log.v(LOGTAG, " read time: " + duration);
+                    imageInputStream.close();
+
+                    // Encode the image with the exif data
+                    imageOutputStream = (OutputStream) new FileOutputStream(mTmpFile);
+                    ExifOutputStream exifOutputStream = new ExifOutputStream(imageOutputStream,
+                            mInterface);
+                    exifOutputStream.setExifData(exifData);
+                    startTime = System.nanoTime();
+                    bmp.compress(Bitmap.CompressFormat.JPEG, 90, exifOutputStream);
+                    endTime = System.nanoTime();
+                    duration = endTime - startTime;
+                    totalWriteDuration += duration;
+                    Log.v(LOGTAG, " write time: " + duration);
+                    exifOutputStream.close();
+                }
+                Log.v(LOGTAG, "======================= normal");
+                Log.v(LOGTAG, "avg read time: " + totalReadDuration / nLoops);
+                Log.v(LOGTAG, "avg write time: " + totalWriteDuration / nLoops);
+                Log.v(LOGTAG, "=======================");
+            } finally {
+                Util.closeSilently(imageInputStream);
+                Util.closeSilently(imageOutputStream);
+            }
+        } catch (Exception e) {
+            throw new Exception(getImageTitle(), e);
+        }
+    }
+
     @Override
     public void tearDown() throws Exception {
         super.tearDown();
index 5f200ea..da86020 100644 (file)
@@ -92,4 +92,17 @@ public class ExifXmlDataTestCase extends InstrumentationTestCase {
             return String.format(RES_ID_TITLE, mImageResourceId);
         }
     }
+
+    protected InputStream reopenFileStream() throws Exception {
+        try {
+            if (mImagePath != null) {
+                return new FileInputStream(mImagePath);
+            } else {
+                Resources res = getInstrumentation().getContext().getResources();
+                return res.openRawResource(mImageResourceId);
+            }
+        } catch (Exception e) {
+            throw new Exception(getImageTitle(), e);
+        }
+    }
 }