Skip to content

Instantly share code, notes, and snippets.

@SoniEx2
Last active August 19, 2016 17:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SoniEx2/34472e8e6ba3a9e900336235f805d5a6 to your computer and use it in GitHub Desktop.
Save SoniEx2/34472e8e6ba3a9e900336235f805d5a6 to your computer and use it in GitHub Desktop.
APNG Sucks!

APNG Sucks!

Hi! Let's talk about APNG! Note that I'm biased because I made my own animated PNG extension and it also sucks.

Problems with APNG

So, APNG has the following issues:

  • It has no good support for spritesheets.
  • It really doesn't play nice with Adam7. Adam7 is useless for APNG.

First I'll talk about the part that most interests me.

Adam7 and APNG

The way APNG is specified makes Adam7 useless. This could be fixed by changing some requirements of the APNG spec, such as "sequence order".

The APNG fdAT chunk looks like this:

    byte
    0    sequence_number       (unsigned int)   Sequence number of the animation chunk, starting from 0
    4    frame_data            X bytes          Frame data for this frame

And the sequence number MUST be one greater than the previous chunk's sequence number. This is stupid if you compare it to some other animation formats.

If one changes the APNG requirements such that:

  1. The fdAT chunk is defined as follows:

         byte
         0    sequence_number       (unsigned int)   Sequence number of the animation chunkset, starting from 0
         0    part_number           (unsigned int)   Sequence number of the data chunk, starting from 0
         8    frame_data            X bytes          Frame data for this frame
    
  2. A fdAT chunk with smaller sequence number may appear after an fdAT chunk with larger sequence number.

  3. A IDAT chunk may appear after any fdAT and fcTL chunks.

Then it becomes possible to truncate APNG files without breaking the animation. This truncation, combined with Adam7 interlacing, lets you do as follows:

  1. Adam7 is a 7-step algorithm. So we split each frame on every step.
  2. Put each step of Adam7 in a separate chunk.
  3. Order those chunks such that the first step's chunks come first, then the 2nd step's, then the 3rd's and so on.

That is, if you have 3 frames, you grab the first Adam7 pixels of each frame, and build such an APNG as follows:

[IHDR][acTL][fcTL][IDAT][fcTL][fdAT][fcTL][fdAT]...

Then you append the second Adam7 pixels of each frame:

[IDAT][fdAT][fdAT]...

And repeat that until the last pass/subimage of Adam7.

With the current APNG spec, it is possible to generate truncatable APNGs, but they can only be parsed by APNG-aware editors, as per the following line on the APNG spec:

Decoders must treat out-of-order APNG chunks as an error. APNG-aware PNG editors should restore them to correct order using the sequence numbers.

Note that only FLIF supports truncation. Also note that this is a relatively trivial change.

APNG and spritesheets

I don't know any games that use APNG spritesheets (I do know some games that use individual APNG files however), but APNG has the issue that you can't divide the spritesheet into individual animations.

Unlike MNG, APNG only supports whole-image updates. If you have a part that loops every 3 seconds and another that loops every 5 seconds, you need a 15-second long animation for a perfect loop. With formats such as MNG, you can split the 3-second animation and the 5-second animation and the decoder handles the 15-second loop for you.

Spritesheet support would make APNG significantly more complex; however, someone smarter than me might be able to come up with a simple way to do it.

Conclusion

APNG sucks! GIF sucks! MNG sucks! WebP sucks! Still waiting for that FLIF thing but I doubt it's ever going to get released.

References

APNG spec: https://wiki.mozilla.org/APNG_Specification

Adam7: https://en.wikipedia.org/wiki/Adam7_algorithm

MNG spec: http://www.libpng.org/pub/mng/spec/mng-1.0-20010209-pdg.html

FLIF animation: http://flif.info/animation.html

WebP spec (animation part): https://developers.google.com/speed/webp/docs/riff_container#animation

License

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment