summaryrefslogtreecommitdiff
path: root/native/graphics
diff options
context:
space:
mode:
authorLeon Scroggins <scroggo@google.com>2021-01-08 17:08:27 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-01-08 17:08:27 +0000
commit14c70a7793128e3c588a53eb233bb4845d4d196b (patch)
treea8168a5203d665bedb68e5e4393ac07e66524e10 /native/graphics
parent9b07789714e79792a944f74dfb6a6f43cd257bdb (diff)
parent0621313fe65f78359f5c3b604b324fb2fd8dba07 (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.cpp145
-rw-r--r--native/graphics/jni/libjnigraphics.map.txt10
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;