Open tgyuuAn opened 2 weeks ago
@tgyuuAn Thank you for taking the time to write this! That said, I think this can be implemented without a custom GIF parser. The AnimatedImageDrawable
docs mention that by default the repeat count in the encoded data is respected. As such I think all we need to do to support using the encoded repeat count is to not call animatedDrawable.repeatCount =
if options.repeatCount == GIF_LOOP_COUNT
. Also I would rename GIF_LOOP_COUNT
to ENCODED_REPEAT_COUNT
to indicate it's encoded in the data.
For GifDecoder
I don't think we can support repeatCount
without reading the data, but we can just mark ENCODED_REPEAT_COUNT
as API >= 28. I'd prefer to avoid adding custom GIF parsing code since it would only be used on older devices and it could be tough to maintain long term.
@tgyuuAn Thank you for taking the time to write this! That said, I think this can be implemented without a custom GIF parser. The
AnimatedImageDrawable
docs mention that by default the repeat count in the encoded data is respected. As such I think all we need to do to support using the encoded repeat count is to not callanimatedDrawable.repeatCount =
ifoptions.repeatCount == GIF_LOOP_COUNT
. Also I would renameGIF_LOOP_COUNT
toENCODED_REPEAT_COUNT
to indicate it's encoded in the data.For
GifDecoder
I don't think we can supportrepeatCount
without reading the data, but we can just markENCODED_REPEAT_COUNT
as API >= 28. I'd prefer to avoid adding custom GIF parsing code since it would only be used on older devices and it could be tough to maintain long term.
I feel a weight lifted off my shoulders !!!!!!!
@colinrtwhite
If it is over 28, there is an exception that causes infinite repetition if you use GifDecoder.
@tgyuuAn You need to run ./gradlew spotlessApply
to fix the style check.
@tgyuuAn Thanks for implementing this - no more changes needed! I'll merge this once we're done with 3.0.x
bug fix releases and include it in the 3.1.0
release.
Key Changes
You can use this feature in your code as follows:
Parsing Logic for GIF
During the GIF parsing process, we utilized
source.peek()
to read the data again. This was necessary because the loop count needs to be accessed without consuming the originalBufferedSource
, ensuring that we can still read the data needed for further processing. Unfortunately, this reliance onpeek()
is a limitation and feels like a workaround in the parsing logic.Handling Loop Count in AnimatedImageDecoder
In the
AnimatedImageDecoder
, the logic that applies the loop count is separate from the logic that consumes theImageSource
. Because of this separation, thewrapDrawable
function now includes an additional parameter,loopCount
. This design choice was unavoidable, as adding a setter toOptions.repeatCount
would not have sufficed for properly applying the loop count without compromising the integrity of the original image data.If you have a better opinion, please tell me, and I will reflect it.
GIF Format Overview
The Graphics Interchange Format (GIF) consists of a structured file format that is primarily used for graphics and animations. Here’s a breakdown of its structure and the significance of the Application Extension block, particularly regarding the parsing of the loop count.
GIF Structure in Bytes
Header (6 bytes):
GIF87a
(6 bytes)GIF89a
(6 bytes) <--- Loop Count exists only in this format.Logical Screen Descriptor (7 bytes):
Global Color Table (if present):
Image Descriptor (10 bytes):
Image Data:
Extension Blocks:
Application Extension Block
The Application Extension Block is crucial for animated GIFs as it defines the animation properties, including the loop count. The structure of the Application Extension Block is as follows:
0x21
to indicate an extension block.0xFF
for application extension.0x0B
for 11 bytes).0x03
for three bytes).0x01
, indicating the presence of loop count data.0
indicates infinite looping.0x00
to indicate the end of the extension.In our parsing logic, we focus on the Application Extension to extract the loop count, which is critical for controlling the animation behavior of the GIF.
For further reading, check out:
If I need to write test code, please let me know where I can write it.
@colinrtwhite