mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-28 20:07:05 -06:00
* 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>
14 lines
440 B
Rust
14 lines
440 B
Rust
#![no_main]
|
|
|
|
use libfuzzer_sys::fuzz_target;
|
|
use photocraft_codecs::{decode_as_with, decode_gif_frames, DecodeOptions, Format, Limits};
|
|
|
|
fuzz_target!(|data: &[u8]| {
|
|
let opts = DecodeOptions {
|
|
limits: Limits { max_width: 4096, max_height: 4096, max_pixels: 1 << 22, max_alloc: 256 << 20 },
|
|
..Default::default()
|
|
};
|
|
let _ = decode_as_with(Format::Gif, data, &opts);
|
|
let _ = decode_gif_frames(data, &opts);
|
|
});
|