1 /**
2 * @file lv_gifenc.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_gif.h"
10 #if LV_USE_GIF
11
12 #include "gifdec.h"
13
14 /*********************
15 * DEFINES
16 *********************/
17 #define MY_CLASS &lv_gif_class
18
19 /**********************
20 * TYPEDEFS
21 **********************/
22
23
24 /**********************
25 * STATIC PROTOTYPES
26 **********************/
27 static void lv_gif_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
28 static void lv_gif_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
29 static void next_frame_task_cb(lv_timer_t * t);
30
31 /**********************
32 * STATIC VARIABLES
33 **********************/
34 const lv_obj_class_t lv_gif_class = {
35 .constructor_cb = lv_gif_constructor,
36 .destructor_cb = lv_gif_destructor,
37 .instance_size = sizeof(lv_gif_t),
38 .base_class = &lv_img_class
39 };
40
41 /**********************
42 * MACROS
43 **********************/
44
45 /**********************
46 * GLOBAL FUNCTIONS
47 **********************/
48
lv_gif_create(lv_obj_t * parent)49 lv_obj_t * lv_gif_create(lv_obj_t * parent)
50 {
51
52 LV_LOG_INFO("begin");
53 lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);
54 lv_obj_class_init_obj(obj);
55 return obj;
56 }
57
lv_gif_set_src(lv_obj_t * obj,const void * src)58 void lv_gif_set_src(lv_obj_t * obj, const void * src)
59 {
60 lv_gif_t * gifobj = (lv_gif_t *) obj;
61
62 /*Close previous gif if any*/
63 if(gifobj->gif) {
64 lv_img_cache_invalidate_src(&gifobj->imgdsc);
65 gd_close_gif(gifobj->gif);
66 gifobj->gif = NULL;
67 gifobj->imgdsc.data = NULL;
68 }
69
70 if(lv_img_src_get_type(src) == LV_IMG_SRC_VARIABLE) {
71 const lv_img_dsc_t * img_dsc = src;
72 gifobj->gif = gd_open_gif_data(img_dsc->data);
73 }
74 else if(lv_img_src_get_type(src) == LV_IMG_SRC_FILE) {
75 gifobj->gif = gd_open_gif_file(src);
76 }
77 if(gifobj->gif == NULL) {
78 LV_LOG_WARN("Could't load the source");
79 return;
80 }
81
82 gifobj->imgdsc.data = gifobj->gif->canvas;
83 gifobj->imgdsc.header.always_zero = 0;
84 gifobj->imgdsc.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
85 gifobj->imgdsc.header.h = gifobj->gif->height;
86 gifobj->imgdsc.header.w = gifobj->gif->width;
87 gifobj->last_call = lv_tick_get();
88
89 lv_img_set_src(obj, &gifobj->imgdsc);
90
91 lv_timer_resume(gifobj->timer);
92 lv_timer_reset(gifobj->timer);
93
94 next_frame_task_cb(gifobj->timer);
95
96 }
97
lv_gif_restart(lv_obj_t * obj)98 void lv_gif_restart(lv_obj_t * obj)
99 {
100 lv_gif_t * gifobj = (lv_gif_t *) obj;
101 gd_rewind(gifobj->gif);
102 }
103
104 /**********************
105 * STATIC FUNCTIONS
106 **********************/
107
lv_gif_constructor(const lv_obj_class_t * class_p,lv_obj_t * obj)108 static void lv_gif_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
109 {
110 LV_UNUSED(class_p);
111
112 lv_gif_t * gifobj = (lv_gif_t *) obj;
113
114 gifobj->timer = lv_timer_create(next_frame_task_cb, 10, obj);
115 lv_timer_pause(gifobj->timer);
116 }
117
lv_gif_destructor(const lv_obj_class_t * class_p,lv_obj_t * obj)118 static void lv_gif_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
119 {
120 LV_UNUSED(class_p);
121 lv_gif_t * gifobj = (lv_gif_t *) obj;
122 lv_img_cache_invalidate_src(&gifobj->imgdsc);
123 gd_close_gif(gifobj->gif);
124 lv_timer_del(gifobj->timer);
125 }
126
next_frame_task_cb(lv_timer_t * t)127 static void next_frame_task_cb(lv_timer_t * t)
128 {
129 lv_obj_t * obj = t->user_data;
130 lv_gif_t * gifobj = (lv_gif_t *) obj;
131 uint32_t elaps = lv_tick_elaps(gifobj->last_call);
132 if(elaps < gifobj->gif->gce.delay * 10) return;
133
134 gifobj->last_call = lv_tick_get();
135
136 int has_next = gd_get_frame(gifobj->gif);
137 if(has_next == 0) {
138 /*It was the last repeat*/
139 if(gifobj->gif->loop_count == 1) {
140 lv_res_t res = lv_event_send(obj, LV_EVENT_READY, NULL);
141 if(res != LV_FS_RES_OK) return;
142 }
143 else {
144 if(gifobj->gif->loop_count > 1) gifobj->gif->loop_count--;
145 gd_rewind(gifobj->gif);
146 }
147 }
148
149 gd_render_frame(gifobj->gif, (uint8_t *)gifobj->imgdsc.data);
150
151 lv_img_cache_invalidate_src(lv_img_get_src(obj));
152 lv_obj_invalidate(obj);
153 }
154
155 #endif /*LV_USE_GIF*/
156