From 4856210398468fd5196e1cb68b80e7529e1046a0 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Fri, 9 Mar 2018 11:59:17 -0500 Subject: [PATCH] Encode F16 Bitmaps to 8-bit P3 Bug: 73743812 Bug: 71430152 Test: If2c3ee0f32eff77b11ce5a7fe82c02811ed1beb3 This matches how we handle decoding images with a wide gamut. For WebP and JPEG, we cannot encode with more precision anyway. For PNG, we could in theory encode to 16 bit linear PNGs. This would be more precise, but would still throw away information due to normalization. Using 8-bit P3 matches the behavior for the other formats, so it is nice to be consistent. Change-Id: I69a44a3eff70e26448a75ecc63ed7604b9c74a95 --- core/jni/android/graphics/Bitmap.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index 5498a931718dc..ce4e384f253ae 100755 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -921,6 +921,28 @@ static jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle, SkBitmap skbitmap; bitmap->getSkBitmap(&skbitmap); + if (skbitmap.colorType() == kRGBA_F16_SkColorType) { + // Convert to P3 before encoding. This matches SkAndroidCodec::computeOutputColorSpace + // for wide gamuts. + auto cs = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, + SkColorSpace::kDCIP3_D65_Gamut); + auto info = skbitmap.info().makeColorType(kRGBA_8888_SkColorType) + .makeColorSpace(std::move(cs)); + SkBitmap p3; + if (!p3.tryAllocPixels(info)) { + return JNI_FALSE; + } + auto xform = SkColorSpaceXform::New(skbitmap.colorSpace(), info.colorSpace()); + if (!xform) { + return JNI_FALSE; + } + if (!xform->apply(SkColorSpaceXform::kRGBA_8888_ColorFormat, p3.getPixels(), + SkColorSpaceXform::kRGBA_F16_ColorFormat, skbitmap.getPixels(), + info.width() * info.height(), kUnpremul_SkAlphaType)) { + return JNI_FALSE; + } + skbitmap = p3; + } return SkEncodeImage(strm.get(), skbitmap, fm, quality) ? JNI_TRUE : JNI_FALSE; }