aboutsummaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorSam Judd <judds@google.com>2014-10-29 19:18:54 -0700
committerSam Judd <judds@google.com>2014-10-30 07:05:09 -0700
commit88868380fb22a5dae89d8664f2daa8c99522bc74 (patch)
treef17200666f744a85ae99c88df3f798aafac553f6 /library
parentb71d633d0fc091f3a4dc5615bb1f3467ca2df618 (diff)
downloadglide-88868380fb22a5dae89d8664f2daa8c99522bc74.tar.gz
Use sample size to acquire Bitmaps in Downsampler.
Fixes #224
Diffstat (limited to 'library')
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java33
1 files changed, 24 insertions, 9 deletions
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java
index e6143197..f5e17e95 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java
@@ -134,14 +134,7 @@ public abstract class Downsampler implements BitmapDecoder<InputStream> {
final int inHeight = inDimens[1];
final int degreesToRotate = TransformationUtils.getExifOrientationDegrees(orientation);
- final int sampleSize;
- if (degreesToRotate == 90 || degreesToRotate == 270) {
- // If we're rotating the image +-90 degrees, we need to downsample accordingly so the image width is
- // decreased to near our target's height and the image height is decreased to near our target width.
- sampleSize = getSampleSize(inHeight, inWidth, outWidth, outHeight);
- } else {
- sampleSize = getSampleSize(inWidth, inHeight, outWidth, outHeight);
- }
+ final int sampleSize = getRoundedSampleSize(degreesToRotate, inWidth, inHeight, outWidth, outHeight);
final Bitmap downsampled =
downsampleWithSize(stream, options, pool, inWidth, inHeight, sampleSize, decodeFormat);
@@ -172,6 +165,26 @@ public abstract class Downsampler implements BitmapDecoder<InputStream> {
}
}
+ private int getRoundedSampleSize(int degreesToRotate, int inWidth, int inHeight, int outWidth, int outHeight) {
+ final int exactSampleSize;
+ if (degreesToRotate == 90 || degreesToRotate == 270) {
+ // If we're rotating the image +-90 degrees, we need to downsample accordingly so the image width is
+ // decreased to near our target's height and the image height is decreased to near our target width.
+ exactSampleSize = getSampleSize(inHeight, inWidth, outWidth, outHeight);
+ } else {
+ exactSampleSize = getSampleSize(inWidth, inHeight, outWidth, outHeight);
+ }
+
+ // BitmapFactory only accepts powers of 2, so it will round down to the nearest power of two that is less than
+ // or equal to the sample size we provide. Because we need to estimate the final image width and height to
+ // re-use Bitmaps, we mirror BitmapFactory's calculation here. For bug, see issue #224. For algorithm see
+ // http://stackoverflow.com/a/17379704/800716.
+ final int powerOfTwoSampleSize = exactSampleSize == 0 ? 0 : Integer.highestOneBit(exactSampleSize - 1);
+
+ // Although functionally equivalent to 0 for BitmapFactory, 1 is a safer default for our code than 0.
+ return Math.max(1, powerOfTwoSampleSize);
+ }
+
protected Bitmap downsampleWithSize(InputStream is, BitmapFactory.Options options,
BitmapPool pool, int inWidth, int inHeight, int sampleSize, DecodeFormat decodeFormat) {
// Prior to KitKat, the inBitmap size must exactly match the size of the bitmap we're decoding.
@@ -179,8 +192,10 @@ public abstract class Downsampler implements BitmapDecoder<InputStream> {
options.inSampleSize = sampleSize;
options.inPreferredConfig = config;
if ((options.inSampleSize == 1 || Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) && shouldUsePool(is)) {
+ int targetWidth = (int) Math.ceil(inWidth / (double) sampleSize);
+ int targetHeight = (int) Math.ceil(inHeight / (double) sampleSize);
// BitmapFactory will clear out the Bitmap before writing to it, so getDirty is safe.
- setInBitmap(options, pool.getDirty(inWidth, inHeight, config));
+ setInBitmap(options, pool.getDirty(targetWidth, targetHeight, config));
}
return decodeStream(is, options);
}