Skip to content

Commit 41da0d2

Browse files
authored
cgifsave: remove regressions from 2853 (#2870)
* cgifsave: pick the best quantizer instead of the first good enough * cgifsave: fix palettes comparison * cgifsave: don't copy unchanged pixels to previous_frame
1 parent 5b79a74 commit 41da0d2

File tree

1 file changed

+28
-17
lines changed

1 file changed

+28
-17
lines changed

libvips/foreign/cgifsave.c

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -214,18 +214,25 @@ vips_foreign_save_cgif_set_transparent( VipsForeignSaveCgif *cgif,
214214
}
215215
}
216216

217+
if( index[i] != trans ) {
218+
old[0] = new[0];
219+
old[1] = new[1];
220+
old[2] = new[2];
221+
old[3] = new[3];
222+
}
223+
217224
old += 4;
218225
new += 4;
219226
}
220227
}
221228

222-
static int
229+
static double
223230
vips__cgif_compare_palettes( const VipsQuantisePalette *new,
224231
const VipsQuantisePalette *old )
225232
{
226233
int i, j;
227-
int best_dist, dist, rd, gd, bd;
228-
int total_dist;
234+
double best_dist, dist, rd, gd, bd;
235+
double total_dist;
229236

230237
g_assert( new->count <= 256 );
231238
g_assert( old->count <= 256 );
@@ -337,19 +344,23 @@ vips_foreign_save_cgif_pick_quantiser( VipsForeignSaveCgif *cgif,
337344
const VipsQuantisePalette *prev = vips__quantise_get_palette(
338345
cgif->previous_quantisation_result );
339346

347+
double global_diff = vips__cgif_compare_palettes( this, global );
348+
double prev_diff = ( prev == global ) ? global_diff :
349+
vips__cgif_compare_palettes( this, prev );
350+
340351
#ifdef DEBUG_VERBOSE
341352
printf( "vips_foreign_save_cgif_write_frame: "
342-
"this -> global distance = %d\n",
343-
vips__cgif_compare_palettes( this, global ) );
353+
"this -> global distance = %g\n",
354+
global_diff );
344355
printf( "vips_foreign_save_cgif_write_frame: "
345-
"this -> prev distance = %d\n",
346-
vips__cgif_compare_palettes( this, prev ) );
356+
"this -> prev distance = %g\n",
357+
prev_diff );
347358
printf( "vips_foreign_save_cgif_write_frame: "
348359
"threshold = %g\n", cgif->interpalette_maxerror );
349360
#endif/*DEBUG_VERBOSE*/
350361

351-
if( vips__cgif_compare_palettes( this, global ) <
352-
cgif->interpalette_maxerror ) {
362+
if( global_diff <= prev_diff &&
363+
global_diff < cgif->interpalette_maxerror ) {
353364
/* Global is good enough, use that.
354365
*/
355366
#ifdef DEBUG_VERBOSE
@@ -365,8 +376,7 @@ vips_foreign_save_cgif_pick_quantiser( VipsForeignSaveCgif *cgif,
365376
*result = cgif->quantisation_result;
366377
*use_local = FALSE;
367378
}
368-
else if( vips__cgif_compare_palettes( this, prev ) <
369-
cgif->interpalette_maxerror ) {
379+
else if( prev_diff < cgif->interpalette_maxerror ) {
370380
/* Previous is good enough, use that again.
371381
*/
372382
#ifdef DEBUG_VERBOSE
@@ -564,6 +574,11 @@ vips_foreign_save_cgif_write_frame( VipsForeignSaveCgif *cgif )
564574
frame_config.attrFlags |= CGIF_FRAME_ATTR_HAS_SET_TRANS;
565575
frame_config.transIndex = trans;
566576
}
577+
else {
578+
/* Take a copy of the RGBA frame.
579+
*/
580+
memcpy( cgif->previous_frame, frame_bytes, 4 * n_pels );
581+
}
567582

568583
if( cgif->delay &&
569584
page_index < cgif->delay_length )
@@ -583,10 +598,6 @@ vips_foreign_save_cgif_write_frame( VipsForeignSaveCgif *cgif )
583598
frame_config.pImageData = cgif->index;
584599
cgif_addframe( cgif->cgif_context, &frame_config );
585600

586-
/* Take a copy of the RGBA frame.
587-
*/
588-
memcpy( cgif->previous_frame, frame_bytes, 4 * n_pels );
589-
590601
return( 0 );
591602
}
592603

@@ -861,7 +872,7 @@ vips_foreign_save_cgif_class_init( VipsForeignSaveCgifClass *class )
861872
_( "Maximum inter-palette error for palette reusage" ),
862873
VIPS_ARGUMENT_OPTIONAL_INPUT,
863874
G_STRUCT_OFFSET( VipsForeignSaveCgif, interpalette_maxerror ),
864-
0, 256, 40.0 );
875+
0, 256, 3.0 );
865876
}
866877

867878
static void
@@ -872,7 +883,7 @@ vips_foreign_save_cgif_init( VipsForeignSaveCgif *gif )
872883
gif->bitdepth = 8;
873884
gif->interframe_maxerror = 0.0;
874885
gif->reoptimise = FALSE;
875-
gif->interpalette_maxerror = 40.0;
886+
gif->interpalette_maxerror = 3.0;
876887
gif->mode = VIPS_FOREIGN_SAVE_CGIF_MODE_GLOBAL;
877888
}
878889

0 commit comments

Comments
 (0)