Implement AImageDecoder dataspace methods
Bug: 135133301 Test: Iffe659e50078139188c3325545624640ae177cc2 Implement AImageDecoderHeaderInfo_getDataSpace, which reports the default ADataSpace to decode to. It may report ADATASPACE_UNKNOWN, which means that we've mostly left the colors in their original color profile. This matches android.graphics.ImageDecoder/BitmapFactory, which would use a ColorSpace named "Unknown". (It will standardize on DISPLAY_P3 for some profiles, which again matches the Java classes.) Implement AImageDecoder_setDataSpace, which allows specifying the ADataSpace to decode to. It only supports explicit ADataSpaces. Change-Id: Iba2f9e09531c23fae83ebe13cb9d18394ee3cd59
This commit is contained in:
@@ -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)
|
||||
{
|
||||
}
|
||||
@@ -111,7 +111,6 @@ bool ImageDecoder::setOutColorType(SkColorType colorType) {
|
||||
if (!gray()) {
|
||||
return false;
|
||||
}
|
||||
mOutColorSpace = nullptr;
|
||||
break;
|
||||
case kN32_SkColorType:
|
||||
break;
|
||||
@@ -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 {
|
||||
@@ -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;
|
||||
|
||||
@@ -66,6 +66,7 @@ private:
|
||||
ImageDecoder& operator=(const ImageDecoder&) = delete;
|
||||
|
||||
SkAlphaType getOutAlphaType() const;
|
||||
sk_sp<SkColorSpace> getOutputColorSpace() const;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -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>
|
||||
@@ -161,6 +163,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 +211,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) {
|
||||
|
||||
@@ -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
|
||||
@@ -17,6 +18,7 @@ LIBJNIGRAPHICS {
|
||||
AImageDecoderHeaderInfo_getAlphaFlags; # introduced=30
|
||||
AImageDecoderHeaderInfo_isAnimated; # introduced=30
|
||||
AImageDecoderHeaderInfo_getAndroidBitmapFormat; # introduced=30
|
||||
AImageDecoderHeaderInfo_getDataSpace; # introduced=30
|
||||
AndroidBitmap_getInfo;
|
||||
AndroidBitmap_getDataSpace;
|
||||
AndroidBitmap_lockPixels;
|
||||
|
||||
Reference in New Issue
Block a user