Skip to content

Commit 09df20c

Browse files
committed
test: add animated GIF → JXL/AVIF tests, verify auto selects GIF for animation
Adds 4 new e2e tests: - animated_gif_to_jxl: first-frame extraction to JXL lossy - animated_gif_to_jxl_lossless: first-frame extraction to JXL lossless - animated_gif_to_avif: first-frame extraction to AVIF - static_gif_to_jxl_and_avif: S3 GIF source to JXL and AVIF Also strengthens animated_gif_format_auto_modern to assert GIF output (since AVIF/JXL/WebP animation encoding is not yet enabled). Total: 46 e2e tests passing.
1 parent 8c99e96 commit 09df20c

1 file changed

Lines changed: 80 additions & 1 deletion

File tree

imageflow_core/tests/integration/visuals/codec_e2e.rs

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,32 @@ fn run_command_bytes(input: Vec<u8>, command: &str) -> Vec<u8> {
115115
output
116116
}
117117

118+
/// Run a JSON-node pipeline with in-memory bytes input.
119+
fn run_preset_bytes(input: Vec<u8>, w: u32, h: u32, preset: EncoderPreset) -> Vec<u8> {
120+
test_init();
121+
let steps = vec![
122+
Node::Decode { io_id: 0, commands: None },
123+
Node::Constrain(Constraint {
124+
mode: ConstraintMode::Within,
125+
w: Some(w),
126+
h: Some(h),
127+
hints: None,
128+
gravity: None,
129+
canvas_color: None,
130+
}),
131+
Node::Encode { io_id: 1, preset },
132+
];
133+
let mut ctx = Context::create().unwrap();
134+
ctx.add_input_vector(0, input).unwrap();
135+
ctx.add_output_buffer(1).unwrap();
136+
let execute =
137+
Execute001 { graph_recording: None, security: None, framewise: Framewise::Steps(steps) };
138+
ctx.execute_1(execute).unwrap();
139+
let output = ctx.take_output_buffer(1).unwrap();
140+
assert!(!output.is_empty(), "empty output for preset");
141+
output
142+
}
143+
118144
fn resolve_source_url(source: &str) -> String {
119145
if source.starts_with("http://") || source.starts_with("https://") {
120146
source.to_owned()
@@ -688,6 +714,39 @@ fn animated_gif_to_webp() {
688714
assert_webp(&output, "animated→webp");
689715
}
690716

717+
/// Animated GIF → JXL (first frame only — JXL animation not yet enabled).
718+
#[test]
719+
fn animated_gif_to_jxl() {
720+
let input = animated_gif_3_frames();
721+
let output = run_preset_bytes(input, 64, 64, EncoderPreset::JxlLossy { distance: 1.0 });
722+
assert_jxl(&output, "animated→jxl (first frame)");
723+
}
724+
725+
/// Animated GIF → JXL lossless (first frame only).
726+
#[test]
727+
fn animated_gif_to_jxl_lossless() {
728+
let input = animated_gif_3_frames();
729+
let output = run_preset_bytes(input, 64, 64, EncoderPreset::JxlLossless);
730+
assert_jxl(&output, "animated→jxl_ll (first frame)");
731+
}
732+
733+
/// Animated GIF → AVIF (first frame only — AVIF animation not yet enabled).
734+
#[test]
735+
fn animated_gif_to_avif() {
736+
let input = animated_gif_3_frames();
737+
let avif_preset = EncoderPreset::Format {
738+
format: s::OutputImageFormat::Avif,
739+
quality_profile: Some(QualityProfile::Good),
740+
quality_profile_dpr: None,
741+
matte: None,
742+
lossless: None,
743+
allow: Some(AllowedFormats::avif()),
744+
encoder_hints: None,
745+
};
746+
let output = run_preset_bytes(input, 64, 64, avif_preset);
747+
assert_avif(&output, "animated→avif (first frame)");
748+
}
749+
691750
/// Animated GIF with format=auto.
692751
#[test]
693752
fn animated_gif_format_auto() {
@@ -697,14 +756,34 @@ fn animated_gif_format_auto() {
697756
}
698757

699758
/// Animated GIF with format=auto and modern codec acceptance.
759+
/// Since AVIF/JXL/WebP animation is not yet enabled, auto should still select GIF.
700760
#[test]
701761
fn animated_gif_format_auto_modern() {
702762
let input = animated_gif_3_frames();
703763
let output = run_command_bytes(
704764
input,
705765
"w=64&h=64&mode=max&format=auto&accept.webp=true&accept.avif=true&accept.jxl=true",
706766
);
707-
assert!(!output.is_empty(), "animated→auto(modern): empty output");
767+
assert_gif(&output, "animated→auto(modern) should be GIF (no animated AVIF/JXL/WebP yet)");
768+
}
769+
770+
/// Static GIF (single frame from S3) → JXL and AVIF via URL command.
771+
#[test]
772+
fn static_gif_to_jxl_and_avif() {
773+
let jxl = run_preset(SRC_GIF, 300, 300, EncoderPreset::JxlLossy { distance: 1.0 });
774+
assert_jxl(&jxl, "static_gif→jxl");
775+
776+
let avif_preset = EncoderPreset::Format {
777+
format: s::OutputImageFormat::Avif,
778+
quality_profile: Some(QualityProfile::Good),
779+
quality_profile_dpr: None,
780+
matte: None,
781+
lossless: None,
782+
allow: Some(AllowedFormats::avif()),
783+
encoder_hints: None,
784+
};
785+
let avif = run_preset(SRC_GIF, 300, 300, avif_preset);
786+
assert_avif(&avif, "static_gif→avif");
708787
}
709788

710789
// ============================================================================

0 commit comments

Comments
 (0)