Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6eeca5c7 authored by Leon Scroggins III's avatar Leon Scroggins III
Browse files

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
parent a6983622
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -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 @@ ImageDecoder::ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChu
    , mDecodeSize(mTargetSize)
    , mOutColorType(mCodec->computeOutputColorType(kN32_SkColorType))
    , mUnpremultipliedRequired(false)
    , mOutColorSpace(mCodec->computeOutputColorSpace(mOutColorType, nullptr))
    , mOutColorSpace(getDefaultColorSpace())
    , mSampleSize(1)
{
}
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ public:

    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.
+3 −3
Original line number Diff line number Diff line
@@ -213,12 +213,12 @@ int32_t AImageDecoderHeaderInfo_getDataSpace(const AImageDecoderHeaderInfo* info
        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);
}