From ea978db1f86b8c6fae3683eafe6621fd958308d7 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Sat, 13 Jan 2018 11:40:42 -0500 Subject: [PATCH] Switch to SkAndroidCodec::computeSampleSize Bug: 63909536 Test: CtsGraphicsTestCases(ImageDecoderTest) and Skia Depends on https://skia-review.googlesource.com/94620 in Skia. Move the code for determining the actual sample size to Skia. That code includes tests which caught bugs that are hard to test for from the Java API. (Previously, we could end up using the wrong sample size and then scaling unnecessarily.) Change-Id: Ib3a5d70e4845e95b18af77668383d38746cb21fc --- core/jni/android/graphics/ImageDecoder.cpp | 40 +++++----------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/core/jni/android/graphics/ImageDecoder.cpp b/core/jni/android/graphics/ImageDecoder.cpp index a0a4be4590be9..ea9c7722cc87a 100644 --- a/core/jni/android/graphics/ImageDecoder.cpp +++ b/core/jni/android/graphics/ImageDecoder.cpp @@ -160,11 +160,6 @@ static jobject ImageDecoder_nCreateByteArray(JNIEnv* env, jobject /*clazz*/, jby return native_create(env, std::move(stream)); } -static bool supports_any_down_scale(const SkAndroidCodec* codec) { - return codec->getEncodedFormat() == SkEncodedImageFormat::kWEBP; -} - -// This method should never return null. Instead, it should throw an exception. static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong nativePtr, jobject jcallback, jobject jpostProcess, jint desiredWidth, jint desiredHeight, jobject jsubset, @@ -173,33 +168,14 @@ static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong jboolean asAlphaMask) { auto* decoder = reinterpret_cast(nativePtr); SkAndroidCodec* codec = decoder->mCodec.get(); - SkImageInfo decodeInfo = codec->getInfo(); - bool scale = false; - int sampleSize = 1; - if (desiredWidth != decodeInfo.width() || desiredHeight != decodeInfo.height()) { - bool match = false; - if (desiredWidth < decodeInfo.width() && desiredHeight < decodeInfo.height()) { - if (supports_any_down_scale(codec)) { - match = true; - decodeInfo = decodeInfo.makeWH(desiredWidth, desiredHeight); - } else { - int sampleX = decodeInfo.width() / desiredWidth; - int sampleY = decodeInfo.height() / desiredHeight; - sampleSize = std::min(sampleX, sampleY); - SkISize sampledSize = codec->getSampledDimensions(sampleSize); - decodeInfo = decodeInfo.makeWH(sampledSize.width(), sampledSize.height()); - if (decodeInfo.width() == desiredWidth && decodeInfo.height() == desiredHeight) { - match = true; - } - } - } - if (!match) { - scale = true; - if (requireUnpremul && kOpaque_SkAlphaType != decodeInfo.alphaType()) { - doThrowISE(env, "Cannot scale unpremultiplied pixels!"); - return nullptr; - } - } + const SkISize desiredSize = SkISize::Make(desiredWidth, desiredHeight); + SkISize decodeSize = desiredSize; + const int sampleSize = codec->computeSampleSize(&decodeSize); + const bool scale = desiredSize != decodeSize; + SkImageInfo decodeInfo = codec->getInfo().makeWH(decodeSize.width(), decodeSize.height()); + if (scale && requireUnpremul && kOpaque_SkAlphaType != decodeInfo.alphaType()) { + doThrowISE(env, "Cannot scale unpremultiplied pixels!"); + return nullptr; } switch (decodeInfo.alphaType()) {