Skip to content

Commit e638abc

Browse files
committed
Merge pull request square#386 from eveliotc/no-options-no-cry
Create Options only when needed
2 parents b684340 + 1953d56 commit e638abc

File tree

7 files changed

+73
-31
lines changed

7 files changed

+73
-31
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: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,28 @@ static BitmapHunter forRequest(Context context, Picasso picasso, Dispatcher disp
232232
}
233233
}
234234

235+
/**
236+
* Lazily create {@link android.graphics.BitmapFactory.Options} based in given
237+
* {@link com.squareup.picasso.Request}, only instantiating them if needed.
238+
*/
235239
static BitmapFactory.Options createBitmapOptions(Request data) {
236-
BitmapFactory.Options options = new BitmapFactory.Options();
237-
if (data.config != null) {
238-
options.inPreferredConfig = data.config;
240+
final boolean justBounds = data.hasSize();
241+
final boolean hasConfig = data.config != null;
242+
BitmapFactory.Options options = null;
243+
if (justBounds || hasConfig) {
244+
options = new BitmapFactory.Options();
245+
options.inJustDecodeBounds = justBounds;
246+
if (hasConfig) {
247+
options.inPreferredConfig = data.config;
248+
}
239249
}
240250
return options;
241251
}
242252

253+
static boolean requiresInSampleSize(BitmapFactory.Options options) {
254+
return options != null && options.inJustDecodeBounds;
255+
}
256+
243257
static void calculateInSampleSize(int reqWidth, int reqHeight, BitmapFactory.Options options) {
244258
calculateInSampleSize(reqWidth, reqHeight, options.outWidth, options.outHeight, options);
245259
}
@@ -252,7 +266,6 @@ static void calculateInSampleSize(int reqWidth, int reqHeight, int width, int he
252266
final int widthRatio = Math.round((float) width / (float) reqWidth);
253267
sampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
254268
}
255-
256269
options.inSampleSize = sampleSize;
257270
options.inJustDecodeBounds = false;
258271
}

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
@@ -84,25 +84,22 @@ private Bitmap decodeStream(InputStream stream, Request data) throws IOException
8484

8585
long mark = markStream.savePosition(MARKER);
8686

87+
final BitmapFactory.Options options = createBitmapOptions(data);
88+
final boolean calculateSize = requiresInSampleSize(options);
89+
8790
boolean isWebPFile = Utils.isWebPFile(stream);
8891
markStream.reset(mark);
8992
// When decode WebP network stream, BitmapFactory throw JNI Exception and make app crash.
9093
// Decode byte array instead
9194
if (isWebPFile) {
9295
byte[] bytes = Utils.toByteArray(stream);
93-
BitmapFactory.Options options = createBitmapOptions(data);
94-
if (data.hasSize()) {
95-
options.inJustDecodeBounds = true;
96-
96+
if (calculateSize) {
9797
BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
9898
calculateInSampleSize(data.targetWidth, data.targetHeight, options);
9999
}
100100
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
101101
} else {
102-
BitmapFactory.Options options = createBitmapOptions(data);
103-
if (data.hasSize()) {
104-
options.inJustDecodeBounds = true;
105-
102+
if (calculateSize) {
106103
BitmapFactory.decodeStream(stream, null, options);
107104
calculateInSampleSize(data.targetWidth, data.targetHeight, options);
108105

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: 40 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,38 @@ 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 nullBitmapOptionsIfNoResizing() {
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+
362+
@Test public void inJustDecodeBoundsIfResizing() {
363+
// Resize must return bitmap options with inJustDecodeBounds = true
364+
final Request requiresResize = new Request.Builder(URI_1).resize(20, 15).build();
365+
final BitmapFactory.Options resizeOptions = createBitmapOptions(requiresResize);
366+
assertThat(resizeOptions).isNotNull();
367+
assertThat(resizeOptions.inJustDecodeBounds).isTrue();
368+
}
369+
370+
@Test public void createWithConfigAndNotInJustDecodeBounds() {
371+
// Given a config must return bitmap options and false inJustDecodeBounds
372+
final Request config = new Request.Builder(URI_1).config(RGB_565).build();
373+
final BitmapFactory.Options configOptions = createBitmapOptions(config);
374+
assertThat(configOptions).isNotNull();
375+
assertThat(configOptions.inJustDecodeBounds).isFalse();
376+
}
377+
342378
@Test public void centerCropTallTooSmall() throws Exception {
343379
Bitmap source = Bitmap.createBitmap(10, 20, ARGB_8888);
344380
Request data = new Request.Builder(URI_1).resize(40, 40).centerCrop().build();

0 commit comments

Comments
 (0)