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