Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions lottie/src/main/java/org/thorvg/lottie/LottieDrawable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ class LottieDrawable internal constructor() : Drawable(), Animatable {
* @return The length of the animation, in milliseconds.
*/
val duration: Long
get() = if (lottieState.valid()) lottieState.lottie.duration else 0L
get() = if (lottieState.valid()) lottieState.lottie?.duration ?: 0L else 0L

var speed: Float
@FloatRange(from = 0.0)
Expand Down Expand Up @@ -300,8 +300,7 @@ class LottieDrawable internal constructor() : Drawable(), Animatable {
require(rawRes != 0) { "" }

state.lottie = Lottie(loadJSONFile(r, rawRes))

setLastFrame(a.getInt(R.styleable.LottieDrawable_frameTo, state.lottie.frameCount))
state.lottie?.let { lottie -> setLastFrame(a.getInt(R.styleable.LottieDrawable_frameTo, lottie.frameCount)) }
setFirstFrame(a.getInt(R.styleable.LottieDrawable_frameFrom, 0))
this@LottieDrawable.speed = a.getFloat(R.styleable.LottieDrawable_speed, 1f)

Expand All @@ -327,7 +326,7 @@ class LottieDrawable internal constructor() : Drawable(), Animatable {
}

internal class LottieDrawableState : ConstantState {
lateinit var lottie: Lottie
var lottie: Lottie? = null

var mBaseWidth = 0f
var baseHeight = 0f
Expand Down Expand Up @@ -361,8 +360,10 @@ class LottieDrawable internal constructor() : Drawable(), Animatable {
}
var lastFrame = 0
set(value) {
field = value.coerceAtMost(lottie.frameCount)
updateFrameInterval()
lottie?.apply {
field = value.coerceAtMost(frameCount)
updateFrameInterval()
}
}

var frameInterval = 0L
Expand All @@ -376,8 +377,8 @@ class LottieDrawable internal constructor() : Drawable(), Animatable {
constructor()

constructor(copy: LottieDrawableState?) {
if (copy != null) {
lottie = Lottie(copy.lottie)
copy?.lottie?.let { lottie ->
this@LottieDrawableState.lottie = Lottie(lottie)
mBaseWidth = copy.mBaseWidth
baseHeight = copy.baseHeight
repeatCount = copy.repeatCount
Expand All @@ -390,28 +391,31 @@ class LottieDrawable internal constructor() : Drawable(), Animatable {
}

fun releaseLottie() {
lottie.destroy()
lottie?.destroy()
lottie = null
}

fun valid(): Boolean {
return ::lottie.isInitialized && lottie.nativePtr != 0L
return lottie?.nativePtr != 0L
}

fun setLottieSize(width: Int, height: Int) {
if (width != this@LottieDrawableState.width || height != this@LottieDrawableState.height) {
this@LottieDrawableState.width = width
this@LottieDrawableState.height = height
lottie.setBufferSize(width, height)
lottie?.setBufferSize(width, height)
}
}

fun getLottieBuffer(frame: Int): Bitmap? {
return lottie.getBuffer(frame)
return lottie?.getBuffer(frame)
}

private fun updateFrameInterval() {
val frameCount = lastFrame - firstFrame
frameInterval = (lottie.duration / frameCount / speed).toLong()
lottie?.let {
val frameCount = lastFrame - firstFrame
frameInterval = (it.duration / frameCount / speed).toLong()
}
}

override fun newDrawable(): Drawable {
Expand Down Expand Up @@ -566,7 +570,11 @@ class LottieDrawable internal constructor() : Drawable(), Animatable {
}

@JvmStatic
private external fun nCreateLottie(content: String, length: Int, outValues: IntArray): Long
private external fun nCreateLottie(
content: String?,
length: Int,
outValues: IntArray?
): Long

Copy link
Collaborator

@ol-of ol-of Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since content and outValues are nullable, the current implementation of
Java_org_thorvg_lottie_LottieDrawable_nCreateLottie in lottie-libs.cpp can crash because it does not perform any null checks.

Please add null-safety checks to Java_org_thorvg_lottie_LottieDrawable_nCreateLottie, for example:

extern "C" jlong
Java_org_thorvg_lottie_LottieDrawable_nCreateLottie(JNIEnv *env, jclass clazz,
        jstring content, jint length, jintArray out_values) {
    if (content == nullptr || inputStr == nullptr) {
        return 0;
    }
   ...
}

@JvmStatic
private external fun nSetLottieBufferSize(
Expand Down