From 0df09db23e165f157fb8003bf6b914d635dc111e Mon Sep 17 00:00:00 2001 From: yuqingli05 <106426122+yuqingli05@users.noreply.github.com> Date: Tue, 21 Feb 2023 04:05:48 +0800 Subject: [PATCH] fix(gif): synchronize with master (#4003) --- src/extra/libs/gif/gifdec.c | 26 ++++++++++++++++++++++---- src/extra/libs/gif/gifdec.h | 2 +- src/extra/libs/gif/lv_gif.c | 17 ++++++++--------- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/extra/libs/gif/gifdec.c b/src/extra/libs/gif/gifdec.c index 68f50057e..3ee9b7194 100644 --- a/src/extra/libs/gif/gifdec.c +++ b/src/extra/libs/gif/gifdec.c @@ -160,6 +160,7 @@ static gd_GIF * gif_open(gd_GIF * gif_base) #endif } gif->anim_start = f_gif_seek(gif, 0, LV_FS_SEEK_CUR); + gif->loop_count = -1; goto ok; fail: f_gif_close(gif_base); @@ -239,6 +240,7 @@ read_application_ext(gd_GIF *gif) { char app_id[8]; char app_auth_code[3]; + uint16_t loop_count; /* Discard block size (always 0x0B). */ f_gif_seek(gif, 1, LV_FS_SEEK_CUR); @@ -249,7 +251,15 @@ read_application_ext(gd_GIF *gif) if (!strncmp(app_id, "NETSCAPE", sizeof(app_id))) { /* Discard block size (0x03) and constant byte (0x01). */ f_gif_seek(gif, 2, LV_FS_SEEK_CUR); - gif->loop_count = read_num(gif); + loop_count = read_num(gif); + if(gif->loop_count < 0) { + if(loop_count == 0) { + gif->loop_count = 0; + } + else{ + gif->loop_count = loop_count + 1; + } + } /* Skip block terminator. */ f_gif_seek(gif, 1, LV_FS_SEEK_CUR); } else if (gif->application) { @@ -568,9 +578,16 @@ gd_get_frame(gd_GIF *gif) dispose(gif); f_gif_read(gif, &sep, 1); while (sep != ',') { - if (sep == ';') - return 0; - if (sep == '!') + if (sep == ';') { + f_gif_seek(gif, gif->anim_start, LV_FS_SEEK_SET); + if(gif->loop_count == 1 || gif->loop_count < 0) { + return 0; + } + else if(gif->loop_count > 1) { + gif->loop_count--; + } + } + else if (sep == '!') read_ext(gif); else return -1; f_gif_read(gif, &sep, 1); @@ -598,6 +615,7 @@ gd_render_frame(gd_GIF *gif, uint8_t *buffer) void gd_rewind(gd_GIF *gif) { + gif->loop_count = -1; f_gif_seek(gif, gif->anim_start, LV_FS_SEEK_SET); } diff --git a/src/extra/libs/gif/gifdec.h b/src/extra/libs/gif/gifdec.h index 00f17c1da..b68fab5d4 100644 --- a/src/extra/libs/gif/gifdec.h +++ b/src/extra/libs/gif/gifdec.h @@ -29,7 +29,7 @@ typedef struct gd_GIF { int32_t anim_start; uint16_t width, height; uint16_t depth; - uint16_t loop_count; + int32_t loop_count; gd_GCE gce; gd_Palette *palette; gd_Palette lct, gct; diff --git a/src/extra/libs/gif/lv_gif.c b/src/extra/libs/gif/lv_gif.c index 4cb2955e2..2bd9e013c 100644 --- a/src/extra/libs/gif/lv_gif.c +++ b/src/extra/libs/gif/lv_gif.c @@ -99,6 +99,8 @@ void lv_gif_restart(lv_obj_t * obj) { lv_gif_t * gifobj = (lv_gif_t *) obj; gd_rewind(gifobj->gif); + lv_timer_resume(gifobj->timer); + lv_timer_reset(gifobj->timer); } /********************** @@ -111,6 +113,7 @@ static void lv_gif_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_gif_t * gifobj = (lv_gif_t *) obj; + gifobj->gif = NULL; gifobj->timer = lv_timer_create(next_frame_task_cb, 10, obj); lv_timer_pause(gifobj->timer); } @@ -120,7 +123,8 @@ static void lv_gif_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) LV_UNUSED(class_p); lv_gif_t * gifobj = (lv_gif_t *) obj; lv_img_cache_invalidate_src(&gifobj->imgdsc); - gd_close_gif(gifobj->gif); + if(gifobj->gif) + gd_close_gif(gifobj->gif); lv_timer_del(gifobj->timer); } @@ -136,14 +140,9 @@ static void next_frame_task_cb(lv_timer_t * t) int has_next = gd_get_frame(gifobj->gif); if(has_next == 0) { /*It was the last repeat*/ - if(gifobj->gif->loop_count == 1) { - lv_res_t res = lv_event_send(obj, LV_EVENT_READY, NULL); - if(res != LV_FS_RES_OK) return; - } - else { - if(gifobj->gif->loop_count > 1) gifobj->gif->loop_count--; - gd_rewind(gifobj->gif); - } + lv_res_t res = lv_event_send(obj, LV_EVENT_READY, NULL); + lv_timer_pause(t); + if(res != LV_FS_RES_OK) return; } gd_render_frame(gifobj->gif, (uint8_t *)gifobj->imgdsc.data);