Skip to content

Commit a5c46a5

Browse files
committed
Create Options only when needed
Create `BitmapFactory.Options` only when resizing or giving a custom `Bitmap.Config` `createBitmapOptions` will translate given `Request` to `BitmapFactory.Options` Introduce `requiresInSampleSize` to determinate if computation of sample size is required
1 parent 7cfc9f2 commit a5c46a5

File tree

7 files changed

+72
-29
lines changed

7 files changed

+72
-29
lines changed

picasso/src/main/java/com/squareup/picasso/AssetBitmapHunter.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ public AssetBitmapHunter(Context context, Picasso picasso, Dispatcher dispatcher
3333
}
3434

3535
Bitmap decodeAsset(String filePath) throws IOException {
36-
BitmapFactory.Options options = createBitmapOptions(data);
37-
if (data.hasSize()) {
38-
options.inJustDecodeBounds = true;
36+
final BitmapFactory.Options options = createBitmapOptions(data);
37+
if (requiresInSampleSize(options)) {
3938
InputStream is = null;
4039
try {
4140
is = assetManager.open(filePath);

picasso/src/main/java/com/squareup/picasso/BitmapHunter.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,32 @@ static BitmapHunter forRequest(Context context, Picasso picasso, Dispatcher disp
232232
}
233233
}
234234

235+
/**
236+
* Lazily create {@link android.graphics.BitmapFactory.Options}
237+
* based in given {@link com.squareup.picasso.Request}
238+
*
239+
* @param data
240+
*/
235241
static BitmapFactory.Options createBitmapOptions(Request data) {
236-
BitmapFactory.Options options = new BitmapFactory.Options();
237-
if (data.config != null) {
242+
final boolean justBounds = data.hasSize();
243+
final boolean hasConfig = data.config != null;
244+
final boolean instantiate = hasConfig || justBounds;
245+
// Only instantiate if we need it
246+
final BitmapFactory.Options options = instantiate ? new BitmapFactory.Options() : null;
247+
if (justBounds) {
248+
options.inJustDecodeBounds = true;
249+
}
250+
251+
if (hasConfig) {
238252
options.inPreferredConfig = data.config;
239253
}
240254
return options;
241255
}
242256

257+
static boolean requiresInSampleSize(BitmapFactory.Options options) {
258+
return options != null && options.inJustDecodeBounds;
259+
}
260+
243261
static void calculateInSampleSize(int reqWidth, int reqHeight, BitmapFactory.Options options) {
244262
calculateInSampleSize(reqWidth, reqHeight, options.outWidth, options.outHeight, options);
245263
}

picasso/src/main/java/com/squareup/picasso/ContactsPhotoBitmapHunter.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,8 @@ private Bitmap decodeStream(InputStream stream, Request data) throws IOException
106106
if (stream == null) {
107107
return null;
108108
}
109-
BitmapFactory.Options options = createBitmapOptions(data);
110-
if (data.hasSize()) {
111-
options.inJustDecodeBounds = true;
109+
final BitmapFactory.Options options = createBitmapOptions(data);
110+
if (requiresInSampleSize(options)) {
112111
InputStream is = getInputStream();
113112
try {
114113
BitmapFactory.decodeStream(is, null, options);

picasso/src/main/java/com/squareup/picasso/ContentStreamBitmapHunter.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ class ContentStreamBitmapHunter extends BitmapHunter {
4444

4545
protected Bitmap decodeContentStream(Request data) throws IOException {
4646
ContentResolver contentResolver = context.getContentResolver();
47-
BitmapFactory.Options options = createBitmapOptions(data);
48-
if (data.hasSize()) {
49-
options.inJustDecodeBounds = true;
47+
final BitmapFactory.Options options = createBitmapOptions(data);
48+
if (requiresInSampleSize(options)) {
5049
InputStream is = null;
5150
try {
5251
is = contentResolver.openInputStream(data.uri);

picasso/src/main/java/com/squareup/picasso/NetworkBitmapHunter.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,25 +81,22 @@ private Bitmap decodeStream(InputStream stream, Request data) throws IOException
8181

8282
long mark = markStream.savePosition(MARKER);
8383

84+
final BitmapFactory.Options options = createBitmapOptions(data);
85+
final boolean calculateSize = requiresInSampleSize(options);
86+
8487
boolean isWebPFile = Utils.isWebPFile(stream);
8588
markStream.reset(mark);
8689
// When decode WebP network stream, BitmapFactory throw JNI Exception and make app crash.
8790
// Decode byte array instead
8891
if (isWebPFile) {
8992
byte[] bytes = Utils.toByteArray(stream);
90-
BitmapFactory.Options options = createBitmapOptions(data);
91-
if (data.hasSize()) {
92-
options.inJustDecodeBounds = true;
93-
93+
if (calculateSize) {
9494
BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
9595
calculateInSampleSize(data.targetWidth, data.targetHeight, options);
9696
}
9797
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
9898
} else {
99-
BitmapFactory.Options options = createBitmapOptions(data);
100-
if (data.hasSize()) {
101-
options.inJustDecodeBounds = true;
102-
99+
if (calculateSize) {
103100
BitmapFactory.decodeStream(stream, null, options);
104101
calculateInSampleSize(data.targetWidth, data.targetHeight, options);
105102

picasso/src/main/java/com/squareup/picasso/ResourceBitmapHunter.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,11 @@ class ResourceBitmapHunter extends BitmapHunter {
4343
}
4444

4545
private Bitmap decodeResource(Resources resources, int id, Request data) {
46-
BitmapFactory.Options bitmapOptions = createBitmapOptions(data);
47-
if (data.hasSize()) {
48-
bitmapOptions.inJustDecodeBounds = true;
49-
BitmapFactory.decodeResource(resources, id, bitmapOptions);
50-
calculateInSampleSize(data.targetWidth, data.targetHeight, bitmapOptions);
46+
final BitmapFactory.Options options = createBitmapOptions(data);
47+
if (requiresInSampleSize(options)) {
48+
BitmapFactory.decodeResource(resources, id, options);
49+
calculateInSampleSize(data.targetWidth, data.targetHeight, options);
5150
}
52-
return BitmapFactory.decodeResource(resources, id, bitmapOptions);
51+
return BitmapFactory.decodeResource(resources, id, options);
5352
}
5453
}

picasso/src/test/java/com/squareup/picasso/BitmapHunterTest.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@
1717

1818
import android.content.Context;
1919
import android.graphics.Bitmap;
20+
import android.graphics.BitmapFactory;
2021
import android.graphics.Matrix;
2122
import android.net.Uri;
22-
import java.io.File;
23-
import java.io.IOException;
24-
import java.util.concurrent.FutureTask;
2523
import org.junit.Before;
2624
import org.junit.Test;
2725
import org.junit.runner.RunWith;
@@ -31,9 +29,15 @@
3129
import org.robolectric.shadows.ShadowBitmap;
3230
import org.robolectric.shadows.ShadowMatrix;
3331

32+
import java.io.File;
33+
import java.io.IOException;
34+
import java.util.concurrent.FutureTask;
35+
3436
import static android.graphics.Bitmap.Config.ARGB_8888;
37+
import static android.graphics.Bitmap.Config.RGB_565;
3538
import static com.squareup.picasso.BitmapHunter.createBitmapOptions;
3639
import static com.squareup.picasso.BitmapHunter.forRequest;
40+
import static com.squareup.picasso.BitmapHunter.requiresInSampleSize;
3741
import static com.squareup.picasso.BitmapHunter.transformResult;
3842
import static com.squareup.picasso.Picasso.LoadedFrom.MEMORY;
3943
import static com.squareup.picasso.TestUtils.ASSET_KEY_1;
@@ -50,8 +54,8 @@
5054
import static com.squareup.picasso.TestUtils.RESOURCE_ID_1;
5155
import static com.squareup.picasso.TestUtils.RESOURCE_ID_KEY_1;
5256
import static com.squareup.picasso.TestUtils.RESOURCE_ID_URI;
53-
import static com.squareup.picasso.TestUtils.RESOURCE_TYPE_URI;
5457
import static com.squareup.picasso.TestUtils.RESOURCE_ID_URI_KEY;
58+
import static com.squareup.picasso.TestUtils.RESOURCE_TYPE_URI;
5559
import static com.squareup.picasso.TestUtils.RESOURCE_TYPE_URI_KEY;
5660
import static com.squareup.picasso.TestUtils.URI_1;
5761
import static com.squareup.picasso.TestUtils.URI_KEY_1;
@@ -339,6 +343,34 @@ public class BitmapHunterTest {
339343
}
340344
}
341345

346+
@Test public void requiresComputeInSampleSize() {
347+
assertThat(requiresInSampleSize(null)).isFalse();
348+
final BitmapFactory.Options defaultOptions = new BitmapFactory.Options();
349+
assertThat(requiresInSampleSize(defaultOptions)).isFalse();
350+
final BitmapFactory.Options justBounds = new BitmapFactory.Options();
351+
justBounds.inJustDecodeBounds = true;
352+
assertThat(requiresInSampleSize(justBounds)).isTrue();
353+
}
354+
355+
@Test public void bitmapOptionsCreation() {
356+
// No resize must return no bitmap options
357+
final Request noResize = new Request.Builder(URI_1).build();
358+
final BitmapFactory.Options noResizeOptions = createBitmapOptions(noResize);
359+
assertThat(noResizeOptions).isNull();
360+
361+
// Resize must return bitmap options with inJustDecodeBounds = true
362+
final Request requiresResize = new Request.Builder(URI_1).resize(20, 15).build();
363+
final BitmapFactory.Options resizeOptions = createBitmapOptions(requiresResize);
364+
assertThat(resizeOptions).isNotNull();
365+
assertThat(resizeOptions.inJustDecodeBounds).isTrue();
366+
367+
// Given a config must return bitmap options and false inJustDecodeBounds
368+
final Request config = new Request.Builder(URI_1).config(RGB_565).build();
369+
final BitmapFactory.Options configOptions = createBitmapOptions(config);
370+
assertThat(configOptions).isNotNull();
371+
assertThat(configOptions.inJustDecodeBounds).isFalse();
372+
}
373+
342374
@Test public void centerCropTallTooSmall() throws Exception {
343375
Bitmap source = Bitmap.createBitmap(10, 20, ARGB_8888);
344376
Request data = new Request.Builder(URI_1).resize(40, 40).centerCrop().build();

0 commit comments

Comments
 (0)