From e16374507f8c51c61f0f1a276308144baf8d6489 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 15 Apr 2020 23:15:03 +0300 Subject: [PATCH] Fix retrieval of frame delay when using GDI+ * src/w32image.c (enum PropertyItem_type): New enumeration. (decode_delay): New function. (w32_frame_delay): Call 'decode_delay' to retrieve the frame delay from image data. --- src/w32image.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/w32image.c b/src/w32image.c index 6a3e37ce0ee..fb36dc9a9f6 100644 --- a/src/w32image.c +++ b/src/w32image.c @@ -200,6 +200,43 @@ w32_can_use_native_image_api (Lisp_Object type) return gdiplus_startup (); } +enum PropertyItem_type { + PI_BYTE = 1, + PI_ASCIIZ = 2, + PI_USHORT = 3, + PI_ULONG = 4, + PI_ULONG_PAIR = 5, + PI_BYTE_ANY = 6, + PI_LONG = 7, + PI_LONG_PAIR = 10 +}; + +static unsigned long +decode_delay (PropertyItem *propertyItem, int frame) +{ + enum PropertyItem_type type = propertyItem[0].type; + unsigned long delay; + + switch (type) + { + case PI_BYTE: + case PI_BYTE_ANY: + delay = ((unsigned char *)propertyItem[0].value)[frame]; + break; + case PI_USHORT: + delay = ((unsigned short *)propertyItem[0].value)[frame]; + break; + case PI_ULONG: + case PI_LONG: /* delay should always be positive */ + delay = ((unsigned long *)propertyItem[0].value)[frame]; + break; + default: + emacs_abort (); + } + + return delay; +} + static double w32_frame_delay (GpBitmap *pBitmap, int frame) { @@ -217,13 +254,14 @@ w32_frame_delay (GpBitmap *pBitmap, int frame) { /* Get the property item. */ GdipGetPropertyItem (pBitmap, PropertyTagFrameDelay, size, propertyItem); - delay = propertyItem[frame].length / 100.0; - if (delay == 0) + delay = decode_delay (propertyItem, frame); + if (delay <= 0) { /* In GIF files, unfortunately, delay is only specified for the first frame. */ - delay = propertyItem[0].length / 100.0; + delay = decode_delay (propertyItem, 0); } + delay /= 100.0; free (propertyItem); } return delay; -- 2.39.5