redwarp / gifdecoder

An implementation of a gif decoder written 100% in Kotlin, plus an associated Drawable for Android
Apache License 2.0
47 stars 6 forks source link

only one bitmap instance through the whole decode procedure #23

Closed vince-styling closed 1 year ago

vince-styling commented 1 year ago

the BitmapCache is good for preload next frame, but it allocating two more bitmaps in memory, for me, I turn to single bitmap, that means I can't benefit from the prepareNextFrame work, but it doesn't matter as I have some other adjustments make me discard your preload job.

below are the key code, omit some unimportant lines

class GifDrawable {
    private val frameBitmap = Bitmap.createBitmap(gifWidth, gifHeight, Bitmap.Config.ARGB_8888)

    fun renderNextFrame(): Long {
        val nextIndex = (++gifState.frameIndex) % gif.frameCount
        val result = gif.getFrame(nextIndex, frameBitmap)
        if (result.isSuccess) {
            frameBitmap.prepareToDraw()
            invalidateSelf()
        }
    }
}

class Gif {
    fun getFrame(index: Int, frameBitmap: Bitmap): Result<Any?> {
        while (currentIndex != index) {
            advance().onFailure { return Result.failure(it) }
        }
        return getCurrentFrame(frameBitmap)
    }

    private fun getCurrentFrame(frameBitmap: Bitmap): Result<Any?> {
        val width = frameBitmap.width
        frameBitmap.setPixels(framePixels, 0, width, 0, 0, width, frameBitmap.height)
        return Result.success(null)
    }
}
redwarp commented 1 year ago

The bitmap cache is probably something that should die indeed: I used to share bitmap cache between different gifs, but I don't think it's necessary. I should just swap between two gifs, current and next, especially now that I modified to only have ARGB_8888

redwarp commented 1 year ago

Decided that indeed, swaping with the pixel buffer only was sufficient. This reduces the memory usage of the GifDrawable, nice!