Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bee0f20 authored by Ruben Brunk's avatar Ruben Brunk
Browse files

Speed improvements for ExifOutputStream.

Change-Id: I7d3ee9c157aefe67734e7b49cfa7868254c134ef
parent 20eb41f8
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -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;
+3 −1
Original line number Diff line number Diff line
@@ -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;
    }

+55 −0
Original line number Diff line number Diff line
@@ -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();
+13 −0
Original line number Diff line number Diff line
@@ -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);
        }
    }
}