@@ -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+
118144fn 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]
693752fn 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]
701761fn 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