diff --git a/src/libs/gif/gifdec.c b/src/libs/gif/gifdec.c index 92ce6e010..88e8ac02f 100644 --- a/src/libs/gif/gifdec.c +++ b/src/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); @@ -240,6 +241,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); @@ -250,7 +252,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); } @@ -576,10 +586,17 @@ gd_get_frame(gd_GIF * gif) dispose(gif); f_gif_read(gif, &sep, 1); - while(sep != ',') { - if(sep == ';') - return 0; - if(sep == '!') + while (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); @@ -607,6 +624,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/libs/gif/gifdec.h b/src/libs/gif/gifdec.h index 223efec01..378ea24aa 100644 --- a/src/libs/gif/gifdec.h +++ b/src/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/libs/gif/lv_gif.c b/src/libs/gif/lv_gif.c index 51b152440..99cb7ec1f 100644 --- a/src/libs/gif/lv_gif.c +++ b/src/libs/gif/lv_gif.c @@ -113,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); } @@ -122,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); } @@ -138,15 +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); - lv_timer_pause(t); - 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);