Skip to content

Commit

Permalink
Manually read stream to byte array in gif decoder.
Browse files Browse the repository at this point in the history
Doing so means we go from using 3x the necessary
memory in the worst case to 2x, and in the best
case we go from using 2x the necessary memory to
using exactly what we need (for images larger than
the buffer size). 

Progress toward bumptech#83
  • Loading branch information
sjudd committed Nov 25, 2014
1 parent 3d25807 commit b504aa2
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 12 deletions.
Expand Up @@ -109,7 +109,7 @@ public void testDecodesFirstFrameAndReturnsGifDecoderToPool() {

InOrder order = inOrder(decoderPool, gifDecoder);
order.verify(decoderPool).obtain(any(GifDecoder.BitmapProvider.class));
order.verify(gifDecoder).setData(eq(gifHeader), eq(data));
order.verify(gifDecoder).setData(eq(gifHeader), any(byte[].class));
order.verify(gifDecoder).advance();
order.verify(gifDecoder).getNextFrame();
order.verify(decoderPool).release(eq(gifDecoder));
Expand Down
Expand Up @@ -14,7 +14,6 @@
import com.bumptech.glide.load.resource.UnitTransformation;
import com.bumptech.glide.util.Util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Queue;
Expand All @@ -24,6 +23,7 @@
* {@link com.bumptech.glide.load.resource.gif.GifDrawable} from {@link java.io.InputStream} data.
*/
public class GifResourceDecoder implements ResourceDecoder<InputStream, GifDrawable> {
private static final int DEFAULT_BUFFER_BYTE_SIZE = 16384;
private static final String TAG = "GifResourceDecoder";
private static final GifHeaderParserPool PARSER_POOL = new GifHeaderParserPool();
private static final GifDecoderPool DECODER_POOL = new GifDecoderPool();
Expand Down Expand Up @@ -97,20 +97,23 @@ public String getId() {
}

private static byte[] inputStreamToBytes(InputStream is) {
final int bufferSize = 16384;
ByteArrayOutputStream buffer = new ByteArrayOutputStream(bufferSize);
byte[] data = new byte[DEFAULT_BUFFER_BYTE_SIZE];
int dataPosition = 0;
try {
int nRead;
byte[] data = new byte[bufferSize];
while ((nRead = is.read(data)) != -1) {
buffer.write(data, 0, nRead);
int read;
while ((read = is.read(data, dataPosition, data.length - dataPosition)) != -1) {
dataPosition += read;
if (dataPosition == data.length) {
byte[] temp = new byte[data.length * 2];
System.arraycopy(data, 0, temp, 0, data.length);
data = temp;
}
}
buffer.flush();
} catch (IOException e) {
Log.w(TAG, "Error reading data from stream", e);
}
//TODO the returned byte[] may be partial if an IOException was thrown from read
return buffer.toByteArray();
// TODO: the returned byte[] may be partial if an IOException was thrown from read
return data;
}

// Visible for testing.
Expand Down
1 change: 0 additions & 1 deletion samples/giphy/src/main/AndroidManifest.xml
Expand Up @@ -6,7 +6,6 @@
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:largeHeap="true"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
Expand Down

0 comments on commit b504aa2

Please sign in to comment.