Implement FrameInfo methods on AImageDecoder
Bug: 160984428
Test: If47d475233f6b9973abf68029b63a610ff47cdae
- AImageDecoder_getFrameInfo
- AImageDecoderFrameInfo_create
- AImageDecoderFrameInfo_delete
- AImageDecoderFrameInfo_getDuration
- AImageDecoderFrameInfo_getFrameRect
- AImageDecoderFrameInfo_getDisposeOp
- AImageDecoderFrameInfo_getBlendOp
- AImageDecoderFrameInfo_hasAlphaWithinBounds
These allow querying for information specific to a single frame in an
encoded image.
Change-Id: I6ce5665e9c25aed23f99ce88290e520d68fcb60e
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp
index 971ba37..e3b575e 100644
--- a/native/graphics/jni/imagedecoder.cpp
+++ b/native/graphics/jni/imagedecoder.cpp
@@ -429,3 +429,78 @@
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 bd659e0..c8f1151 100644
--- a/native/graphics/jni/libjnigraphics.map.txt
+++ b/native/graphics/jni/libjnigraphics.map.txt
@@ -17,12 +17,20 @@
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;