diff options
author | Leon Scroggins <scroggo@google.com> | 2021-01-08 17:08:27 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-01-08 17:08:27 +0000 |
commit | 14c70a7793128e3c588a53eb233bb4845d4d196b (patch) | |
tree | a8168a5203d665bedb68e5e4393ac07e66524e10 /native/graphics | |
parent | 9b07789714e79792a944f74dfb6a6f43cd257bdb (diff) | |
parent | 0621313fe65f78359f5c3b604b324fb2fd8dba07 (diff) |
Merge changes from topics "FrameInfo", "_advanceFrame"
* changes:
Implement FrameInfo methods on AImageDecoder
Implement AImageDecoder _advanceFrame and _rewind
Diffstat (limited to 'native/graphics')
-rw-r--r-- | native/graphics/jni/imagedecoder.cpp | 145 | ||||
-rw-r--r-- | native/graphics/jni/libjnigraphics.map.txt | 10 |
2 files changed, 150 insertions, 5 deletions
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp index 4aeebe47f1ae..e3b575e066d6 100644 --- a/native/graphics/jni/imagedecoder.cpp +++ b/native/graphics/jni/imagedecoder.cpp @@ -173,7 +173,13 @@ int AImageDecoder_setAndroidBitmapFormat(AImageDecoder* decoder, int32_t format) || format > ANDROID_BITMAP_FORMAT_RGBA_F16) { return ANDROID_IMAGE_DECODER_BAD_PARAMETER; } - return toDecoder(decoder)->setOutColorType(getColorType((AndroidBitmapFormat) format)) + + auto* imageDecoder = toDecoder(decoder); + if (imageDecoder->currentFrame() != 0) { + return ANDROID_IMAGE_DECODER_INVALID_STATE; + } + + return imageDecoder->setOutColorType(getColorType((AndroidBitmapFormat) format)) ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION; } @@ -185,6 +191,10 @@ int AImageDecoder_setDataSpace(AImageDecoder* decoder, int32_t dataspace) { } ImageDecoder* imageDecoder = toDecoder(decoder); + if (imageDecoder->currentFrame() != 0) { + return ANDROID_IMAGE_DECODER_INVALID_STATE; + } + imageDecoder->setOutColorSpace(std::move(cs)); return ANDROID_IMAGE_DECODER_SUCCESS; } @@ -279,7 +289,12 @@ int AImageDecoder_setUnpremultipliedRequired(AImageDecoder* decoder, bool requir return ANDROID_IMAGE_DECODER_BAD_PARAMETER; } - return toDecoder(decoder)->setUnpremultipliedRequired(required) + auto* imageDecoder = toDecoder(decoder); + if (imageDecoder->currentFrame() != 0) { + return ANDROID_IMAGE_DECODER_INVALID_STATE; + } + + return imageDecoder->setUnpremultipliedRequired(required) ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION; } @@ -288,7 +303,12 @@ int AImageDecoder_setTargetSize(AImageDecoder* decoder, int32_t width, int32_t h return ANDROID_IMAGE_DECODER_BAD_PARAMETER; } - return toDecoder(decoder)->setTargetSize(width, height) + auto* imageDecoder = toDecoder(decoder); + if (imageDecoder->currentFrame() != 0) { + return ANDROID_IMAGE_DECODER_INVALID_STATE; + } + + return imageDecoder->setTargetSize(width, height) ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_SCALE; } @@ -309,10 +329,15 @@ int AImageDecoder_setCrop(AImageDecoder* decoder, ARect crop) { return ANDROID_IMAGE_DECODER_BAD_PARAMETER; } + auto* imageDecoder = toDecoder(decoder); + if (imageDecoder->currentFrame() != 0) { + return ANDROID_IMAGE_DECODER_INVALID_STATE; + } + SkIRect cropIRect; cropIRect.setLTRB(crop.left, crop.top, crop.right, crop.bottom); SkIRect* cropPtr = cropIRect == SkIRect::MakeEmpty() ? nullptr : &cropIRect; - return toDecoder(decoder)->setCropRect(cropPtr) + return imageDecoder->setCropRect(cropPtr) ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_BAD_PARAMETER; } @@ -341,6 +366,10 @@ int AImageDecoder_decodeImage(AImageDecoder* decoder, return ANDROID_IMAGE_DECODER_BAD_PARAMETER; } + if (imageDecoder->finished()) { + return ANDROID_IMAGE_DECODER_FINISHED; + } + return ResultToErrorCode(imageDecoder->decode(pixels, stride)); } @@ -352,7 +381,7 @@ bool AImageDecoder_isAnimated(AImageDecoder* decoder) { if (!decoder) return false; ImageDecoder* imageDecoder = toDecoder(decoder); - return imageDecoder->mCodec->codec()->getFrameCount() > 1; + return imageDecoder->isAnimated(); } int32_t AImageDecoder_getRepeatCount(AImageDecoder* decoder) { @@ -369,3 +398,109 @@ int32_t AImageDecoder_getRepeatCount(AImageDecoder* decoder) { } return count; } + +int AImageDecoder_advanceFrame(AImageDecoder* decoder) { + if (!decoder) return ANDROID_IMAGE_DECODER_BAD_PARAMETER; + + ImageDecoder* imageDecoder = toDecoder(decoder); + if (!imageDecoder->isAnimated()) { + return ANDROID_IMAGE_DECODER_BAD_PARAMETER; + } + + if (imageDecoder->advanceFrame()) { + return ANDROID_IMAGE_DECODER_SUCCESS; + } + + if (imageDecoder->finished()) { + return ANDROID_IMAGE_DECODER_FINISHED; + } + + return ANDROID_IMAGE_DECODER_INCOMPLETE; +} + +int AImageDecoder_rewind(AImageDecoder* decoder) { + if (!decoder) return ANDROID_IMAGE_DECODER_BAD_PARAMETER; + + ImageDecoder* imageDecoder = toDecoder(decoder); + if (!imageDecoder->isAnimated()) { + return ANDROID_IMAGE_DECODER_BAD_PARAMETER; + } + + return imageDecoder->rewind() ? ANDROID_IMAGE_DECODER_SUCCESS + : ANDROID_IMAGE_DECODER_SEEK_ERROR; +} + +AImageDecoderFrameInfo* AImageDecoderFrameInfo_create() { + return reinterpret_cast<AImageDecoderFrameInfo*>(new SkCodec::FrameInfo); +} + +static SkCodec::FrameInfo* toFrameInfo(AImageDecoderFrameInfo* info) { + return reinterpret_cast<SkCodec::FrameInfo*>(info); +} + +static const SkCodec::FrameInfo* toFrameInfo(const AImageDecoderFrameInfo* info) { + return reinterpret_cast<const SkCodec::FrameInfo*>(info); +} + +void AImageDecoderFrameInfo_delete(AImageDecoderFrameInfo* info) { + delete toFrameInfo(info); +} + +int AImageDecoder_getFrameInfo(AImageDecoder* decoder, + AImageDecoderFrameInfo* info) { + if (!decoder || !info) { + return ANDROID_IMAGE_DECODER_BAD_PARAMETER; + } + + auto* imageDecoder = toDecoder(decoder); + if (imageDecoder->finished()) { + return ANDROID_IMAGE_DECODER_FINISHED; + } + + *toFrameInfo(info) = imageDecoder->getCurrentFrameInfo(); + return ANDROID_IMAGE_DECODER_SUCCESS; +} + +int64_t AImageDecoderFrameInfo_getDuration(const AImageDecoderFrameInfo* info) { + if (!info) return 0; + + return toFrameInfo(info)->fDuration * 1'000'000; +} + +ARect AImageDecoderFrameInfo_getFrameRect(const AImageDecoderFrameInfo* info) { + if (!info) { + return { 0, 0, 0, 0}; + } + + const SkIRect& r = toFrameInfo(info)->fFrameRect; + return { r.left(), r.top(), r.right(), r.bottom() }; +} + +bool AImageDecoderFrameInfo_hasAlphaWithinBounds(const AImageDecoderFrameInfo* info) { + if (!info) return false; + + return toFrameInfo(info)->fHasAlphaWithinBounds; +} + +int32_t AImageDecoderFrameInfo_getDisposeOp(const AImageDecoderFrameInfo* info) { + if (!info) return ANDROID_IMAGE_DECODER_BAD_PARAMETER; + + static_assert(static_cast<int>(SkCodecAnimation::DisposalMethod::kKeep) + == ANDROID_IMAGE_DECODER_DISPOSE_OP_NONE); + static_assert(static_cast<int>(SkCodecAnimation::DisposalMethod::kRestoreBGColor) + == ANDROID_IMAGE_DECODER_DISPOSE_OP_BACKGROUND); + static_assert(static_cast<int>(SkCodecAnimation::DisposalMethod::kRestorePrevious) + == ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS); + return static_cast<int>(toFrameInfo(info)->fDisposalMethod); +} + +int32_t AImageDecoderFrameInfo_getBlendOp(const AImageDecoderFrameInfo* info) { + if (!info) return ANDROID_IMAGE_DECODER_BAD_PARAMETER; + + switch (toFrameInfo(info)->fBlend) { + case SkCodecAnimation::Blend::kSrc: + return ANDROID_IMAGE_DECODER_BLEND_OP_SRC; + case SkCodecAnimation::Blend::kSrcOver: + return ANDROID_IMAGE_DECODER_BLEND_OP_SRC_OVER; + } +} diff --git a/native/graphics/jni/libjnigraphics.map.txt b/native/graphics/jni/libjnigraphics.map.txt index a184ab9d42e9..c8f115178e23 100644 --- a/native/graphics/jni/libjnigraphics.map.txt +++ b/native/graphics/jni/libjnigraphics.map.txt @@ -15,12 +15,22 @@ LIBJNIGRAPHICS { AImageDecoder_setCrop; # introduced=30 AImageDecoder_isAnimated; # introduced=31 AImageDecoder_getRepeatCount; # introduced=31 + AImageDecoder_advanceFrame; # introduced=31 + AImageDecoder_rewind; # introduced=31 + AImageDecoder_getFrameInfo; # introduced = 31 AImageDecoderHeaderInfo_getWidth; # introduced=30 AImageDecoderHeaderInfo_getHeight; # introduced=30 AImageDecoderHeaderInfo_getMimeType; # introduced=30 AImageDecoderHeaderInfo_getAlphaFlags; # introduced=30 AImageDecoderHeaderInfo_getAndroidBitmapFormat; # introduced=30 AImageDecoderHeaderInfo_getDataSpace; # introduced=30 + AImageDecoderFrameInfo_create; # introduced = 31 + AImageDecoderFrameInfo_delete; # introduced = 31 + AImageDecoderFrameInfo_getDuration; # introduced = 31 + AImageDecoderFrameInfo_getFrameRect; # introduced = 31 + AImageDecoderFrameInfo_hasAlphaWithinBounds; # introduced = 31 + AImageDecoderFrameInfo_getDisposeOp; # introduced = 31 + AImageDecoderFrameInfo_getBlendOp; # introduced = 31 AndroidBitmap_getInfo; AndroidBitmap_getDataSpace; AndroidBitmap_lockPixels; |