@@ -22,6 +22,7 @@ typedef struct {
2222struct _AvifAnimation {
2323 GdkPixbufAnimation parent ;
2424 GArray * frames ;
25+ uint64_t animation_time ;
2526
2627 GdkPixbufModuleSizeFunc size_func ;
2728 GdkPixbufModuleUpdatedFunc updated_func ;
@@ -140,16 +141,10 @@ static gboolean avif_animation_iter_advance(GdkPixbufAnimationIter * iter, const
140141 size_t prev_frame = avif_iter -> current_frame ;
141142 uint64_t elapsed_time = current_time -> tv_sec * 1000 + current_time -> tv_usec / 1000 - avif_iter -> time_offset ;
142143
143- /*
144- * duration in seconds stored in a double which is cast to uint64_t
145- * is the precision loss here significant?
146- */
147- uint64_t animation_time = (uint64_t )(context -> decoder -> duration * 1000 );
148-
149- if (context -> decoder -> repetitionCount > 0 && elapsed_time > animation_time * context -> decoder -> repetitionCount ) {
144+ if (context -> decoder -> repetitionCount > 0 && elapsed_time > context -> animation_time * context -> decoder -> repetitionCount ) {
150145 avif_iter -> current_frame = context -> decoder -> imageCount - 1 ;
151146 } else {
152- elapsed_time = elapsed_time % animation_time ;
147+ elapsed_time = elapsed_time % context -> animation_time ;
153148
154149 avif_iter -> current_frame = 0 ;
155150 uint64_t frame_duration ;
@@ -423,6 +418,7 @@ static gboolean avif_context_try_load(AvifAnimation * context, GError ** error)
423418 AvifAnimationFrame frame ;
424419 frame .pixbuf = set_pixbuf (context , error );
425420 frame .duration_ms = (uint64_t )(decoder -> imageTiming .duration * 1000 );
421+ context -> animation_time = frame .duration_ms ;
426422
427423 if (frame .pixbuf == NULL ) {
428424 return FALSE;
@@ -447,6 +443,13 @@ static gboolean avif_context_try_load(AvifAnimation * context, GError ** error)
447443 frame .pixbuf = set_pixbuf (context , error );
448444 frame .duration_ms = (uint64_t )(decoder -> imageTiming .duration * 1000 );
449445
446+ if (frame .pixbuf == NULL ) {
447+ return FALSE;
448+ }
449+
450+ /* We don't use the animation duration from the AVIF structure directly due to precision problems */
451+ context -> animation_time += frame .duration_ms ;
452+
450453 g_array_append_val (context -> frames , frame );
451454 }
452455 return TRUE;
0 commit comments