Sunday, 7 March 2021

possible bug: libnsgif does not handle successive RESTORE frames correctly

Hello again everyone,

I think I have a GIF which libnsgif does not handle correctly:

https://github.com/libvips/libvips/blob/master/test/test-suite/images/dispose-previous.gif

This GIF has three frames which draw three concentric red circles. The
GIF does this:

- clear frame
frame 0:
- disposal_method COMBINE
- draw outermost red circle
frame 1:
- disposal_method RESTORE
- draw middle red circle
frame 2:
- disposal_method RESTORE
- draw inner red circle

So the viewer should see this:

https://github.com/libvips/libvips/blob/master/test/test-suite/images/dispose-previous.png

frame 0:
- outer circle
frame 1:
- outer + middle
frame 2:
- outer + inner

However, if you view with libnsgif, you'll see frame 2 has all three
circles, ie. the middle frame is not removed.

Looking at the code, the problem seems to be that
gif_internal_decode_frame() calls gif__record_previous_frame() before
it calls gif__recover_previous_frame(). This means that if you have
two frames with RESTORE dispose in a row, the second restore will be
missed, since it will save the frame (overwriting the restore) before
it tries to restore it.

The simplest fix is probably to simply move the record handler to just
after the recover. I think this makes intuitive sense -- you want to
finish disposing of the previous frame before you record the current
state.

John
_______________________________________________
netsurf-dev mailing list -- netsurf-dev@netsurf-browser.org
To unsubscribe send an email to netsurf-dev-leave@netsurf-browser.org

No comments:

Post a Comment