Closed Bug 580182 Opened 14 years ago Closed 14 years ago

(animation) problem with dispose=previous

Categories

(Core :: Graphics: ImageLib, defect)

x86
Windows XP
defect
Not set
normal

Tracking

()

VERIFIED FIXED
mozilla2.0b7

People

(Reporter: newstop, Assigned: newstop)

Details

Attachments

(8 files, 2 obsolete files)

User-Agent:       Mozilla/5.0 (Windows; Windows NT 5.1; en-US; rv:2.0b2pre) Gecko/20100718 Minefield/4.0b2pre
Build Identifier: 

See the attached example: flags.gif 

It's structure:

1. show Blue (250x150), dispose = none
2. show "UK" (250x150), dispose = previous
3. show "EU" (128x128), dispose = none

dispose = previous means that after UK is shown, the image should go back to previous (Blue) frame, and then EU stars should appear on top of that Blue background.

But dispose = previous for some reason clears the background, turning it transparent. So EU stars appear on transparent background.

This GIF shouldn't have *any* transparency, because:
1. there is no transparent color.
2. there is no dispose = clear.

I tested it with many image viewers and browsers: they all show it correctly.
Only Firefox seems to have that problem. 
And it's not new, I went as far back as Firefox 2, the bug is there.
Also, it's not just that particular GIF, because when I converted it to 24-bit (no alpha) apng, the bug is still there.


Reproducible: Always
Attached image flags.gif example
I can confirm the behavior (though every single webkit-based browser I have here, plus Preview, all show the third frame on a _green_ background for some reason; that can't possibly be correct).

Bobby, any idea what's up here?
Status: UNCONFIRMED → NEW
Ever confirmed: true
Just took a quick look through this with gdb. It appears that it's doing the dispose=previous stuff correctly, but that for some reason the previous frame it restores is straight RGBA zeros (consistent with the behavior we're seeing). I'll figure out what that's about after I finish doing some reviews for joe.

Also, bz - are you sure you're seeing green on mac/Preview? I get a lighter blue...
> Also, bz - are you sure you're seeing green on mac/Preview?

Very sure, yes.  I'm on 10.5; that might matter.
I'm seeing the same things as Bobby. I think the very first frame is not stored in compositingFrame, because it's displayed "as is" instead (for optimization purposes).

Maybe right before this:
    CopyFrameImage(mAnim->compositingFrame, mAnim->compositingPrevFrame);
there needs to be a check for first frame...
Or maybe a check for mAnim->lastCompositedFrameIndex ...


P.S. I think the light blue is color #0 (rgb=56,83,153), maybe webkit simply fills the buffer with it before decoding.
Attached image a_example.png
Another example, but dispose=previous only clears the frame on 2nd loop. The 1st loop is displayed correctly. That makes me think the reason could be a little different, but I'm pretty sure it's located somewhere in imgContainer::DoComposite() too.

There are a number of optimizations in DoComposite(), and it seems that some of them are not 100% correct.
Investigating this is on my todo list, but it'll probably be a while unless this becomes a blocker. I'll expedite reviews on any patches though.
Attached patch proposed patch (obsolete) — Splinter Review
The patch has 3 parts:

1. Turns off "doDisposal = PR_FALSE" optimization if next frame has 
   dispose=previous.

   It corrects flags.gif problem, as doDisposal = PR_TRUE will cause 
   compositingFrame to contain "this frame after disposal op", as intended.
   It will be stored later in compositingPrevFrame and restored from it nicely.

2. Typo in NS_WARNING() 

3. Turns off aPrevFrame->SetFrameDisposalMethod(kDisposeClearAll) optimization
   if next frame has dispose=previous.

   It corrects a_example.png problem, as next loop will not be messed up 
   by that ClearAll optimization.
(In reply to comment #8)
> Created attachment 466982 [details] [diff] [review]
> proposed patch
> 
> The patch has 3 parts:
> 
> 1. Turns off "doDisposal = PR_FALSE" optimization if next frame has 
>    dispose=previous.
> 
>    It corrects flags.gif problem, as doDisposal = PR_TRUE will cause 
>    compositingFrame to contain "this frame after disposal op", as intended.
>    It will be stored later in compositingPrevFrame and restored from it nicely.
> 
> 2. Typo in NS_WARNING() 
> 
> 3. Turns off aPrevFrame->SetFrameDisposalMethod(kDisposeClearAll) optimization
>    if next frame has dispose=previous.
> 
>    It corrects a_example.png problem, as next loop will not be messed up 
>    by that ClearAll optimization.

This looks good to me, but Joe's the one who wrote this stuff. Joe, what do you think?
This looks great. I'd love to see some modifications to the comments above the code you're changing (right now it only says "transparency" and "8bit"), and we'll need a test for this too.
Attached patch proposed patch, v2 (obsolete) — Splinter Review
Added some comments to reflect the changes. 

Also fixed the comment I forgot to change in bug 433047.
Attachment #466982 - Attachment is obsolete: true
Joe, I think the first 2 attachments are good tests for both issues,
but let me know if you want to see then modified in some way...
Totally agreed - we just need them to be put into our automated tests. Best option is probably a reftest.
(In reply to comment #13)
> Totally agreed - we just need them to be put into our automated tests. Best
> option is probably a reftest.

More specifically, what we should do is modify the test cases so that they're as short as possible, so that the frame that visually differs is the last one, and so that it doesn't loop.

That way, we can write a simple delay test, where we let the animation run its course, and then compare what's left on the screen with what the final frame should look like.

See modules/libpr0n/test/reftest/apng/delaytest.html for an example of how this should work.
Attached image bug580182-1.gif
the same as flags.gif but much faster and with only 1 loop.
Attached image bug580182-2.png
the same as a_example.png but much faster and with only 2 loops.
I don't know how to write a reftest myself, but if someone else is willing to try, you can use these animations, which are basically the same as originals, but faster and they stop very soon. If the last frame has a transparent pixel(0,0), it's a bug. Hope that's enough.
Attachment #467096 - Flags: review?(joe)
If you can also post the reference images (ie, what the images _should_ end up looking like), I'll write the reftest.
Attached image bug580182-1-ref.gif
correct last frame, for reference
Attached image bug580182-2-ref.png
correct last frame, for reference
I see the reftest is currently using 100ms delay, but you might want to increase it to 300ms or so, to let the second test finish 2 loops.

Btw, I fixed another DoComposite() problem recently (see bug 433047), I can make a similar test for it too, if you think it would be useful.
Comment on attachment 467096 [details] [diff] [review]
proposed patch, v2

More details in the comments as to *why* things are different when we're using kDisposeRestorePrevious would be helpful too.
Attachment #467096 - Flags: review?(joe) → review+
Expanded comments, renamed imgContainer into RasterImage
Attachment #467096 - Attachment is obsolete: true
Attachment #467912 - Flags: review?(joe)
Attached patch tests v1Splinter Review
Added tests. These fail without the patch, and pass with it (Good Thing).

However, they make use of delaytest, so I fear they'll suffer from the same
problem as bug 558678. As such, I don't think they should be checked in right
now (though this patch certainly should).

Joe, after we stop working on ff4, what do you say we spend some serious time
cleaning up our test situation? ;-)
Requesting a2.0.

This patch is very low risk, and has tests. It fixes animation behavior and makes us more correct. This patch was submitted by a contributor, and thus does not represent a failing of any moco employee to be working on blockers.
status2.0: --- → ?
Comment on attachment 467912 [details] [diff] [review]
proposed patch, v3

Much better, thanks :)
Attachment #467912 - Flags: review?(joe) → review+
Comment on attachment 467912 [details] [diff] [review]
proposed patch, v3

well, except for Bobby, who worked on the test!!!!! :D
Attachment #467912 - Flags: approval2.0+
Comment on attachment 467932 [details] [diff] [review]
tests v1

What's the reason for changing the apng delaytest to 500ms?
Attachment #467932 - Flags: review+
Attachment #467932 - Flags: approval2.0+
(In reply to comment #28)
> Comment on attachment 467932 [details] [diff] [review]
> tests v1
> 
> What's the reason for changing the apng delaytest to 500ms?

comment 21, with an extra safety margin.

Either way, I don't think it's worth quibbling over now, since in the end we're probably going to make the reftest poll anyway.
status2.0: ? → ---
So what needs to happen at this point to land this?  Just adding checkin-needed?  Or can I just push the patches?
(In reply to comment #30)
> So what needs to happen at this point to land this?  Just adding
> checkin-needed?  Or can I just push the patches?

Should be good to go AFAIK.
Keywords: checkin-needed
(though probably not the tests, because they use delaytest, and will probably go intermittently orange)
Assignee: nobody → newstop
Pushed fix as http://hg.mozilla.org/mozilla-central/rev/d43112f63698

The test still needs to land.

Bobby, file a separate bug on tracking that, perhaps?
Status: NEW → RESOLVED
Closed: 14 years ago
Flags: in-testsuite?
Keywords: checkin-needed
Resolution: --- → FIXED
Target Milestone: --- → mozilla2.0b6
(In reply to comment #33) 
> Bobby, file a separate bug on tracking that, perhaps?

Filed bug 594147.
Thanks for landing. Everything works fine in Minefield:
Mozilla/5.0 (Windows NT 5.1; rv:2.0b6pre) Gecko/20100908 Firefox/4.0b6pre
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: