@@ -341,17 +341,9 @@ impl PngImage {
341341 let mut prev_line = Vec :: new ( ) ;
342342 let mut prev_pass: Option < u8 > = None ;
343343 let mut f_buf = Vec :: new ( ) ;
344- let mut best_possible = 0 ;
345344 for line in self . scan_lines ( false ) {
346345 if prev_pass != line. pass || line. data . len ( ) != prev_line. len ( ) {
347346 prev_line = vec ! [ 0 ; line. data. len( ) ] ;
348- // Calculate the best possible result for this pass
349- best_possible = match filter {
350- RowFilter :: Entropy => ilog2i ( line. data . len ( ) as u32 + 1 ) as i32 ,
351- RowFilter :: Bigrams => 1 ,
352- RowFilter :: BigEnt => ilog2i ( line. data . len ( ) as u32 ) as i32 ,
353- _ => 0 ,
354- }
355347 }
356348 // Alpha optimisation may alter the line data, so we need a mutable copy of it
357349 let mut line_data = line. data . to_vec ( ) ;
@@ -368,6 +360,15 @@ impl PngImage {
368360 prev_line = line_data;
369361 } else {
370362 // Heuristic filter selection strategies
363+
364+ if line_data. iter ( ) . all ( |& x| x == 0 ) {
365+ // Assume None if the line is all zeros
366+ filtered. push ( RowFilter :: None as u8 ) ;
367+ filtered. extend_from_slice ( & line_data) ;
368+ prev_line = line_data;
369+ continue ;
370+ }
371+
371372 let mut best_line = Vec :: new ( ) ;
372373 let mut best_line_raw = Vec :: new ( ) ;
373374 // Avoid vertical filtering on first line of each interlacing pass
@@ -380,21 +381,17 @@ impl PngImage {
380381 RowFilter :: MinSum => {
381382 // MSAD algorithm mentioned in libpng reference docs
382383 // http://www.libpng.org/pub/png/book/chapter09.html
383- let mut best_size = i32 :: MAX ;
384+ let mut best_size = usize :: MAX ;
384385 for f in try_filters {
385386 f. filter_line ( bpp, & mut line_data, & prev_line, & mut f_buf, alpha_bytes) ;
386387 let size = f_buf. iter ( ) . fold ( 0 , |acc, & x| {
387388 let signed = x as i8 ;
388- acc + signed. unsigned_abs ( ) as i32
389+ acc + signed. unsigned_abs ( ) as usize
389390 } ) ;
390391 if size < best_size {
391392 best_size = size;
392393 std:: mem:: swap ( & mut best_line, & mut f_buf) ;
393394 best_line_raw. clone_from ( & line_data) ;
394- if size == best_possible {
395- // Best possible result
396- break ;
397- }
398395 }
399396 }
400397 }
@@ -418,33 +415,25 @@ impl PngImage {
418415 best_size = size;
419416 std:: mem:: swap ( & mut best_line, & mut f_buf) ;
420417 best_line_raw. clone_from ( & line_data) ;
421- if size == best_possible {
422- // Best possible result
423- break ;
424- }
425418 }
426419 }
427420 }
428421 RowFilter :: Bigrams => {
429422 // Count distinct bigrams, from pngwolf
430423 // https://bjoern.hoehrmann.de/pngwolf/
431- let mut best_size = i32 :: MAX ;
424+ let mut best_size = usize :: MAX ;
432425 for f in try_filters {
433426 f. filter_line ( bpp, & mut line_data, & prev_line, & mut f_buf, alpha_bytes) ;
434427 let mut set = bitarr ! [ 0 ; 0x10000 ] ;
435428 for pair in f_buf. windows ( 2 ) {
436429 let bigram = ( pair[ 0 ] as usize ) << 8 | pair[ 1 ] as usize ;
437430 set. set ( bigram, true ) ;
438431 }
439- let size = set. count_ones ( ) as i32 ;
432+ let size = set. count_ones ( ) ;
440433 if size < best_size {
441434 best_size = size;
442435 std:: mem:: swap ( & mut best_line, & mut f_buf) ;
443436 best_line_raw. clone_from ( & line_data) ;
444- if size == best_possible {
445- // Best possible result
446- break ;
447- }
448437 }
449438 }
450439 }
@@ -465,10 +454,6 @@ impl PngImage {
465454 best_size = size;
466455 std:: mem:: swap ( & mut best_line, & mut f_buf) ;
467456 best_line_raw. clone_from ( & line_data) ;
468- if size == best_possible {
469- // Best possible result
470- break ;
471- }
472457 }
473458 }
474459 }
0 commit comments