* feat(codecs): decode every frame of an animated GIF (#572)
decode_gif_frames returns each frame composited onto the logical screen
(disposal methods applied) with its delay in milliseconds. decode still
keeps the first frame only. A damaged later frame keeps the frames before
it and marks the first with DecodeWarning::Truncated; dimensions, the
total decoded bytes and a frame cap are checked against the limits.
* feat(io): import_gif_frames hands each GIF frame over as a document (#572)
A frame at a time becomes a single-layer document, so a caller can
flatten and drop it instead of holding every frame twice.
* feat(engine): animated GIFs load every frame into video layers (#572)
New Video Layer from File, Replace Footage, Reload Frame and Video Frames
to Layers take all frames of a GIF instead of the first. The timeline rate
comes from the GIF's delays (the most common one, delays under 20 ms shown
at 100 ms as browsers do); an explicit fps still wins.
* docs: animated GIF frames in video layers (#572)
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>