Loading libs/hwui/hwui/ImageDecoder.cpp +9 −4 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ ImageDecoder::ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChu , mDecodeSize(mTargetSize) , mOutColorType(mCodec->computeOutputColorType(kN32_SkColorType)) , mUnpremultipliedRequired(false) , mOutColorSpace(mCodec->getInfo().refColorSpace()) , mOutColorSpace(mCodec->computeOutputColorSpace(mOutColorType, nullptr)) , mSampleSize(1) { } Loading Loading @@ -111,7 +111,6 @@ bool ImageDecoder::setOutColorType(SkColorType colorType) { if (!gray()) { return false; } mOutColorSpace = nullptr; break; case kN32_SkColorType: break; Loading @@ -137,9 +136,15 @@ void ImageDecoder::setOutColorSpace(sk_sp<SkColorSpace> colorSpace) { mOutColorSpace = std::move(colorSpace); } sk_sp<SkColorSpace> ImageDecoder::getOutputColorSpace() const { // kGray_8 is used for ALPHA_8, which ignores the color space. return mOutColorType == kGray_8_SkColorType ? nullptr : mOutColorSpace; } SkImageInfo ImageDecoder::getOutputInfo() const { SkISize size = mCropRect ? mCropRect->size() : mTargetSize; return SkImageInfo::Make(size, mOutColorType, getOutAlphaType(), mOutColorSpace); return SkImageInfo::Make(size, mOutColorType, getOutAlphaType(), getOutputColorSpace()); } bool ImageDecoder::opaque() const { Loading @@ -154,7 +159,7 @@ SkCodec::Result ImageDecoder::decode(void* pixels, size_t rowBytes) { void* decodePixels = pixels; size_t decodeRowBytes = rowBytes; auto decodeInfo = SkImageInfo::Make(mDecodeSize, mOutColorType, getOutAlphaType(), mOutColorSpace); getOutputColorSpace()); // Used if we need a temporary before scaling or subsetting. // FIXME: Use scanline decoding on only a couple lines to save memory. b/70709380. SkBitmap tmp; Loading libs/hwui/hwui/ImageDecoder.h +1 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ private: ImageDecoder& operator=(const ImageDecoder&) = delete; SkAlphaType getOutAlphaType() const; sk_sp<SkColorSpace> getOutputColorSpace() const; }; } // namespace android native/graphics/jni/imagedecoder.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ #include <android/asset_manager.h> #include <android/bitmap.h> #include <android/data_space.h> #include <android/imagedecoder.h> #include <android/graphics/MimeType.h> #include <android/rect.h> #include <hwui/ImageDecoder.h> #include <log/log.h> #include <SkAndroidCodec.h> #include <utils/Color.h> #include <fcntl.h> #include <optional> Loading Loading @@ -165,6 +167,18 @@ int AImageDecoder_setAndroidBitmapFormat(AImageDecoder* decoder, int32_t format) ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION; } int AImageDecoder_setDataSpace(AImageDecoder* decoder, int32_t dataspace) { sk_sp<SkColorSpace> cs = uirenderer::DataSpaceToColorSpace((android_dataspace)dataspace); // 0 is ADATASPACE_UNKNOWN. We need an explicit request for an ADataSpace. if (!decoder || !dataspace || !cs) { return ANDROID_IMAGE_DECODER_BAD_PARAMETER; } ImageDecoder* imageDecoder = toDecoder(decoder); imageDecoder->setOutColorSpace(std::move(cs)); return ANDROID_IMAGE_DECODER_SUCCESS; } const AImageDecoderHeaderInfo* AImageDecoder_getHeaderInfo(const AImageDecoder* decoder) { return reinterpret_cast<const AImageDecoderHeaderInfo*>(decoder); } Loading Loading @@ -201,6 +215,20 @@ bool AImageDecoderHeaderInfo_isAnimated(const AImageDecoderHeaderInfo* info) { return toDecoder(info)->mCodec->codec()->getFrameCount() > 1; } int32_t AImageDecoderHeaderInfo_getDataSpace(const AImageDecoderHeaderInfo* info) { if (!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, // 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); return uirenderer::ColorSpaceToADataSpace(colorSpace.get(), colorType); } // FIXME: Share with getFormat in android_bitmap.cpp? static AndroidBitmapFormat getFormat(SkColorType colorType) { switch (colorType) { Loading native/graphics/jni/libjnigraphics.map.txt +2 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ LIBJNIGRAPHICS { AImageDecoder_delete; # introduced=30 AImageDecoder_setAndroidBitmapFormat; # introduced=30 AImageDecoder_setUnpremultipliedRequired; # introduced=30 AImageDecoder_setDataSpace; # introduced=30 AImageDecoder_getHeaderInfo; # introduced=30 AImageDecoder_getMinimumStride; # introduced=30 AImageDecoder_decodeImage; # introduced=30 Loading @@ -18,6 +19,7 @@ LIBJNIGRAPHICS { AImageDecoderHeaderInfo_getAlphaFlags; # introduced=30 AImageDecoderHeaderInfo_isAnimated; # introduced=30 AImageDecoderHeaderInfo_getAndroidBitmapFormat; # introduced=30 AImageDecoderHeaderInfo_getDataSpace; # introduced=30 AndroidBitmap_getInfo; AndroidBitmap_getDataSpace; AndroidBitmap_lockPixels; Loading Loading
libs/hwui/hwui/ImageDecoder.cpp +9 −4 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ ImageDecoder::ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChu , mDecodeSize(mTargetSize) , mOutColorType(mCodec->computeOutputColorType(kN32_SkColorType)) , mUnpremultipliedRequired(false) , mOutColorSpace(mCodec->getInfo().refColorSpace()) , mOutColorSpace(mCodec->computeOutputColorSpace(mOutColorType, nullptr)) , mSampleSize(1) { } Loading Loading @@ -111,7 +111,6 @@ bool ImageDecoder::setOutColorType(SkColorType colorType) { if (!gray()) { return false; } mOutColorSpace = nullptr; break; case kN32_SkColorType: break; Loading @@ -137,9 +136,15 @@ void ImageDecoder::setOutColorSpace(sk_sp<SkColorSpace> colorSpace) { mOutColorSpace = std::move(colorSpace); } sk_sp<SkColorSpace> ImageDecoder::getOutputColorSpace() const { // kGray_8 is used for ALPHA_8, which ignores the color space. return mOutColorType == kGray_8_SkColorType ? nullptr : mOutColorSpace; } SkImageInfo ImageDecoder::getOutputInfo() const { SkISize size = mCropRect ? mCropRect->size() : mTargetSize; return SkImageInfo::Make(size, mOutColorType, getOutAlphaType(), mOutColorSpace); return SkImageInfo::Make(size, mOutColorType, getOutAlphaType(), getOutputColorSpace()); } bool ImageDecoder::opaque() const { Loading @@ -154,7 +159,7 @@ SkCodec::Result ImageDecoder::decode(void* pixels, size_t rowBytes) { void* decodePixels = pixels; size_t decodeRowBytes = rowBytes; auto decodeInfo = SkImageInfo::Make(mDecodeSize, mOutColorType, getOutAlphaType(), mOutColorSpace); getOutputColorSpace()); // Used if we need a temporary before scaling or subsetting. // FIXME: Use scanline decoding on only a couple lines to save memory. b/70709380. SkBitmap tmp; Loading
libs/hwui/hwui/ImageDecoder.h +1 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ private: ImageDecoder& operator=(const ImageDecoder&) = delete; SkAlphaType getOutAlphaType() const; sk_sp<SkColorSpace> getOutputColorSpace() const; }; } // namespace android
native/graphics/jni/imagedecoder.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ #include <android/asset_manager.h> #include <android/bitmap.h> #include <android/data_space.h> #include <android/imagedecoder.h> #include <android/graphics/MimeType.h> #include <android/rect.h> #include <hwui/ImageDecoder.h> #include <log/log.h> #include <SkAndroidCodec.h> #include <utils/Color.h> #include <fcntl.h> #include <optional> Loading Loading @@ -165,6 +167,18 @@ int AImageDecoder_setAndroidBitmapFormat(AImageDecoder* decoder, int32_t format) ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION; } int AImageDecoder_setDataSpace(AImageDecoder* decoder, int32_t dataspace) { sk_sp<SkColorSpace> cs = uirenderer::DataSpaceToColorSpace((android_dataspace)dataspace); // 0 is ADATASPACE_UNKNOWN. We need an explicit request for an ADataSpace. if (!decoder || !dataspace || !cs) { return ANDROID_IMAGE_DECODER_BAD_PARAMETER; } ImageDecoder* imageDecoder = toDecoder(decoder); imageDecoder->setOutColorSpace(std::move(cs)); return ANDROID_IMAGE_DECODER_SUCCESS; } const AImageDecoderHeaderInfo* AImageDecoder_getHeaderInfo(const AImageDecoder* decoder) { return reinterpret_cast<const AImageDecoderHeaderInfo*>(decoder); } Loading Loading @@ -201,6 +215,20 @@ bool AImageDecoderHeaderInfo_isAnimated(const AImageDecoderHeaderInfo* info) { return toDecoder(info)->mCodec->codec()->getFrameCount() > 1; } int32_t AImageDecoderHeaderInfo_getDataSpace(const AImageDecoderHeaderInfo* info) { if (!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, // 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); return uirenderer::ColorSpaceToADataSpace(colorSpace.get(), colorType); } // FIXME: Share with getFormat in android_bitmap.cpp? static AndroidBitmapFormat getFormat(SkColorType colorType) { switch (colorType) { Loading
native/graphics/jni/libjnigraphics.map.txt +2 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ LIBJNIGRAPHICS { AImageDecoder_delete; # introduced=30 AImageDecoder_setAndroidBitmapFormat; # introduced=30 AImageDecoder_setUnpremultipliedRequired; # introduced=30 AImageDecoder_setDataSpace; # introduced=30 AImageDecoder_getHeaderInfo; # introduced=30 AImageDecoder_getMinimumStride; # introduced=30 AImageDecoder_decodeImage; # introduced=30 Loading @@ -18,6 +19,7 @@ LIBJNIGRAPHICS { AImageDecoderHeaderInfo_getAlphaFlags; # introduced=30 AImageDecoderHeaderInfo_isAnimated; # introduced=30 AImageDecoderHeaderInfo_getAndroidBitmapFormat; # introduced=30 AImageDecoderHeaderInfo_getDataSpace; # introduced=30 AndroidBitmap_getInfo; AndroidBitmap_getDataSpace; AndroidBitmap_lockPixels; Loading