@@ -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 ;
@@ -163,6 +158,7 @@ static gboolean avif_animation_iter_advance(GdkPixbufAnimationIter * iter, const
163158 elapsed_time -= frame_duration ;
164159 avif_iter -> current_frame ++ ;
165160 }
161+ avif_iter -> current_frame = avif_iter -> current_frame % context -> decoder -> imageCount ;
166162 }
167163
168164 return prev_frame != avif_iter -> current_frame ;
@@ -423,6 +419,7 @@ static gboolean avif_context_try_load(AvifAnimation * context, GError ** error)
423419 AvifAnimationFrame frame ;
424420 frame .pixbuf = set_pixbuf (context , error );
425421 frame .duration_ms = (uint64_t )(decoder -> imageTiming .duration * 1000 );
422+ context -> animation_time = frame .duration_ms ;
426423
427424 if (frame .pixbuf == NULL ) {
428425 return FALSE;
@@ -447,6 +444,13 @@ static gboolean avif_context_try_load(AvifAnimation * context, GError ** error)
447444 frame .pixbuf = set_pixbuf (context , error );
448445 frame .duration_ms = (uint64_t )(decoder -> imageTiming .duration * 1000 );
449446
447+ if (frame .pixbuf == NULL ) {
448+ return FALSE;
449+ }
450+
451+ /* We don't use the animation duration from the AVIF structure directly due to precision problems */
452+ context -> animation_time += frame .duration_ms ;
453+
450454 g_array_append_val (context -> frames , frame );
451455 }
452456 return TRUE;
0 commit comments