acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

lv_gif.c (3884B)

      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 
     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 
     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 
     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 
    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 
    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 
    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*/