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

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

Merge "Replace setAlphaFlags with setUnpremultipliedRequired"

parents 5477bb44 1ade46d2
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -241,7 +241,7 @@ static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong
        doThrowISE(env, "Could not scale to target size!");
        doThrowISE(env, "Could not scale to target size!");
        return nullptr;
        return nullptr;
    }
    }
    if (requireUnpremul && !decoder->setOutAlphaType(kUnpremul_SkAlphaType)) {
    if (requireUnpremul && !decoder->setUnpremultipliedRequired(true)) {
        doThrowISE(env, "Cannot scale unpremultiplied pixels!");
        doThrowISE(env, "Cannot scale unpremultiplied pixels!");
        return nullptr;
        return nullptr;
    }
    }
@@ -301,11 +301,15 @@ static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong
        }
        }
    }
    }


    SkBitmap bm;
    SkImageInfo bitmapInfo = decoder->getOutputInfo();
    SkImageInfo bitmapInfo = decoder->getOutputInfo();
    if (decoder->opaque()) {
        bitmapInfo = bitmapInfo.makeAlphaType(kOpaque_SkAlphaType);
    }
    if (asAlphaMask && colorType == kGray_8_SkColorType) {
    if (asAlphaMask && colorType == kGray_8_SkColorType) {
        bitmapInfo = bitmapInfo.makeColorType(kAlpha_8_SkColorType);
        bitmapInfo = bitmapInfo.makeColorType(kAlpha_8_SkColorType);
    }
    }

    SkBitmap bm;
    if (!bm.setInfo(bitmapInfo)) {
    if (!bm.setInfo(bitmapInfo)) {
        doThrowIOE(env, "Failed to setInfo properly");
        doThrowIOE(env, "Failed to setInfo properly");
        return nullptr;
        return nullptr;
+18 −29
Original line number Original line Diff line number Diff line
@@ -30,19 +30,25 @@ ImageDecoder::ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChu
    , mTargetSize(mCodec->getInfo().dimensions())
    , mTargetSize(mCodec->getInfo().dimensions())
    , mDecodeSize(mTargetSize)
    , mDecodeSize(mTargetSize)
    , mOutColorType(mCodec->computeOutputColorType(kN32_SkColorType))
    , mOutColorType(mCodec->computeOutputColorType(kN32_SkColorType))
    , mOutAlphaType(mCodec->getInfo().isOpaque() ?
    , mUnpremultipliedRequired(false)
                    kOpaque_SkAlphaType : kPremul_SkAlphaType)
    , mOutColorSpace(mCodec->getInfo().refColorSpace())
    , mOutColorSpace(mCodec->getInfo().refColorSpace())
    , mSampleSize(1)
    , mSampleSize(1)
{
{
}
}


SkAlphaType ImageDecoder::getOutAlphaType() const {
    // While an SkBitmap may want to use kOpaque_SkAlphaType for a performance
    // optimization, this class just outputs raw pixels. Using either
    // premultiplication choice has no effect on decoding an opaque encoded image.
    return mUnpremultipliedRequired ? kUnpremul_SkAlphaType : kPremul_SkAlphaType;
}

bool ImageDecoder::setTargetSize(int width, int height) {
bool ImageDecoder::setTargetSize(int width, int height) {
    if (width <= 0 || height <= 0) {
    if (width <= 0 || height <= 0) {
        return false;
        return false;
    }
    }


    auto info = SkImageInfo::Make(width, height, mOutColorType, mOutAlphaType);
    auto info = SkImageInfo::Make(width, height, mOutColorType, getOutAlphaType());
    size_t rowBytes = info.minRowBytes();
    size_t rowBytes = info.minRowBytes();
    if (rowBytes == 0) {
    if (rowBytes == 0) {
        // This would have overflowed.
        // This would have overflowed.
@@ -63,7 +69,7 @@ bool ImageDecoder::setTargetSize(int width, int height) {
    SkISize targetSize = { width, height }, decodeSize = targetSize;
    SkISize targetSize = { width, height }, decodeSize = targetSize;
    int sampleSize = mCodec->computeSampleSize(&decodeSize);
    int sampleSize = mCodec->computeSampleSize(&decodeSize);


    if (decodeSize != targetSize && mOutAlphaType == kUnpremul_SkAlphaType
    if (decodeSize != targetSize && mUnpremultipliedRequired
            && !mCodec->getInfo().isOpaque()) {
            && !mCodec->getInfo().isOpaque()) {
        return false;
        return false;
    }
    }
@@ -119,29 +125,11 @@ bool ImageDecoder::setOutColorType(SkColorType colorType) {
    return true;
    return true;
}
}


bool ImageDecoder::setOutAlphaType(SkAlphaType alpha) {
bool ImageDecoder::setUnpremultipliedRequired(bool required) {
    switch (alpha) {
    if (required && !opaque() && mDecodeSize != mTargetSize) {
        case kOpaque_SkAlphaType:
            return opaque();
        case kPremul_SkAlphaType:
            if (opaque()) {
                // Opaque can be treated as premul.
                return true;
            }
            break;
        case kUnpremul_SkAlphaType:
            if (opaque()) {
                // Opaque can be treated as unpremul.
                return true;
            }
            if (mDecodeSize != mTargetSize) {
                return false;
            }
            break;
        default:
        return false;
        return false;
    }
    }
    mOutAlphaType = alpha;
    mUnpremultipliedRequired = required;
    return true;
    return true;
}
}


@@ -151,11 +139,11 @@ void ImageDecoder::setOutColorSpace(sk_sp<SkColorSpace> colorSpace) {


SkImageInfo ImageDecoder::getOutputInfo() const {
SkImageInfo ImageDecoder::getOutputInfo() const {
    SkISize size = mCropRect ? mCropRect->size() : mTargetSize;
    SkISize size = mCropRect ? mCropRect->size() : mTargetSize;
    return SkImageInfo::Make(size, mOutColorType, mOutAlphaType, mOutColorSpace);
    return SkImageInfo::Make(size, mOutColorType, getOutAlphaType(), mOutColorSpace);
}
}


bool ImageDecoder::opaque() const {
bool ImageDecoder::opaque() const {
    return mOutAlphaType == kOpaque_SkAlphaType;
    return mCodec->getInfo().alphaType() == kOpaque_SkAlphaType;
}
}


bool ImageDecoder::gray() const {
bool ImageDecoder::gray() const {
@@ -165,7 +153,8 @@ bool ImageDecoder::gray() const {
SkCodec::Result ImageDecoder::decode(void* pixels, size_t rowBytes) {
SkCodec::Result ImageDecoder::decode(void* pixels, size_t rowBytes) {
    void* decodePixels = pixels;
    void* decodePixels = pixels;
    size_t decodeRowBytes = rowBytes;
    size_t decodeRowBytes = rowBytes;
    auto decodeInfo = SkImageInfo::Make(mDecodeSize, mOutColorType, mOutAlphaType, mOutColorSpace);
    auto decodeInfo = SkImageInfo::Make(mDecodeSize, mOutColorType, getOutAlphaType(),
                                        mOutColorSpace);
    // Used if we need a temporary before scaling or subsetting.
    // Used if we need a temporary before scaling or subsetting.
    // FIXME: Use scanline decoding on only a couple lines to save memory. b/70709380.
    // FIXME: Use scanline decoding on only a couple lines to save memory. b/70709380.
    SkBitmap tmp;
    SkBitmap tmp;
+4 −4
Original line number Original line Diff line number Diff line
@@ -41,14 +41,12 @@ public:


    bool setOutColorType(SkColorType outColorType);
    bool setOutColorType(SkColorType outColorType);


    bool setOutAlphaType(SkAlphaType outAlphaType);
    bool setUnpremultipliedRequired(bool unpremultipliedRequired);


    void setOutColorSpace(sk_sp<SkColorSpace> cs);
    void setOutColorSpace(sk_sp<SkColorSpace> cs);


    // The size is the final size after scaling and cropping.
    // The size is the final size after scaling and cropping.
    SkImageInfo getOutputInfo() const;
    SkImageInfo getOutputInfo() const;
    SkColorType getOutColorType() const { return mOutColorType; }
    SkAlphaType getOutAlphaType() const { return mOutAlphaType; }


    bool opaque() const;
    bool opaque() const;
    bool gray() const;
    bool gray() const;
@@ -59,13 +57,15 @@ private:
    SkISize mTargetSize;
    SkISize mTargetSize;
    SkISize mDecodeSize;
    SkISize mDecodeSize;
    SkColorType mOutColorType;
    SkColorType mOutColorType;
    SkAlphaType mOutAlphaType;
    bool mUnpremultipliedRequired;
    sk_sp<SkColorSpace> mOutColorSpace;
    sk_sp<SkColorSpace> mOutColorSpace;
    int mSampleSize;
    int mSampleSize;
    std::optional<SkIRect> mCropRect;
    std::optional<SkIRect> mCropRect;


    ImageDecoder(const ImageDecoder&) = delete;
    ImageDecoder(const ImageDecoder&) = delete;
    ImageDecoder& operator=(const ImageDecoder&) = delete;
    ImageDecoder& operator=(const ImageDecoder&) = delete;

    SkAlphaType getOutAlphaType() const;
};
};


} // namespace android
} // namespace android
+3 −17
Original line number Original line Diff line number Diff line
@@ -241,26 +241,12 @@ int AImageDecoderHeaderInfo_getAlphaFlags(const AImageDecoderHeaderInfo* info) {
    }
    }
}
}


SkAlphaType toAlphaType(int androidBitmapFlags) {
int AImageDecoder_setUnpremultipliedRequired(AImageDecoder* decoder, bool required) {
    switch (androidBitmapFlags) {
    if (!decoder) {
        case ANDROID_BITMAP_FLAGS_ALPHA_PREMUL:
            return kPremul_SkAlphaType;
        case ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL:
            return kUnpremul_SkAlphaType;
        case ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE:
            return kOpaque_SkAlphaType;
        default:
            return kUnknown_SkAlphaType;
    }
}

int AImageDecoder_setAlphaFlags(AImageDecoder* decoder, int alphaFlag) {
    if (!decoder || alphaFlag < ANDROID_BITMAP_FLAGS_ALPHA_PREMUL
            || alphaFlag > ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL) {
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
    }
    }


    return toDecoder(decoder)->setOutAlphaType(toAlphaType(alphaFlag))
    return toDecoder(decoder)->setUnpremultipliedRequired(required)
            ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
            ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
}
}


+17 −17
Original line number Original line Diff line number Diff line
LIBJNIGRAPHICS {
LIBJNIGRAPHICS {
  global:
  global:
    AImageDecoder_createFromAAsset;
    AImageDecoder_createFromAAsset; # introduced=30
    AImageDecoder_createFromFd;
    AImageDecoder_createFromFd; # introduced=30
    AImageDecoder_createFromBuffer;
    AImageDecoder_createFromBuffer; # introduced=30
    AImageDecoder_delete;
    AImageDecoder_delete; # introduced=30
    AImageDecoder_setAndroidBitmapFormat;
    AImageDecoder_setAndroidBitmapFormat; # introduced=30
    AImageDecoder_setAlphaFlags;
    AImageDecoder_setUnpremultipliedRequired; # introduced=30
    AImageDecoder_getHeaderInfo;
    AImageDecoder_getHeaderInfo; # introduced=30
    AImageDecoder_getMinimumStride;
    AImageDecoder_getMinimumStride; # introduced=30
    AImageDecoder_decodeImage;
    AImageDecoder_decodeImage; # introduced=30
    AImageDecoder_setTargetSize;
    AImageDecoder_setTargetSize; # introduced=30
    AImageDecoder_setCrop;
    AImageDecoder_setCrop; # introduced=30
    AImageDecoderHeaderInfo_getWidth;
    AImageDecoderHeaderInfo_getWidth; # introduced=30
    AImageDecoderHeaderInfo_getHeight;
    AImageDecoderHeaderInfo_getHeight; # introduced=30
    AImageDecoderHeaderInfo_getMimeType;
    AImageDecoderHeaderInfo_getMimeType; # introduced=30
    AImageDecoderHeaderInfo_getAlphaFlags;
    AImageDecoderHeaderInfo_getAlphaFlags; # introduced=30
    AImageDecoderHeaderInfo_isAnimated;
    AImageDecoderHeaderInfo_isAnimated; # introduced=30
    AImageDecoderHeaderInfo_getAndroidBitmapFormat;
    AImageDecoderHeaderInfo_getAndroidBitmapFormat; # introduced=30
    AndroidBitmap_getInfo;
    AndroidBitmap_getInfo;
    AndroidBitmap_getDataSpace;
    AndroidBitmap_getDataSpace;
    AndroidBitmap_lockPixels;
    AndroidBitmap_lockPixels;