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

Commit 3b72b976 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Decode images to sRGB, premultiply based on framework define"

parents b4413f69 33e3741c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 \
+49 −3
Original line number Diff line number Diff line
@@ -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) {