Animated GIF imagery with finite looping are falling one loop short
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Apr 2018 16:22:49 +0000 (16:22 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Apr 2018 16:22:49 +0000 (16:22 +0000)
commit3d65b949b7274aaadd4d5abd8281ae5e8b3cec6f
tree902f0f5e7c4cb1290650a44597ed8d787424ebc5
parent9c43651bddbcf83f24bdf4ed2bfed3b25ff5a2f4
Animated GIF imagery with finite looping are falling one loop short
https://bugs.webkit.org/show_bug.cgi?id=183153

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2018-04-17
Reviewed by Simon Fraser.

Source/WebCore:

The Netscape Looping Application Extension is a block which may be added
to a GIF file to tell the viewer to loop through the entire GIF frames.
This is communicated through two bytes designated for the "loopCount" in
this block.

The entire block may not be found in the GIF, in which case the GIF is
supposed to animate its entire frames only once.

If the block exists and loopCount = 0, this means the image has to loop
through its frames indefinitely.

If the block exist and loopCount > 0, this should mean the image has to
loop through its frames loopCount + 1 times. The extra loop seems to be
the consensus among most of the GIF generators and viewers. For example,
if the image designer wants the image to loop through its frames n times:
-- The GIF generator (e.g. Adobe Photoshop and https://ezgif.com/maker)
   will write n - 1 for loopCount. However http://gifmaker.me and
   http://gifmaker.org write n for loopCount.
-- The browser (e.g. Chrome 65.0.3325 181 and FireFox Quantum 59.0.2) will
   translate loopCount = n - 1 to: animate GIF once + loop n - 1, which
   means loop the GIF n times.

Because the specs are not really clear about this, we are going to consider
the agreed-upon behavior among most of the web browsers the specs here.

* platform/graphics/cg/ImageDecoderCG.cpp:
(WebCore::ImageDecoderCG::repetitionCount const):
* platform/image-decoders/gif/GIFImageDecoder.cpp:
(WebCore::GIFImageDecoder::repetitionCount const):

LayoutTests:

This layout test tests GIF when it has to loop its entire frames a specific
number of times. There are three cases for the loopCount field:
-- loopCount is missing: This means the GIF should animate only once. This
   is covered by animated-red-green-blue-repeat-1.gif.
-- loopCount = 0: This means the image has to animate indefinatly. This
   case is covered by the new GIF animated-red-green-blue-repeat-infinite.gif.
-- loopCount > 0: This will loop the GIF entire frames for (loopCount + 1)
   times. To fix the test with the extra loop, loopCount in
   animated-red-green-blue-repeat-2.gif was changed to 1 instead of 2.

* fast/images/animated-image-loop-count-expected.html:
* fast/images/animated-image-loop-count.html:
* fast/images/resources/animated-red-green-blue-repeat-2.gif:
* fast/images/resources/animated-red-green-blue-repeat-infinite.gif:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
LayoutTests/ChangeLog
LayoutTests/fast/images/animated-image-loop-count-expected.html
LayoutTests/fast/images/animated-image-loop-count.html
LayoutTests/fast/images/resources/animated-red-green-blue-repeat-2.gif
LayoutTests/fast/images/resources/animated-red-green-blue-repeat-infinite.gif [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp
Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp