Bug 15974

Summary: Public GIF image decoder does not handle disposal of previous frames correctly
Product: WebKit Reporter: Peter Kasting <pkasting>
Component: ImagesAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: alp
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: All   
Attachments:
Description Flags
Sample image relying on "not specified" disposal
none
Sample image (1) relying on "clear to previous"
none
Sample image (2) relying on "clear to previous"
none
patch v1
mrowe: review-
patch v2 alp: review+

Description Peter Kasting 2007-11-13 17:32:43 PST
GIFImageDecoder.cpp (not used by Safari, but used by the Cairo/Qt ports) does not correctly deal with disposal of previous frames in a multi-frame GIF.

GIFs can specify four disposal methods for a frame: "not specified", "keep", "clear to background color", and "clear to previous".  There are multiple issues:
* GIFImageReader doesn't provide the disposal method to GIFImageDecoder.cpp, just a flag indicating whether or not the method was "keep".  This makes it impossible to distinguish the two clear methods, and more noticeably, treats "not specified" like a clear method.  Mozilla, IE, and Safari, by contrast, treat "not specified" as "keep", and at least some GIFs on the web rely on this (example to be attached after filing).
* When clearing, the code in GIFImageDecoder.cpp:initFrameBuffer() reverts to the contents of frame 0, which is not the same as either of the clear methods in the spec.  By contrast, Mozilla treats both clear methods like "clear to background color".  I don't know what IE or Safari do or what actual images rely on.

I think the right fix here is to change RGBA32Buffer's "includeInNextFrame()" method (which is only used by the GIF decoder) to instead return an actual disposal method, have GIFImageReader provide the true disposal method, and then fix initFrameBuffer() to respect this method.  I don't know whether "clear to previous" should be treated like "clear to background color" (as Mozilla does) or made to follow the GIF spec.  Input welcome.
Comment 1 Peter Kasting 2007-11-13 17:34:26 PST
Created attachment 17247 [details]
Sample image relying on "not specified" disposal

This image never specifies a disposal method for any of its frames, and relies on that making each frame act like the disposal method was "keep".
Comment 2 Peter Kasting 2007-11-13 17:45:55 PST
Created attachment 17249 [details]
Sample image (1) relying on "clear to previous"

Here's an image that I think relies on "clear to previous" behavior to work right.
Comment 3 Peter Kasting 2007-11-13 17:47:23 PST
Created attachment 17250 [details]
Sample image (2) relying on "clear to previous"

...and another.

Firefox, IE and Safari all display both these images fine.  I need to verify exactly what the clearing behavior in the files is, though.
Comment 4 Peter Kasting 2007-11-13 17:51:18 PST
I lied, I don't think Mozilla treats "clear to previous" as "clear to background color".  I was misinterpreting their code.  I think everybody else actually gets this right according to the spec.
Comment 5 Peter Kasting 2007-11-16 14:18:35 PST
Created attachment 17320 [details]
patch v1

This patch makes all the above attached images work correctly.  It also calls ensureHeight() in a more consistent way (we don't ensureHeight(m_size.height()) on some frames before decoding anything the way we did before) and calls setHasAlpha() correctly (although a bit conservatively -- we might claim to have alpha when we don't, but never the other way), which was trickier with the new initialization code.
Comment 6 Darin Adler 2007-11-16 20:18:01 PST
Comment on attachment 17320 [details]
patch v1

r=me
Comment 7 Mark Rowe (bdash) 2007-11-19 04:22:48 PST
Landed in r27896.
Comment 8 Mark Rowe (bdash) 2007-11-19 05:03:08 PST
I had to roll this out as it caused a bunch of build failures in the ports using this class.
Comment 9 Alp Toker 2007-11-23 15:00:33 PST
Peter,

If you need some help integrating your modified GIF API into other ports, please do ask and I'll be happy to take a look.
Comment 10 Peter Kasting 2007-11-24 22:53:05 PST
(In reply to comment #9)
> If you need some help integrating your modified GIF API into other ports,
> please do ask and I'll be happy to take a look.

If you have the ability to build various other ports, help would be very appreciated.  Feel free to post an updated patch.  Otherwise, I will try to get to writing patches that cover the other ports as well in the next few days (although I don't have the ability to build them to test).
Comment 11 Peter Kasting 2007-11-26 18:13:12 PST
Created attachment 17541 [details]
patch v2

This attempts to fix build bustage problems.
Comment 12 Alp Toker 2007-11-26 19:01:47 PST
Landed in r28068.