Speed improvements for ExifOutputStream.
Change-Id: I7d3ee9c157aefe67734e7b49cfa7868254c134ef
diff --git a/gallerycommon/src/com/android/gallery3d/exif/ExifInterface.java b/gallerycommon/src/com/android/gallery3d/exif/ExifInterface.java
index 2fef9ed..a1cf0fc 100644
--- a/gallerycommon/src/com/android/gallery3d/exif/ExifInterface.java
+++ b/gallerycommon/src/com/android/gallery3d/exif/ExifInterface.java
@@ -20,6 +20,7 @@
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 @@
}
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 @@
}
OutputStream s = getExifWriterStream(exifOutStream);
s.write(jpeg, 0, jpeg.length);
+ s.flush();
}
/**
@@ -817,6 +819,7 @@
}
OutputStream s = getExifWriterStream(exifOutStream);
bmap.compress(Bitmap.CompressFormat.JPEG, 90, s);
+ s.flush();
}
/**
@@ -834,6 +837,7 @@
}
OutputStream s = getExifWriterStream(exifOutStream);
doExifStreamIO(jpegStream, s);
+ s.flush();
}
/**
@@ -1010,7 +1014,7 @@
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;
diff --git a/gallerycommon/src/com/android/gallery3d/exif/ExifOutputStream.java b/gallerycommon/src/com/android/gallery3d/exif/ExifOutputStream.java
index e5a5bf0..96672e8 100644
--- a/gallerycommon/src/com/android/gallery3d/exif/ExifOutputStream.java
+++ b/gallerycommon/src/com/android/gallery3d/exif/ExifOutputStream.java
@@ -18,6 +18,7 @@
import android.util.Log;
+import java.io.BufferedOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -58,6 +59,7 @@
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 @@
private final ExifInterface mInterface;
protected ExifOutputStream(OutputStream ou, ExifInterface iRef) {
- super(ou);
+ super(new BufferedOutputStream(ou, STREAMBUFFER_SIZE));
mInterface = iRef;
}
diff --git a/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java b/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java
index 8c4fc3d..1286c58 100644
--- a/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java
+++ b/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java
@@ -18,6 +18,7 @@
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 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();
diff --git a/tests/src/com/android/gallery3d/exif/ExifXmlDataTestCase.java b/tests/src/com/android/gallery3d/exif/ExifXmlDataTestCase.java
index 5f200ea..da86020 100644
--- a/tests/src/com/android/gallery3d/exif/ExifXmlDataTestCase.java
+++ b/tests/src/com/android/gallery3d/exif/ExifXmlDataTestCase.java
@@ -92,4 +92,17 @@
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);
+ }
+ }
}