@@ -958,8 +958,10 @@ test("decodeGifFirstFrame agrees byte-for-byte with frames[0] (synthetic)", () =
958958 ) ;
959959} ) ;
960960
961- test ( "decodeGifFirstFrame agrees with the full decode on both fixture GIFs" , ( ) => {
962- for ( const path of [ TESTSRC_GIF , SINTEL_GIF ] ) {
961+ test ( "decodeGifFirstFrame agrees with the full decode on every available fixture GIF" , ( ) => {
962+ const fixtures = [ TESTSRC_GIF , SINTEL_GIF ] . filter ( existsSync ) ;
963+ assert ( fixtures . length > 0 , "at least the checked-in fixture is present" ) ;
964+ for ( const path of fixtures ) {
963965 const bytes = new Uint8Array ( readFileSync ( path ) ) ;
964966 const full = mustDecode ( bytes , path ) ;
965967 const first = decodeGifFirstFrame ( bytes ) ;
@@ -1090,7 +1092,11 @@ if (FFMPEG_DIR === null) {
10901092 const fixtures : Array < [ string , string , number ] > = [
10911093 [ TESTSRC_GIF , "testsrc-48x32-8f" , 8 ] ,
10921094 [ SINTEL_GIF , "sintel-3s" , 36 ] ,
1093- ] ;
1095+ ] . filter ( ( [ path ] ) => existsSync ( path ) ) ;
1096+
1097+ if ( ! existsSync ( SINTEL_GIF ) ) {
1098+ console . log ( " \x1b[33m- skipped: optional devnotes/media/sintel-3s.gif fixture missing\x1b[0m" ) ;
1099+ }
10941100
10951101 for ( const [ path , label , expectedFrames ] of fixtures ) {
10961102 test ( `${ label } : frames match ffmpeg's composited output (MAE ~0)` , ( ) => {
@@ -1151,22 +1157,24 @@ if (FFMPEG_DIR === null) {
11511157 }
11521158 } ) ;
11531159
1154- test ( "sintel-3s: first-frame fast path is cheaper than the full decode" , ( ) => {
1155- const bytes = new Uint8Array ( readFileSync ( SINTEL_GIF ) ) ;
1156- const t0 = performance . now ( ) ;
1157- const full = decodeGif ( bytes ) ;
1158- const fullMs = performance . now ( ) - t0 ;
1159- const t1 = performance . now ( ) ;
1160- const first = decodeGifFirstFrame ( bytes ) ;
1161- const firstMs = performance . now ( ) - t1 ;
1162- assert ( full . ok && first !== null , "both paths decode" ) ;
1163- measurements . push ( `sintel-3s: full decode ${ fullMs . toFixed ( 1 ) } ms, first frame only ${ firstMs . toFixed ( 1 ) } ms` ) ;
1164- console . log ( ` ${ measurements [ measurements . length - 1 ] } ` ) ;
1165- // Frame 0 is ~1/36th of the LZW work; anything close to the full decode
1166- // would mean the early-out is not early. Generous 0.75 bound so timer
1167- // noise on a loaded machine cannot flake the suite.
1168- assert ( firstMs < fullMs * 0.75 + 2 , `first-frame ${ firstMs } ms vs full ${ fullMs } ms` ) ;
1169- } ) ;
1160+ if ( existsSync ( SINTEL_GIF ) ) {
1161+ test ( "sintel-3s: first-frame fast path is cheaper than the full decode" , ( ) => {
1162+ const bytes = new Uint8Array ( readFileSync ( SINTEL_GIF ) ) ;
1163+ const t0 = performance . now ( ) ;
1164+ const full = decodeGif ( bytes ) ;
1165+ const fullMs = performance . now ( ) - t0 ;
1166+ const t1 = performance . now ( ) ;
1167+ const first = decodeGifFirstFrame ( bytes ) ;
1168+ const firstMs = performance . now ( ) - t1 ;
1169+ assert ( full . ok && first !== null , "both paths decode" ) ;
1170+ measurements . push ( `sintel-3s: full decode ${ fullMs . toFixed ( 1 ) } ms, first frame only ${ firstMs . toFixed ( 1 ) } ms` ) ;
1171+ console . log ( ` ${ measurements [ measurements . length - 1 ] } ` ) ;
1172+ // Frame 0 is ~1/36th of the LZW work; anything close to the full decode
1173+ // would mean the early-out is not early. Generous 0.75 bound so timer
1174+ // noise on a loaded machine cannot flake the suite.
1175+ assert ( firstMs < fullMs * 0.75 + 2 , `first-frame ${ firstMs } ms vs full ${ fullMs } ms` ) ;
1176+ } ) ;
1177+ }
11701178}
11711179
11721180// ═════════════════════════════════════════════════════════
0 commit comments