Prevent divide-by-zero in ImageAnimator for images with 0 delay between frames#56223
Prevent divide-by-zero in ImageAnimator for images with 0 delay between frames#56223danmoseley merged 2 commits intodotnet:mainfrom jeffhandley:jeffhandley/imageanimator/0
Conversation
|
Tagging subscribers to this area: @safern, @tarekgh Issue DetailsFixes #55972 Per the GIF spec, a frame delay can have a value of 0. That was historically used for 2 purposes:
While the latter of those features is archaic, we still need to handle 0-delay frames. We assign them our animation delay speed to be "1 tick". It's possible the frame could get skipped if a tick takes longer than the tick time, but this gives a uniform speed for GIFs where all frame delays are 0. To prevent the divide-by-zero:
|
| /// and if there are animation frames or loops remaining. | ||
| /// </summary> | ||
| private bool ShouldAnimate => Animated ? (_loopCount == 0 || _loop <= _loopCount) : false; | ||
| private bool ShouldAnimate => TotalAnimationTime > 0 ? (_loopCount == 0 || _loop <= _loopCount) : false; |
There was a problem hiding this comment.
This changes the behavior at line 160, preventing animation from occurring if the total animation time is <= 0.
| lastEndTime += delay > 0 ? delay : ImageAnimator.AnimationDelayMS; | ||
|
|
||
| // Guard against overflows | ||
| if (lastEndTime < _totalAnimationTime) |
There was a problem hiding this comment.
this is for cases where delay is negative? does that ever happen/is it legal or are you just being careful?
There was a problem hiding this comment.
if just being careful, could you instead simply force delay to be no less than zero? then I think you wouldn't need _totalAnimationTime?
There was a problem hiding this comment.
I'm being careful mostly. Here's how it comes together though.
- If the delay is <= 0, then apply the default animation delay
- If the accumulated last end time overflows, then collapse all of the remaining frames into that instant (essentially skipping any frames beyond the overflow of animation time)
- Ensure that TotalAnimationTime is a non-zero value if any frames are to be animated
- Eliminate the array access from TotalAnimationTime, replacing that with _totalAnimationTime
|
Speaking of animated images, I wonder when System.Drawing.Common's ImageAnimator can pick up png images with multiple frames as animated? I guess I could try to see if I can propose an api to help provide support for animated png's if possible on the .NET side of things in .NET 7 if that is required then somehow get the image animator to actually check for it all. And yes this is a known issue with people trying to manually hack in their own "Image animator" for their picture boxes as well. |
|
Unrelated failures. |
safern
left a comment
There was a problem hiding this comment.
LGTM, thanks for fixing so quickly!
Fixes #55972
Per the GIF spec, a frame delay can have a value of 0. That was historically used for 2 purposes:
While the latter of those features is archaic, we still need to handle 0-delay frames. We assign them our animation delay speed to be "1 tick". It's possible the frame could get skipped if a tick takes longer than the tick time, but this gives a uniform speed for GIFs where all frame delays are 0.
To prevent the divide-by-zero:
ShouldAnimateproperty to check that the total animation time is > 0