Skip to content

Commit

Permalink
Automated g4 rollback of changelist 108724201.
Browse files Browse the repository at this point in the history
*** Reason for rollback ***

Rollforward with compatibility for apps targeting API 21

*** Original change description ***

Automated g4 rollback of changelist 108709885.

*** Reason for rollback ***

Broke Street View

*** Original change description ***

MOE automated commit.

Merge pull request bumptech#762 from vanniktech/master_clean_upload_script

Clean upload script up

-------------
Merge pull request bumptech#727 from josemontiel/master

Implemented CENTER_INSIDE support

-------------
Update Downsampler names.

-------------
Merge pull request bumptech#758 from mullender/glide-issue-738

fix for issue bumptech#738 Some images simply do no...

***
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=108748541
  • Loading branch information
sjudd committed Dec 2, 2015
1 parent 2ab0e01 commit 32f25e6
Show file tree
Hide file tree
Showing 10 changed files with 373 additions and 32 deletions.
3 changes: 3 additions & 0 deletions library/src/main/java/com/bumptech/glide/RequestBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,9 @@ public Target<TranscodeType> into(ImageView view) {
case CENTER_CROP:
requestOptions.optionalCenterCrop(context);
break;
case CENTER_INSIDE:
requestOptions.optionalCenterInside(context);
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.bumptech.glide.load.resource.bitmap;

import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;

import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;

import java.security.MessageDigest;

/**
* Returns the image with its original size if its dimensions match or are smaller
* than the target's, couple with {@link android.widget.ImageView.ScaleType#CENTER_INSIDE}
* in order to center it in Target. If not, then it is scaled so that one of the dimensions of
* the image will be equal to the given dimension and the other will be less than the given
* dimension (maintaining the image's aspect ratio).
*/
public class CenterInside extends BitmapTransformation {
private static final String ID = "com.bumptech.glide.load.resource.bitmap.CenterInside";
private static final byte[] ID_BYTES = ID.getBytes(CHARSET);

public CenterInside(Context context) {
super(context);
}

public CenterInside(BitmapPool bitmapPool) {
super(bitmapPool);
}

@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth,
int outHeight) {
return TransformationUtils.centerInside(pool, toTransform, outWidth, outHeight);
}

@Override
public boolean equals(Object o) {
return o instanceof CenterInside;
}

@Override
public int hashCode() {
return ID.hashCode();
}

@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
messageDigest.update(ID_BYTES);
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,22 @@ public abstract class DownsampleStrategy {
* requested size.
*
* <p>This method will upscale if the requested width and height are greater than the source width
* and height. To avoid upscaling, use {@link #AT_LEAST} or {@link #AT_MOST}.
* and height. To avoid upscaling, use {@link #AT_LEAST}, {@link #AT_MOST} or
* {@link #CENTER_INSIDE}.
*
* <p>On pre-KitKat devices, this is equivalent to {@link #AT_MOST} because only power of
* two downsampling can be used.
*/
public static final DownsampleStrategy CENTER_INSIDE = new CenterInside();
public static final DownsampleStrategy FIT_CENTER = new FitCenter();

/**
* Scales, maintaining the original aspect ratio, so that one of the image's dimensions is
* exactly equal to the requested size and the other dimension is greater than or equal to
* the requested size.
*
* <p>This method will upscale if the requested width and height are greater than the source width
* and height. To avoid upscaling, use {@link #AT_LEAST} or {@link #AT_MOST}.
* and height. To avoid upscaling, use {@link #AT_LEAST}, {@link #AT_MOST},
* or {@link #CENTER_INSIDE}.
*
* <p>On pre-KitKat devices, this is equivalent to {@link #AT_LEAST} because only power of
* two downsampling can be used.
Expand All @@ -43,6 +45,15 @@ public abstract class DownsampleStrategy {
*/
public static final DownsampleStrategy AT_MOST = new AtMost();

/**
* Returns the original image if it is smaller than the target, otherwise it will be downscaled
* maintaining its original aspect ratio, so that one of the image's dimensions is exactly equal
* to the requested size and the other is less or equal than the requested size.
*
* <p>This method will not upscale.</p>
*/
public static final DownsampleStrategy CENTER_INSIDE = new CenterInside();

/**
* Performs no downsampling or scaling.
*/
Expand Down Expand Up @@ -86,7 +97,7 @@ public abstract float getScaleFactor(int sourceWidth, int sourceHeight, int requ
public abstract SampleSizeRounding getSampleSizeRounding(int sourceWidth, int sourceHeight,
int requestedWidth, int requestedHeight);

private static class CenterInside extends DownsampleStrategy {
private static class FitCenter extends DownsampleStrategy {

@Override
public float getScaleFactor(int sourceWidth, int sourceHeight, int requestedWidth,
Expand Down Expand Up @@ -168,6 +179,23 @@ public SampleSizeRounding getSampleSizeRounding(int sourceWidth, int sourceHeigh
}
}

private static class CenterInside extends DownsampleStrategy {

@Override
public float getScaleFactor(int sourceWidth, int sourceHeight, int requestedWidth,
int requestedHeight) {

return Math.min(1.f,
FIT_CENTER.getScaleFactor(sourceWidth, sourceHeight, requestedWidth, requestedHeight));
}

@Override
public SampleSizeRounding getSampleSizeRounding(int sourceWidth, int sourceHeight,
int requestedWidth, int requestedHeight) {
return SampleSizeRounding.QUALITY;
}
}

/**
* Indicates whether to prefer to prefer downsampling or scaling to prefer lower memory usage
* or higher quality.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,17 +400,19 @@ private static Bitmap decodeStream(InputStream is, BitmapFactory.Options options
int sourceHeight = options.outHeight;
String outMimeType = options.outMimeType;
final Bitmap result;
TransformationUtils.getBitmapDrawableLock().lock();
try {
result = BitmapFactory.decodeStream(is, null, options);
} catch (IllegalArgumentException e) {
throw newIoExceptionForInBitmapAssertion(e, sourceWidth, sourceHeight, outMimeType, options);
} finally {
TransformationUtils.getBitmapDrawableLock().unlock();
}

if (options.inJustDecodeBounds) {
is.reset();

}

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.util.Preconditions;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* A class with methods to efficiently resize Bitmaps.
*/
Expand All @@ -30,6 +35,18 @@ public final class TransformationUtils {
private static final int CIRCLE_CROP_PAINT_FLAGS = PAINT_FLAGS | Paint.ANTI_ALIAS_FLAG;
private static final Paint CIRCLE_CROP_SHAPE_PAINT = new Paint(CIRCLE_CROP_PAINT_FLAGS);
private static final Paint CIRCLE_CROP_BITMAP_PAINT;
/**
* https://github.com/bumptech/glide/issues/738 On some devices (Moto X with android 5.1) bitmap
* drawing is not thread safe.
* This lock only locks for these specific devices. For other types of devices the lock is always
* available and therefore does not impact performance
*/
private static final Lock BITMAP_DRAWABLE_LOCK = "XT1097".equals(Build.MODEL)
// TODO: Switch to Build.VERSION_CODES.LOLLIPOP_MR1 when apps have updated target API levels.
&& Build.VERSION.SDK_INT == 22
? new ReentrantLock()
: new NoLock();

static {
CIRCLE_CROP_BITMAP_PAINT = new Paint(CIRCLE_CROP_PAINT_FLAGS);
CIRCLE_CROP_BITMAP_PAINT.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
Expand All @@ -39,6 +56,11 @@ private TransformationUtils() {
// Utility class.
}


public static Lock getBitmapDrawableLock() {
return BITMAP_DRAWABLE_LOCK;
}

/**
* A potentially expensive operation to crop the given Bitmap so that it fills the given
* dimensions. This operation is significantly less expensive in terms of memory if a mutable
Expand Down Expand Up @@ -74,9 +96,7 @@ public static Bitmap centerCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitm
// We don't add or remove alpha, so keep the alpha setting of the Bitmap we were given.
TransformationUtils.setAlpha(inBitmap, result);

Canvas canvas = new Canvas(result);
canvas.drawBitmap(inBitmap, m, DEFAULT_PAINT);
clear(canvas);
applyMatrix(inBitmap, result, m);
return result;
}

Expand Down Expand Up @@ -129,15 +149,39 @@ public static Bitmap fitCenter(@NonNull BitmapPool pool, @NonNull Bitmap inBitma
Log.v(TAG, "minPct: " + minPercentage);
}

Canvas canvas = new Canvas(toReuse);
Matrix matrix = new Matrix();
matrix.setScale(minPercentage, minPercentage);
canvas.drawBitmap(inBitmap, matrix, DEFAULT_PAINT);
clear(canvas);
applyMatrix(inBitmap, toReuse, matrix);

return toReuse;
}

/**
* If the Bitmap is smaller or equal to the Target it returns the original size, if not then
* {@link #fitCenter(BitmapPool, Bitmap, int, int)} is called instead.
*
* @param pool The BitmapPool obtain a bitmap from.
* @param inBitmap The Bitmap to center.
* @param width The width in pixels of the target.
* @param height The height in pixels of the target.
* @return returns input Bitmap if smaller or equal to target, or toFit if the Bitmap's width or
* height is larger than the given dimensions
*/
public static Bitmap centerInside(@NonNull BitmapPool pool, @NonNull Bitmap inBitmap, int width,
int height) {
if (inBitmap.getWidth() <= width && inBitmap.getHeight() <= height) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "requested target size larger or equal to input, returning input");
}
return inBitmap;
} else {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "requested target size too big for input, fit centering instead");
}
return fitCenter(pool, inBitmap, width, height);
}
}

/**
* Sets the alpha of the Bitmap we're going to re-use to the alpha of the Bitmap we're going to
* transform. This keeps {@link android.graphics.Bitmap#hasAlpha()}} consistent before and after
Expand Down Expand Up @@ -240,10 +284,7 @@ public static Bitmap rotateImageExif(@NonNull BitmapPool pool, @NonNull Bitmap i

matrix.postTranslate(-newRect.left, -newRect.top);

final Canvas canvas = new Canvas(result);
canvas.drawBitmap(inBitmap, matrix, DEFAULT_PAINT);
clear(canvas);

applyMatrix(inBitmap, result, matrix);
return result;
}

Expand Down Expand Up @@ -275,15 +316,20 @@ public static Bitmap circleCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitm

Bitmap result = pool.get(destWidth, destHeight, getSafeConfig(toTransform));
setAlphaIfAvailable(result, true /*hasAlpha*/);
Canvas canvas = new Canvas(result);

// Draw a circle
canvas.drawCircle(destRect.left + radius, destRect.top + radius, radius,
CIRCLE_CROP_SHAPE_PAINT);

// Draw the bitmap in the circle
canvas.drawBitmap(toTransform, srcRect, destRect, CIRCLE_CROP_BITMAP_PAINT);
clear(canvas);
BITMAP_DRAWABLE_LOCK.lock();
try {
Canvas canvas = new Canvas(result);
// Draw a circle
canvas.drawCircle(destRect.left + radius, destRect.top + radius, radius,
CIRCLE_CROP_SHAPE_PAINT);
// Draw the bitmap in the circle
canvas.drawBitmap(toTransform, srcRect, destRect, CIRCLE_CROP_BITMAP_PAINT);
clear(canvas);
} finally {
BITMAP_DRAWABLE_LOCK.unlock();
}

if (!toTransform.equals(inBitmap)) {
pool.put(toTransform);
Expand Down Expand Up @@ -335,10 +381,15 @@ public static Bitmap roundedCorners(@NonNull BitmapPool pool, @NonNull Bitmap in
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rect = new RectF(0, 0, result.getWidth(), result.getHeight());
Canvas canvas = new Canvas(result);
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.drawRoundRect(rect, roundingRadius, roundingRadius, paint);
clear(canvas);
BITMAP_DRAWABLE_LOCK.lock();
try {
Canvas canvas = new Canvas(result);
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.drawRoundRect(rect, roundingRadius, roundingRadius, paint);
clear(canvas);
} finally {
BITMAP_DRAWABLE_LOCK.unlock();
}

if (!toTransform.equals(inBitmap)) {
pool.put(toTransform);
Expand All @@ -356,6 +407,18 @@ private static Bitmap.Config getSafeConfig(Bitmap bitmap) {
return bitmap.getConfig() != null ? bitmap.getConfig() : Bitmap.Config.ARGB_8888;
}

private static void applyMatrix(@NonNull Bitmap inBitmap, @NonNull Bitmap targetBitmap,
Matrix matrix) {
BITMAP_DRAWABLE_LOCK.lock();
try {
Canvas canvas = new Canvas(targetBitmap);
canvas.drawBitmap(inBitmap, matrix, DEFAULT_PAINT);
clear(canvas);
} finally {
BITMAP_DRAWABLE_LOCK.unlock();
}
}

// Visible for testing.
static void initializeMatrixForRotation(int exifOrientation, Matrix matrix) {
switch (exifOrientation) {
Expand Down Expand Up @@ -387,4 +450,37 @@ static void initializeMatrixForRotation(int exifOrientation, Matrix matrix) {
// Do nothing.
}
}

private static final class NoLock implements Lock {
@Override
public void lock() {
// do nothing
}

@Override
public void lockInterruptibly() throws InterruptedException {
// do nothing
}

@Override
public boolean tryLock() {
return true;
}

@Override
public boolean tryLock(long time, @NonNull TimeUnit unit) throws InterruptedException {
return true;
}

@Override
public void unlock() {
// do nothing
}

@NonNull
@Override
public Condition newCondition() {
throw new UnsupportedOperationException("Should not be called");
}
}
}
Loading

0 comments on commit 32f25e6

Please sign in to comment.