From 73277df1debcf894aece03f0d1b2852281c266a5 Mon Sep 17 00:00:00 2001 From: Sam Judd Date: Tue, 16 Jan 2018 21:13:46 -0800 Subject: [PATCH] Avoid converting RGBA_F16 to ARGB_8888 in TransformationUtils. --- checkstyle.xml | 2 +- .../com/bumptech/glide/WideGamutTest.java | 33 +++++++++++++++ .../resource/bitmap/TransformationUtils.java | 40 +++++++++++++------ 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/checkstyle.xml b/checkstyle.xml index c2a00167d8..52a2c2e5d5 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -73,7 +73,7 @@ - + diff --git a/instrumentation/src/androidTest/java/com/bumptech/glide/WideGamutTest.java b/instrumentation/src/androidTest/java/com/bumptech/glide/WideGamutTest.java index 60bef4c88e..0b72432c92 100644 --- a/instrumentation/src/androidTest/java/com/bumptech/glide/WideGamutTest.java +++ b/instrumentation/src/androidTest/java/com/bumptech/glide/WideGamutTest.java @@ -15,6 +15,7 @@ import com.bumptech.glide.load.DecodeFormat; import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.test.ConcurrencyHelper; import com.bumptech.glide.test.GlideApp; import com.bumptech.glide.test.ResourceIds; @@ -155,6 +156,38 @@ public void load_withSmallerWideGamutInPool_decodesBitmap() { assertThat(bitmap).isNotNull(); } + @Test + public void circleCrop_withWideGamutBitmap_producesWideGamutBitmap() { + Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.RGBA_F16); + byte[] data = asPng(bitmap); + + Bitmap result = + concurrency.get( + GlideApp.with(context) + .asBitmap() + .load(data) + .circleCrop() + .submit()); + assertThat(result).isNotNull(); + assertThat(result.getConfig()).isEqualTo(Config.RGBA_F16); + } + + @Test + public void roundedCorners_withWideGamutBitmap_producesWideGamutBitmap() { + Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.RGBA_F16); + byte[] data = asPng(bitmap); + + Bitmap result = + concurrency.get( + GlideApp.with(context) + .asBitmap() + .load(data) + .transform(new RoundedCorners(/*roundingRadius=*/ 10)) + .submit()); + assertThat(result).isNotNull(); + assertThat(result.getConfig()).isEqualTo(Config.RGBA_F16); + } + private static byte[] asJpeg(Bitmap bitmap) { return toByteArray(bitmap, CompressFormat.JPEG); } diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java index 8978e818ce..1c4d4812c0 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java @@ -1,6 +1,7 @@ package com.bumptech.glide.load.resource.bitmap; import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; @@ -137,7 +138,7 @@ public static Bitmap centerCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitm m.setScale(scale, scale); m.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f)); - Bitmap result = pool.get(width, height, getSafeConfig(inBitmap)); + Bitmap result = pool.get(width, height, getNonNullConfig(inBitmap)); // We don't add or remove alpha, so keep the alpha setting of the Bitmap we were given. TransformationUtils.setAlpha(inBitmap, result); @@ -186,7 +187,7 @@ public static Bitmap fitCenter(@NonNull BitmapPool pool, @NonNull Bitmap inBitma targetWidth = (int) (minPercentage * inBitmap.getWidth()); targetHeight = (int) (minPercentage * inBitmap.getHeight()); - Bitmap.Config config = getSafeConfig(inBitmap); + Bitmap.Config config = getNonNullConfig(inBitmap); Bitmap toReuse = pool.get(targetWidth, targetHeight, config); // We don't add or remove alpha, so keep the alpha setting of the Bitmap we were given. @@ -324,7 +325,7 @@ public static Bitmap rotateImageExif(@NonNull BitmapPool pool, @NonNull Bitmap i final int newWidth = Math.round(newRect.width()); final int newHeight = Math.round(newRect.height()); - Bitmap.Config config = getSafeConfig(inBitmap); + Bitmap.Config config = getNonNullConfig(inBitmap); Bitmap result = pool.get(newWidth, newHeight, config); matrix.postTranslate(-newRect.left, -newRect.top); @@ -384,7 +385,8 @@ public static Bitmap circleCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitm // Alpha is required for this transformation. Bitmap toTransform = getAlphaSafeBitmap(pool, inBitmap); - Bitmap result = pool.get(destMinEdge, destMinEdge, Bitmap.Config.ARGB_8888); + Bitmap.Config outConfig = getAlphaSafeConfig(inBitmap); + Bitmap result = pool.get(destMinEdge, destMinEdge, outConfig); result.setHasAlpha(true); BITMAP_DRAWABLE_LOCK.lock(); @@ -406,14 +408,15 @@ public static Bitmap circleCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitm return result; } - private static Bitmap getAlphaSafeBitmap(@NonNull BitmapPool pool, - @NonNull Bitmap maybeAlphaSafe) { - if (Bitmap.Config.ARGB_8888.equals(maybeAlphaSafe.getConfig())) { + private static Bitmap getAlphaSafeBitmap( + @NonNull BitmapPool pool, @NonNull Bitmap maybeAlphaSafe) { + Bitmap.Config safeConfig = getAlphaSafeConfig(maybeAlphaSafe); + if (safeConfig.equals(maybeAlphaSafe.getConfig())) { return maybeAlphaSafe; } - Bitmap argbBitmap = pool.get(maybeAlphaSafe.getWidth(), maybeAlphaSafe.getHeight(), - Bitmap.Config.ARGB_8888); + Bitmap argbBitmap = + pool.get(maybeAlphaSafe.getWidth(), maybeAlphaSafe.getHeight(), safeConfig); new Canvas(argbBitmap).drawBitmap(maybeAlphaSafe, 0 /*left*/, 0 /*top*/, null /*paint*/); // We now own this Bitmap. It's our responsibility to replace it in the pool outside this method @@ -421,6 +424,18 @@ private static Bitmap getAlphaSafeBitmap(@NonNull BitmapPool pool, return argbBitmap; } + @NonNull + private static Config getAlphaSafeConfig(@NonNull Bitmap inBitmap) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // Avoid short circuiting the sdk check. + if (Bitmap.Config.RGBA_F16.equals(inBitmap.getConfig())) { // NOPMD + return Bitmap.Config.RGBA_F16; + } + } + + return Bitmap.Config.ARGB_8888; + } + /** * Creates a bitmap from a source bitmap and rounds the corners. * @@ -462,9 +477,9 @@ public static Bitmap roundedCorners( Preconditions.checkArgument(roundingRadius > 0, "roundingRadius must be greater than 0."); // Alpha is required for this transformation. + Bitmap.Config safeConfig = getAlphaSafeConfig(inBitmap); Bitmap toTransform = getAlphaSafeBitmap(pool, inBitmap); - Bitmap result = - pool.get(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888); + Bitmap result = pool.get(toTransform.getWidth(), toTransform.getHeight(), safeConfig); result.setHasAlpha(true); @@ -496,7 +511,8 @@ private static void clear(Canvas canvas) { canvas.setBitmap(null); } - private static Bitmap.Config getSafeConfig(Bitmap bitmap) { + @NonNull + private static Bitmap.Config getNonNullConfig(@NonNull Bitmap bitmap) { return bitmap.getConfig() != null ? bitmap.getConfig() : Bitmap.Config.ARGB_8888; }