AImageDecoder: allow no color conversion

Bug: 135133301
Test: I5e8bdcdae6837db23c0f4ef08f931f3bebe0ce0d

Previously the default SkColorSpace for AImageDecoder was set to the
result of SkAndroidCodec::computeOutputColorSpace. If the image has a
profile that does not map to an SkColorSpace, it will return either
DISPLAY_P3 or SRGB. Using that at decode time will result in color
conversion.

Instead, default to a null SkColorSpace for such a profile, resulting in
no color conversion. If the image has no profile, default to SRGB, as
usual.

A client that wants SRGB can still request and get that, but this allows
getting the raw pixels for an advanced client that may want to do its
own conversion.

Change-Id: I489f31fef79dec11e97c8e8fb9207adb77a3d0c7
diff --git a/libs/hwui/hwui/ImageDecoder.cpp b/libs/hwui/hwui/ImageDecoder.cpp
index 4b2857f..afd82ac 100644
--- a/libs/hwui/hwui/ImageDecoder.cpp
+++ b/libs/hwui/hwui/ImageDecoder.cpp
@@ -24,6 +24,19 @@
 
 using namespace android;
 
+sk_sp<SkColorSpace> ImageDecoder::getDefaultColorSpace() const {
+    const skcms_ICCProfile* encodedProfile = mCodec->getICCProfile();
+    if (encodedProfile) {
+        // If the profile maps directly to an SkColorSpace, that SkColorSpace
+        // will be returned. Otherwise, nullptr will be returned. In either
+        // case, using this SkColorSpace results in doing no color correction.
+        return SkColorSpace::Make(*encodedProfile);
+    }
+
+    // The image has no embedded color profile, and should be treated as SRGB.
+    return SkColorSpace::MakeSRGB();
+}
+
 ImageDecoder::ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChunkReader> peeker)
     : mCodec(std::move(codec))
     , mPeeker(std::move(peeker))
@@ -31,7 +44,7 @@
     , mDecodeSize(mTargetSize)
     , mOutColorType(mCodec->computeOutputColorType(kN32_SkColorType))
     , mUnpremultipliedRequired(false)
-    , mOutColorSpace(mCodec->computeOutputColorSpace(mOutColorType, nullptr))
+    , mOutColorSpace(getDefaultColorSpace())
     , mSampleSize(1)
 {
 }
diff --git a/libs/hwui/hwui/ImageDecoder.h b/libs/hwui/hwui/ImageDecoder.h
index 0c99f84..a1b5157 100644
--- a/libs/hwui/hwui/ImageDecoder.h
+++ b/libs/hwui/hwui/ImageDecoder.h
@@ -43,6 +43,7 @@
 
     bool setUnpremultipliedRequired(bool unpremultipliedRequired);
 
+    sk_sp<SkColorSpace> getDefaultColorSpace() const;
     void setOutColorSpace(sk_sp<SkColorSpace> cs);
 
     // The size is the final size after scaling and cropping.
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp
index c1143ce..2e4d214 100644
--- a/native/graphics/jni/imagedecoder.cpp
+++ b/native/graphics/jni/imagedecoder.cpp
@@ -213,12 +213,12 @@
         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
     }
 
-    // Note: This recomputes the data space because it's possible the client has
-    // changed the output color space, so we cannot rely on it. Alternatively,
+    // Note: This recomputes the color type because it's possible the client has
+    // changed the output color type, so we cannot rely on it. Alternatively,
     // we could store the ADataSpace in the ImageDecoder.
     const ImageDecoder* imageDecoder = toDecoder(info);
     SkColorType colorType = imageDecoder->mCodec->computeOutputColorType(kN32_SkColorType);
-    sk_sp<SkColorSpace> colorSpace = imageDecoder->mCodec->computeOutputColorSpace(colorType);
+    sk_sp<SkColorSpace> colorSpace = imageDecoder->getDefaultColorSpace();
     return uirenderer::ColorSpaceToADataSpace(colorSpace.get(), colorType);
 }