summaryrefslogtreecommitdiff
path: root/native/graphics/jni/imagedecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'native/graphics/jni/imagedecoder.cpp')
-rw-r--r--native/graphics/jni/imagedecoder.cpp69
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;