@@ -22,6 +22,7 @@ typedef struct {
22
22
struct _AvifAnimation {
23
23
GdkPixbufAnimation parent ;
24
24
GArray * frames ;
25
+ uint64_t animation_time ;
25
26
26
27
GdkPixbufModuleSizeFunc size_func ;
27
28
GdkPixbufModuleUpdatedFunc updated_func ;
@@ -140,16 +141,10 @@ static gboolean avif_animation_iter_advance(GdkPixbufAnimationIter * iter, const
140
141
size_t prev_frame = avif_iter -> current_frame ;
141
142
uint64_t elapsed_time = current_time -> tv_sec * 1000 + current_time -> tv_usec / 1000 - avif_iter -> time_offset ;
142
143
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 ) {
150
145
avif_iter -> current_frame = context -> decoder -> imageCount - 1 ;
151
146
} else {
152
- elapsed_time = elapsed_time % animation_time ;
147
+ elapsed_time = elapsed_time % context -> animation_time ;
153
148
154
149
avif_iter -> current_frame = 0 ;
155
150
uint64_t frame_duration ;
@@ -423,6 +418,7 @@ static gboolean avif_context_try_load(AvifAnimation * context, GError ** error)
423
418
AvifAnimationFrame frame ;
424
419
frame .pixbuf = set_pixbuf (context , error );
425
420
frame .duration_ms = (uint64_t )(decoder -> imageTiming .duration * 1000 );
421
+ context -> animation_time = frame .duration_ms ;
426
422
427
423
if (frame .pixbuf == NULL ) {
428
424
return FALSE;
@@ -447,6 +443,13 @@ static gboolean avif_context_try_load(AvifAnimation * context, GError ** error)
447
443
frame .pixbuf = set_pixbuf (context , error );
448
444
frame .duration_ms = (uint64_t )(decoder -> imageTiming .duration * 1000 );
449
445
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
+
450
453
g_array_append_val (context -> frames , frame );
451
454
}
452
455
return TRUE;
0 commit comments