From ff330b0f422c314f0a1337ac623ac97b3113e8c7 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 14 Apr 2021 17:04:24 +0200 Subject: [PATCH] feat(img_decoder) add frame_id parameter to the image decoder Related to #2090 --- src/draw/lv_draw_img.c | 2 +- src/draw/lv_draw_img.h | 9 +++++---- src/draw/lv_img_cache.c | 5 +++-- src/draw/lv_img_cache.h | 3 ++- src/draw/lv_img_decoder.c | 27 ++++++++------------------- src/draw/lv_img_decoder.h | 8 ++++++-- 6 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/draw/lv_draw_img.c b/src/draw/lv_draw_img.c index 8209575bd..7e2ad93e3 100644 --- a/src/draw/lv_draw_img.c +++ b/src/draw/lv_draw_img.c @@ -236,7 +236,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords, { if(draw_dsc->opa <= LV_OPA_MIN) return LV_RES_OK; - lv_img_cache_entry_t * cdsc = _lv_img_cache_open(src, draw_dsc->recolor); + lv_img_cache_entry_t * cdsc = _lv_img_cache_open(src, draw_dsc->recolor, draw_dsc->frame_id); if(cdsc == NULL) return LV_RES_INV; diff --git a/src/draw/lv_draw_img.h b/src/draw/lv_draw_img.h index 894e91fc4..3608bc00e 100644 --- a/src/draw/lv_draw_img.h +++ b/src/draw/lv_draw_img.h @@ -30,17 +30,18 @@ extern "C" { **********************/ typedef struct { - lv_opa_t opa; uint16_t angle; - lv_point_t pivot; uint16_t zoom; + lv_point_t pivot; - lv_opa_t recolor_opa; lv_color_t recolor; + lv_opa_t recolor_opa; - lv_blend_mode_t blend_mode; + lv_opa_t opa; + lv_blend_mode_t blend_mode : 4; + int32_t frame_id; uint8_t antialias : 1; } lv_draw_img_dsc_t; diff --git a/src/draw/lv_img_cache.c b/src/draw/lv_img_cache.c index 167bea282..587d9631d 100644 --- a/src/draw/lv_img_cache.c +++ b/src/draw/lv_img_cache.c @@ -60,7 +60,7 @@ * @param color color The color of the image with `LV_IMG_CF_ALPHA_...` * @return pointer to the cache entry or NULL if can open the image */ -lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color) +lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color, int32_t frame_id) { /*Is the image cached?*/ lv_img_cache_entry_t * cached_src = NULL; @@ -83,6 +83,7 @@ lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color) for(i = 0; i < entry_cnt; i++) { if(color.full == cache[i].dec_dsc.color.full && + frame_id == cache[i].dec_dsc.frame_id && lv_img_cache_match(src, cache[i].dec_dsc.src)) { /*If opened increment its life. *Image difficult to open should live longer to keep avoid frequent their recaching. @@ -119,7 +120,7 @@ lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color) #endif /*Open the image and measure the time to open*/ uint32_t t_start = lv_tick_get(); - lv_res_t open_res = lv_img_decoder_open(&cached_src->dec_dsc, src, color); + lv_res_t open_res = lv_img_decoder_open(&cached_src->dec_dsc, src, color, frame_id); if(open_res == LV_RES_INV) { LV_LOG_WARN("Image draw cannot open the image resource"); lv_memset_00(cached_src, sizeof(lv_img_cache_entry_t)); diff --git a/src/draw/lv_img_cache.h b/src/draw/lv_img_cache.h index 3846f6b42..588d01519 100644 --- a/src/draw/lv_img_cache.h +++ b/src/draw/lv_img_cache.h @@ -47,9 +47,10 @@ typedef struct { * The image is closed if a new image is opened and the new image takes its place in the cache. * @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable * @param color The color of the image with `LV_IMG_CF_ALPHA_...` + * @param frame_id the index of the frame. Used only with animated images, set 0 for normal images * @return pointer to the cache entry or NULL if can open the image */ -lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color); +lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color, int32_t frame_id); /** * Set the number of images to be cached. diff --git a/src/draw/lv_img_decoder.c b/src/draw/lv_img_decoder.c index 6fa0b0318..4040a1f2c 100644 --- a/src/draw/lv_img_decoder.c +++ b/src/draw/lv_img_decoder.c @@ -95,24 +95,13 @@ lv_res_t lv_img_decoder_get_info(const void * src, lv_img_header_t * header) return res; } -/** - * Open an image. - * Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc` - * @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable. - * @param src the image source. Can be - * 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`) - * 2) Variable: Pointer to an `lv_img_dsc_t` variable - * 3) Symbol: E.g. `LV_SYMBOL_OK` - * @param color The color of the image with `LV_IMG_CF_ALPHA_...` - * @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set. - * LV_RES_INV: none of the registered image decoders were able to open the image. - */ -lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_color_t color) +lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_color_t color, int32_t frame_id) { lv_memset_00(dsc, sizeof(lv_img_decoder_dsc_t)); dsc->color = color; dsc->src_type = lv_img_src_get_type(src); + dsc->frame_id = frame_id; if(dsc->src_type == LV_IMG_SRC_FILE) { size_t fnlen = strlen(src); @@ -130,16 +119,16 @@ lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_co lv_res_t res = LV_RES_INV; - lv_img_decoder_t * d; - _LV_LL_READ(&LV_GC_ROOT(_lv_img_decoder_ll), d) { + lv_img_decoder_t * decoder; + _LV_LL_READ(&LV_GC_ROOT(_lv_img_decoder_ll), decoder) { /*Info and Open callbacks are required*/ - if(d->info_cb == NULL || d->open_cb == NULL) continue; + if(decoder->info_cb == NULL || decoder->open_cb == NULL) continue; - res = d->info_cb(d, src, &dsc->header); + res = decoder->info_cb(decoder, src, &dsc->header); if(res != LV_RES_OK) continue; - dsc->decoder = d; - res = d->open_cb(d, dsc); + dsc->decoder = decoder; + res = decoder->open_cb(decoder, dsc); /*Opened successfully. It is a good decoder to for this image source*/ if(res == LV_RES_OK) return res; diff --git a/src/draw/lv_img_decoder.h b/src/draw/lv_img_decoder.h index b06900067..6c852eae4 100644 --- a/src/draw/lv_img_decoder.h +++ b/src/draw/lv_img_decoder.h @@ -102,9 +102,12 @@ typedef struct _lv_img_decoder_dsc { /**The image source. A file path like "S:my_img.png" or pointer to an `lv_img_dsc_t` variable*/ const void * src; - /**Style to draw the image.*/ + /**Color to draw the image. USed when the image has alpha channel only*/ lv_color_t color; + /**Frame of the image, using with animated images*/ + int32_t frame_id; + /**Type of the source: file or variable. Can be set in `open` function if required*/ lv_img_src_t src_type; @@ -157,10 +160,11 @@ lv_res_t lv_img_decoder_get_info(const void * src, lv_img_header_t * header); * 2) Variable: Pointer to an `lv_img_dsc_t` variable * 3) Symbol: E.g. `LV_SYMBOL_OK` * @param color The color of the image with `LV_IMG_CF_ALPHA_...` + * @param frame_id the index of the frame. Used only with animated images, set 0 for normal images * @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set. * LV_RES_INV: none of the registered image decoders were able to open the image. */ -lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_color_t color); +lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_color_t color, int32_t frame_id); /** * Read a line from an opened image