diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp index 23035b69af903..ac4c16a4199bb 100644 --- a/native/graphics/jni/imagedecoder.cpp +++ b/native/graphics/jni/imagedecoder.cpp @@ -353,3 +353,18 @@ bool AImageDecoder_isAnimated(AImageDecoder* decoder) { ImageDecoder* imageDecoder = toDecoder(decoder); return imageDecoder->mCodec->codec()->getFrameCount() > 1; } + +int32_t AImageDecoder_getRepeatCount(AImageDecoder* decoder) { + if (!decoder) return ANDROID_IMAGE_DECODER_BAD_PARAMETER; + + ImageDecoder* imageDecoder = toDecoder(decoder); + const int count = imageDecoder->mCodec->codec()->getRepetitionCount(); + + // Skia should not report anything out of range, but defensively treat + // negative and too big as INFINITE. + if (count == SkCodec::kRepetitionCountInfinite || count < 0 + || count > std::numeric_limits::max()) { + return ANDROID_IMAGE_DECODER_INFINITE; + } + return count; +} diff --git a/native/graphics/jni/libjnigraphics.map.txt b/native/graphics/jni/libjnigraphics.map.txt index af2c455e36dff..a184ab9d42e95 100644 --- a/native/graphics/jni/libjnigraphics.map.txt +++ b/native/graphics/jni/libjnigraphics.map.txt @@ -14,6 +14,7 @@ LIBJNIGRAPHICS { AImageDecoder_computeSampledSize; # introduced=30 AImageDecoder_setCrop; # introduced=30 AImageDecoder_isAnimated; # introduced=31 + AImageDecoder_getRepeatCount; # introduced=31 AImageDecoderHeaderInfo_getWidth; # introduced=30 AImageDecoderHeaderInfo_getHeight; # introduced=30 AImageDecoderHeaderInfo_getMimeType; # introduced=30