@@ -236,8 +236,16 @@ fn decode_into_replay_after_success_matches_oneshot() {
236236fn incomplete_data_returns_recoverable_eof ( ) {
237237 // Empty input → recoverable EOF
238238 let mut dec = JpegDecoder :: new ( ZCursor :: new ( & [ ] as & [ u8 ] ) ) ;
239+ assert ! ( dec. info( ) . is_none( ) ) ;
240+ assert_eq ! ( dec. output_buffer_size( ) , None ) ;
241+ assert_eq ! ( dec. decoded_output_bytes( ) , None ) ;
242+ assert_eq ! ( dec. decoded_scanlines( ) , None ) ;
239243 let err = dec. decode_headers ( ) . unwrap_err ( ) ;
240244 assert ! ( err. is_recoverable_eof( ) , "empty input: expected recoverable EOF, got: {err:?}" ) ;
245+ assert ! ( dec. info( ) . is_none( ) ) ;
246+ assert_eq ! ( dec. output_buffer_size( ) , None ) ;
247+ assert_eq ! ( dec. decoded_output_bytes( ) , None ) ;
248+ assert_eq ! ( dec. decoded_scanlines( ) , None ) ;
241249
242250 // Truncated just after SOI → recoverable EOF
243251 let data = include_bytes ! ( "../../../test-images/jpeg/synthetic_image.jpg" ) ;
@@ -249,6 +257,10 @@ fn incomplete_data_returns_recoverable_eof() {
249257 let mut dec = JpegDecoder :: new ( ZCursor :: new ( & [ 0x00 , 0x00 ] ) ) ;
250258 let err = dec. decode_headers ( ) . unwrap_err ( ) ;
251259 assert ! ( !err. is_recoverable_eof( ) , "bad magic: should not be recoverable, got: {err:?}" ) ;
260+ assert ! ( dec. info( ) . is_none( ) ) ;
261+ assert_eq ! ( dec. output_buffer_size( ) , None ) ;
262+ assert_eq ! ( dec. decoded_output_bytes( ) , None ) ;
263+ assert_eq ! ( dec. decoded_scanlines( ) , None ) ;
252264
253265 // Non-EOF error variants → NOT recoverable
254266 use zune_jpeg:: errors:: DecodeErrors ;
@@ -1271,6 +1283,8 @@ fn per_row_checkpoint_avoids_full_scan_replay() {
12711283 decoder
12721284 . decode_headers ( )
12731285 . expect ( "headers should be fully visible at cutoff" ) ;
1286+ assert_eq ! ( decoder. decoded_output_bytes( ) , Some ( 0 ) ) ;
1287+ assert_eq ! ( decoder. decoded_scanlines( ) , Some ( 0 ) ) ;
12741288 let mut out = vec ! [ 0u8 ; decoder. output_buffer_size( ) . unwrap( ) ] ;
12751289
12761290 // First decode attempt — should fail with recoverable EOF.
@@ -1285,6 +1299,11 @@ fn per_row_checkpoint_avoids_full_scan_replay() {
12851299 let first_scanlines = decoder
12861300 . decoded_scanlines ( )
12871301 . expect ( "headers are decoded, so partial progress should be known" ) ;
1302+ let first_bytes = decoder
1303+ . decoded_output_bytes ( )
1304+ . expect ( "headers are decoded, so partial progress should be known" ) ;
1305+ assert ! ( first_bytes > 0 , "scan EOF should expose a stable output prefix" ) ;
1306+ assert ! ( first_bytes < out. len( ) , "truncated decode should not report full output" ) ;
12881307 assert ! (
12891308 first_scanlines > 0 && first_scanlines < usize :: from( decoder. info( ) . unwrap( ) . height) ,
12901309 "expected a stable partial prefix, got {first_scanlines} scanlines"
@@ -1300,6 +1319,8 @@ fn per_row_checkpoint_avoids_full_scan_replay() {
13001319 err. is_recoverable_eof( ) ,
13011320 "expected recoverable EOF on second attempt, got {err:?}"
13021321 ) ;
1322+ assert ! ( decoder. decoded_output_bytes( ) . unwrap( ) >= first_bytes) ;
1323+ assert ! ( decoder. decoded_scanlines( ) . unwrap( ) >= first_scanlines) ;
13031324
13041325 // Third attempt — expose full data. Should resume from the per-row
13051326 // checkpoint saved during the second attempt.
@@ -1309,6 +1330,11 @@ fn per_row_checkpoint_avoids_full_scan_replay() {
13091330 . decode_into ( & mut out)
13101331 . expect ( "full data should allow decode to complete" ) ;
13111332 assert_pixels_match ( & out, & expected, "per_row_checkpoint" , data. len ( ) ) ;
1333+ assert_eq ! (
1334+ decoder. decoded_output_bytes( ) ,
1335+ Some ( out. len( ) ) ,
1336+ "successful decode should report the full output buffer as stable"
1337+ ) ;
13121338 assert_eq ! (
13131339 decoder. decoded_scanlines( ) ,
13141340 Some ( usize :: from( decoder. info( ) . unwrap( ) . height) ) ,
0 commit comments