diff options
| author | 2017-01-05 17:08:22 +0000 | |
|---|---|---|
| committer | 2017-01-05 17:08:27 +0000 | |
| commit | 3b72b9768fa40e8b43eceaa72f8d84594a2f0cc2 (patch) | |
| tree | d2b3b88fb652f48a184c589fb945baca090f8145 | |
| parent | b4413f694fbb8b03737d3e7a3831896bd371bed5 (diff) | |
| parent | 33e3741cad838d3228aeb110a107b021bf7b90a7 (diff) | |
Merge "Decode images to sRGB, premultiply based on framework define"
| -rw-r--r-- | core/jni/Android.mk | 1 | ||||
| -rw-r--r-- | core/jni/android/graphics/BitmapFactory.cpp | 52 |
2 files changed, 50 insertions, 3 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk index a13ebaf55cf4..252f168040df 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -215,6 +215,7 @@ LOCAL_C_INCLUDES += \ external/skia/src/effects \ external/skia/src/image \ external/skia/src/images \ + external/skia/src/utils \ external/sqlite/dist \ external/sqlite/android \ external/tremor/Tremor \ diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index 1165a45c1535..19d4848e1656 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -8,6 +8,7 @@ #include "SkBRDAllocator.h" #include "SkFrontBufferedStream.h" #include "SkMath.h" +#include "SkOpts.h" #include "SkPixelRef.h" #include "SkStream.h" #include "SkUtils.h" @@ -224,6 +225,45 @@ static bool needsFineScale(const SkISize fullSize, const SkISize decodedSize, needsFineScale(fullSize.height(), decodedSize.height(), sampleSize); } +static inline SkAlphaType computeDecodeAlphaType(SkColorType colorType, SkAlphaType alphaType) { +#ifndef ANDROID_ENABLE_LINEAR_BLENDING + // Skia premultiplies linearly. Until the framework enables linear blending, + // it expects a legacy premultiply. + if (kPremul_SkAlphaType == alphaType && kRGBA_F16_SkColorType != colorType) { + return kUnpremul_SkAlphaType; + } +#endif + + return alphaType; +} + +static inline void premultiplyIfNecessary(SkBitmap* bitmap, SkPMColor* colorPtr, int* colorCount, + SkAlphaType alphaType, bool requireUnpremultiplied) { +#ifndef ANDROID_ENABLE_LINEAR_BLENDING + if (kUnpremul_SkAlphaType != alphaType || requireUnpremultiplied) { + return; + } + + switch (bitmap->colorType()) { + case kN32_SkColorType: + for (int y = 0; y < bitmap->height(); y++) { + SkOpts::RGBA_to_rgbA(bitmap->getAddr32(0, y), bitmap->getAddr32(0, y), + bitmap->width()); + } + + return; + case kIndex_8_SkColorType: + SkOpts::RGBA_to_rgbA(colorPtr, colorPtr, *colorCount); + return; + default: + // kRGBA_F16 will be premultiplied by the codec if necessary. + // kGray_8 (alias kAlpha_8) and k565 are opaque. + LOG_ALWAYS_FATAL("Should be unreachable - no need for legacy premultiply."); + return; + } +#endif +} + static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding, jobject options) { // This function takes ownership of the input stream. Since the SkAndroidCodec // will take ownership of the stream, we don't necessarily need to take ownership @@ -391,13 +431,17 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding colorCount = &maxColors; } - // Set the alpha type for the decode. SkAlphaType alphaType = codec->computeOutputAlphaType(requireUnpremultiplied); + SkAlphaType decodeAlphaType = computeDecodeAlphaType(decodeColorType, alphaType); const SkImageInfo decodeInfo = SkImageInfo::Make(size.width(), size.height(), - decodeColorType, alphaType, GraphicsJNI::colorSpaceForType(decodeColorType)); + decodeColorType, decodeAlphaType, codec->computeOutputColorSpace(decodeColorType)); + + // When supported by the colorType, we will decode to sRGB (or linear sRGB). However, + // we only want to mark the bitmap as sRGB when linear blending is enabled. + SkImageInfo bitmapInfo = decodeInfo.makeAlphaType(alphaType) + .makeColorSpace(GraphicsJNI::colorSpaceForType(decodeColorType)); - SkImageInfo bitmapInfo = decodeInfo; if (decodeColorType == kGray_8_SkColorType) { // The legacy implementation of BitmapFactory used kAlpha8 for // grayscale images (before kGray8 existed). While the codec @@ -433,6 +477,8 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding default: return nullObjectReturn("codec->getAndroidPixels() failed."); } + premultiplyIfNecessary(&decodingBitmap, colorPtr, colorCount, decodeAlphaType, + requireUnpremultiplied); jbyteArray ninePatchChunk = NULL; if (peeker.mPatch != NULL) { |