@@ -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 ;
@@ -163,6 +158,7 @@ static gboolean avif_animation_iter_advance(GdkPixbufAnimationIter * iter, const
163
158
elapsed_time -= frame_duration ;
164
159
avif_iter -> current_frame ++ ;
165
160
}
161
+ avif_iter -> current_frame = avif_iter -> current_frame % context -> decoder -> imageCount ;
166
162
}
167
163
168
164
return prev_frame != avif_iter -> current_frame ;
@@ -423,6 +419,7 @@ static gboolean avif_context_try_load(AvifAnimation * context, GError ** error)
423
419
AvifAnimationFrame frame ;
424
420
frame .pixbuf = set_pixbuf (context , error );
425
421
frame .duration_ms = (uint64_t )(decoder -> imageTiming .duration * 1000 );
422
+ context -> animation_time = frame .duration_ms ;
426
423
427
424
if (frame .pixbuf == NULL ) {
428
425
return FALSE;
@@ -447,6 +444,13 @@ static gboolean avif_context_try_load(AvifAnimation * context, GError ** error)
447
444
frame .pixbuf = set_pixbuf (context , error );
448
445
frame .duration_ms = (uint64_t )(decoder -> imageTiming .duration * 1000 );
449
446
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
+
450
454
g_array_append_val (context -> frames , frame );
451
455
}
452
456
return TRUE;
0 commit comments