@@ -214,18 +214,25 @@ vips_foreign_save_cgif_set_transparent( VipsForeignSaveCgif *cgif,
214
214
}
215
215
}
216
216
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
+
217
224
old += 4 ;
218
225
new += 4 ;
219
226
}
220
227
}
221
228
222
- static int
229
+ static double
223
230
vips__cgif_compare_palettes ( const VipsQuantisePalette * new ,
224
231
const VipsQuantisePalette * old )
225
232
{
226
233
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 ;
229
236
230
237
g_assert ( new -> count <= 256 );
231
238
g_assert ( old -> count <= 256 );
@@ -337,19 +344,23 @@ vips_foreign_save_cgif_pick_quantiser( VipsForeignSaveCgif *cgif,
337
344
const VipsQuantisePalette * prev = vips__quantise_get_palette (
338
345
cgif -> previous_quantisation_result );
339
346
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
+
340
351
#ifdef DEBUG_VERBOSE
341
352
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 );
344
355
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 );
347
358
printf ( "vips_foreign_save_cgif_write_frame: "
348
359
"threshold = %g\n" , cgif -> interpalette_maxerror );
349
360
#endif /*DEBUG_VERBOSE*/
350
361
351
- if ( vips__cgif_compare_palettes ( this , global ) <
352
- cgif -> interpalette_maxerror ) {
362
+ if ( global_diff <= prev_diff &&
363
+ global_diff < cgif -> interpalette_maxerror ) {
353
364
/* Global is good enough, use that.
354
365
*/
355
366
#ifdef DEBUG_VERBOSE
@@ -365,8 +376,7 @@ vips_foreign_save_cgif_pick_quantiser( VipsForeignSaveCgif *cgif,
365
376
* result = cgif -> quantisation_result ;
366
377
* use_local = FALSE;
367
378
}
368
- else if ( vips__cgif_compare_palettes ( this , prev ) <
369
- cgif -> interpalette_maxerror ) {
379
+ else if ( prev_diff < cgif -> interpalette_maxerror ) {
370
380
/* Previous is good enough, use that again.
371
381
*/
372
382
#ifdef DEBUG_VERBOSE
@@ -564,6 +574,11 @@ vips_foreign_save_cgif_write_frame( VipsForeignSaveCgif *cgif )
564
574
frame_config .attrFlags |= CGIF_FRAME_ATTR_HAS_SET_TRANS ;
565
575
frame_config .transIndex = trans ;
566
576
}
577
+ else {
578
+ /* Take a copy of the RGBA frame.
579
+ */
580
+ memcpy ( cgif -> previous_frame , frame_bytes , 4 * n_pels );
581
+ }
567
582
568
583
if ( cgif -> delay &&
569
584
page_index < cgif -> delay_length )
@@ -583,10 +598,6 @@ vips_foreign_save_cgif_write_frame( VipsForeignSaveCgif *cgif )
583
598
frame_config .pImageData = cgif -> index ;
584
599
cgif_addframe ( cgif -> cgif_context , & frame_config );
585
600
586
- /* Take a copy of the RGBA frame.
587
- */
588
- memcpy ( cgif -> previous_frame , frame_bytes , 4 * n_pels );
589
-
590
601
return ( 0 );
591
602
}
592
603
@@ -861,7 +872,7 @@ vips_foreign_save_cgif_class_init( VipsForeignSaveCgifClass *class )
861
872
_ ( "Maximum inter-palette error for palette reusage" ),
862
873
VIPS_ARGUMENT_OPTIONAL_INPUT ,
863
874
G_STRUCT_OFFSET ( VipsForeignSaveCgif , interpalette_maxerror ),
864
- 0 , 256 , 40 .0 );
875
+ 0 , 256 , 3 .0 );
865
876
}
866
877
867
878
static void
@@ -872,7 +883,7 @@ vips_foreign_save_cgif_init( VipsForeignSaveCgif *gif )
872
883
gif -> bitdepth = 8 ;
873
884
gif -> interframe_maxerror = 0.0 ;
874
885
gif -> reoptimise = FALSE;
875
- gif -> interpalette_maxerror = 40 .0 ;
886
+ gif -> interpalette_maxerror = 3 .0 ;
876
887
gif -> mode = VIPS_FOREIGN_SAVE_CGIF_MODE_GLOBAL ;
877
888
}
878
889
0 commit comments