diff options
Diffstat (limited to 'native/graphics/jni/imagedecoder.cpp')
-rw-r--r-- | native/graphics/jni/imagedecoder.cpp | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp index 2ef203dd466f..1c45ea6aaecc 100644 --- a/native/graphics/jni/imagedecoder.cpp +++ b/native/graphics/jni/imagedecoder.cpp @@ -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> @@ -131,6 +133,10 @@ static ImageDecoder* toDecoder(AImageDecoder* d) { return reinterpret_cast<ImageDecoder*>(d); } +static const ImageDecoder* toDecoder(const AImageDecoder* d) { + return reinterpret_cast<const ImageDecoder*>(d); +} + // Note: This differs from the version in android_bitmap.cpp in that this // version returns kGray_8_SkColorType for ANDROID_BITMAP_FORMAT_A_8. SkCodec // allows decoding single channel images to gray, which Android then treats @@ -161,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); } @@ -197,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) { @@ -225,13 +257,12 @@ AndroidBitmapFormat AImageDecoderHeaderInfo_getAndroidBitmapFormat( int AImageDecoderHeaderInfo_getAlphaFlags(const AImageDecoderHeaderInfo* info) { if (!info) { - // FIXME: Better invalid? - return -1; + return ANDROID_IMAGE_DECODER_BAD_PARAMETER; } switch (toDecoder(info)->mCodec->getInfo().alphaType()) { case kUnknown_SkAlphaType: LOG_ALWAYS_FATAL("Invalid alpha type"); - return -1; + return ANDROID_IMAGE_DECODER_INTERNAL_ERROR; case kUnpremul_SkAlphaType: // fall through. premul is the default. case kPremul_SkAlphaType: @@ -241,26 +272,12 @@ int AImageDecoderHeaderInfo_getAlphaFlags(const AImageDecoderHeaderInfo* info) { } } -SkAlphaType toAlphaType(int androidBitmapFlags) { - switch (androidBitmapFlags) { - 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) { +int AImageDecoder_setUnpremultipliedRequired(AImageDecoder* decoder, bool required) { + if (!decoder) { 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; } @@ -273,6 +290,18 @@ int AImageDecoder_setTargetSize(AImageDecoder* decoder, int width, int height) { ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_SCALE; } +int AImageDecoder_computeSampledSize(const AImageDecoder* decoder, int sampleSize, + int* width, int* height) { + if (!decoder || !width || !height || sampleSize < 1) { + return ANDROID_IMAGE_DECODER_BAD_PARAMETER; + } + + SkISize size = toDecoder(decoder)->mCodec->getSampledDimensions(sampleSize); + *width = size.width(); + *height = size.height(); + return ANDROID_IMAGE_DECODER_SUCCESS; +} + int AImageDecoder_setCrop(AImageDecoder* decoder, ARect crop) { if (!decoder) { return ANDROID_IMAGE_DECODER_BAD_PARAMETER; |