On Fri, 3 Jul 2020 at 12:16, <jcupitt@gmail.com> wrote:
> Thank you for libnsgif. I think I might have come across a gif that
> fails to render correctly in libnsgif-0.2.1:
>
> https://user-images.githubusercontent.com/580843/86457777-18bd1400-bd1c-11ea-923a-adeed2eba031.gif
>
> Frame 6 is DISPOSE_PREVIOUS and should unpaint the tips of the wings.
> libnsgif does not seem to handle this though, and the tips are left
> behind.
Hello again, I spent a little time looking at the code.
tldr: I think GIFs which have a COMBINE frame followed by a RESTORE
frame will not render correctly in libnsgif.
1. The frames in this GIF (except for frame 5) have disposal_method 1,
GIF_FRAME_COMBINE, ie. the frame is not cleared and pixels accumulate.
2. Frame 5 is GIF_FRAME_RESTORE, meaning that after frame 5 is
rendered, the frame should be restored to frame 4. This is detected
when frame 6 rendering starts here:
https://source.netsurf-browser.org/libnsgif.git/tree/src/libnsgif.c#n794
And it calls gif_internal_decode_frame() recursively to put the pixels
for frame 4 back.
3. However, because frame 4 is GIF_FRAME_COMBINE, the frame 4 pixels
are incorrectly painted on top of frame 5.
4. gif_internal_decode_frame() then decode the pixels for frame 6, but
because frame 4 has not been restored, the wingtips are left behind.
The problem is that with GIF_FRAME_COMBINE, the state of a GIF frame
depends on all the previous frames. You can't just call
gif_internal_decode_frame() to put the pixels back --- you need to
re-render the entire animation.
It seems to me that the best way to implement GIF_FRAME_RESTORE is to
have an extra bitmap in the gif struct to hold the restore pixels.
When processing a frame with GIF_FRAME_RESTORE set, a copy should be
made of the frame before painting in the new pixels. When processing a
frame whose /previous/ frame is GIF_FRAME_RESTORE, the frame should be
initialised from the previous bitmap.
Does this sound reasonable? I could try to make a patch if there's interest.
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