1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

feat(decoder): add decoder open args (#4834)

Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
Neo Xu 2023-11-22 02:30:31 +08:00 committed by GitHub
parent 534768ed27
commit 695f4e9247
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 94 additions and 33 deletions

View File

@ -343,7 +343,8 @@ to open is an animation.
lv_result_t res;
lv_image_decoder_dsc_t dsc;
res = lv_image_decoder_open(&dsc, &my_img_dsc, color, frame_id);
lv_image_decoder_args_t args = { 0 }; /*Custom decoder behavior via args*/
res = lv_image_decoder_open(&dsc, &my_img_dsc, &args);
if(res == LV_RESULT_OK) {
/*Do something with `dsc->img_data`*/
@ -457,7 +458,7 @@ See the detailed code below:
{
...
lv_image_decoder_dsc_t decoder_dsc;
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, draw_dsc->recolor, -1);
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, NULL);
if(res != LV_RESULT_OK) {
LV_LOG_ERROR("Failed to open image");
return;

View File

@ -90,9 +90,8 @@ lv_result_t lv_image_decoder_get_info(const void * src, lv_image_header_t * head
return res;
}
lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src, lv_color_t color, int32_t frame_id)
lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src, const lv_image_decoder_args_t * args)
{
LV_UNUSED(color);
lv_memzero(dsc, sizeof(lv_image_decoder_dsc_t));
if(src == NULL) return LV_RESULT_INVALID;
@ -103,7 +102,7 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src
}
dsc->src_type = src_type;
dsc->frame_id = frame_id;
if(args) dsc->frame_id = args->frame_id;
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
size_t fnlen = lv_strlen(src);
@ -122,6 +121,20 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src
lv_result_t res = LV_RESULT_INVALID;
lv_image_decoder_t * decoder;
lv_image_decoder_args_t * args_copy = NULL;
/*Make a copy of args */
if(args) {
args_copy = lv_malloc(sizeof(lv_image_decoder_args_t));
LV_ASSERT_MALLOC(args_copy);
if(args_copy == NULL) {
LV_LOG_WARN("Out of memory");
return LV_RESULT_INVALID;
}
lv_memcpy(args_copy, args, sizeof(lv_image_decoder_args_t));
dsc->args = args_copy;
}
_LV_LL_READ(img_decoder_ll_p, decoder) {
/*Info and Open callbacks are required*/
if(decoder->info_cb == NULL || decoder->open_cb == NULL) continue;
@ -132,7 +145,7 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src
if(dsc->header.stride == 0) dsc->header.stride = img_width_to_stride(&dsc->header);
dsc->decoder = decoder;
res = decoder->open_cb(decoder, dsc);
res = decoder->open_cb(decoder, dsc, args);
/*Opened successfully. It is a good decoder for this image source*/
if(res == LV_RESULT_OK) return res;
@ -150,6 +163,8 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src
if(dsc->src_type == LV_IMAGE_SRC_FILE)
lv_free((void *)dsc->src);
if(args_copy) lv_free(args_copy);
return res;
}
@ -178,6 +193,7 @@ void lv_image_decoder_close(lv_image_decoder_dsc_t * dsc)
{
if(dsc->decoder) {
if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc);
if(dsc->args) lv_free(dsc->args);
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
lv_free((void *)dsc->src);

View File

@ -49,6 +49,22 @@ struct _lv_image_decoder_dsc_t;
struct _lv_image_decoder_t;
struct _lv_cache_entry_t;
/**
* Image decoder args.
* It determines how to decoder an image, e.g. whether to premultiply the alpha or not.
* It should be passed to lv_img_decoder_open() function. If NULL is provided, default
* args are used.
*
* Default args:
* all field are zero or false.
*/
typedef struct _lv_image_decoder_args_t {
int32_t frame_id; /*A not use args*/
bool stride_align; /*Whether stride should be aligned*/
bool premultiply; /*Whether image should be premultiplied or not after decoding*/
bool no_cache; /*Whether this image should be kept out of cache*/
} lv_image_decoder_args_t;
/**
* Get info from an image and store in the `header`
* @param src the image source. Can be a pointer to a C array or a file name (Use
@ -63,9 +79,11 @@ typedef lv_result_t (*lv_image_decoder_info_f_t)(struct _lv_image_decoder_t * de
* Open an image for decoding. Prepare it as it is required to read it later
* @param decoder pointer to the decoder the function associated with
* @param dsc pointer to decoder descriptor. `src`, `color` are already initialized in it.
* @param args arguments of how to decode the image. see `lv_image_decoder_args_t`.
*/
typedef lv_result_t (*lv_image_decoder_open_f_t)(struct _lv_image_decoder_t * decoder,
struct _lv_image_decoder_dsc_t * dsc);
struct _lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args);
/**
* Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
@ -103,6 +121,9 @@ typedef struct _lv_image_decoder_dsc_t {
/**The decoder which was able to open the image source*/
lv_image_decoder_t * decoder;
/*A copy of parameters of how this image is decoded*/
lv_image_decoder_args_t * args;
/**The image source. A file path like "S:my_img.png" or pointer to an `lv_image_dsc_t` variable*/
const void * src;
@ -172,11 +193,11 @@ lv_result_t lv_image_decoder_get_info(const void * src, lv_image_header_t * head
* 2) Variable: Pointer to an `lv_image_dsc_t` variable
* 3) Symbol: E.g. `LV_SYMBOL_OK`
* @param color The color of the image with `LV_IMAGE_CF_ALPHA_...`
* @param frame_id the index of the frame. Used only with animated images, set 0 for normal images
* @param args args about how the image should be opened.
* @return LV_RESULT_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
* LV_RESULT_INVALID: none of the registered image decoders were able to open the image.
*/
lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src, lv_color_t color, int32_t frame_id);
lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src, const lv_image_decoder_args_t * args);
/**
* Decode an area of the opened image

View File

@ -124,7 +124,7 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c
}
else {
lv_image_decoder_dsc_t decoder_dsc;
lv_image_decoder_open(&decoder_dsc, dsc->img_src, dsc->color, 0);
lv_image_decoder_open(&decoder_dsc, dsc->img_src, NULL);
img_area.x1 = 0;
img_area.y1 = 0;
img_area.x2 = decoder_dsc.header.w - 1;

View File

@ -195,7 +195,7 @@ static void img_draw_normal(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_
}
lv_image_decoder_dsc_t decoder_dsc;
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, draw_dsc->recolor, -1);
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, NULL);
if(res != LV_RESULT_OK) {
LV_LOG_ERROR("Failed to open image");
return;
@ -210,7 +210,7 @@ static void img_draw_tiled(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
const lv_area_t * coords)
{
lv_image_decoder_dsc_t decoder_dsc;
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, draw_dsc->recolor, -1);
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, NULL);
if(res != LV_RESULT_OK) {
LV_LOG_ERROR("Failed to open image");
return;

View File

@ -291,7 +291,7 @@ static void _set_paint_fill_pattern(Tvg_Paint * obj, Tvg_Canvas * canvas, const
const lv_matrix_t * m)
{
lv_image_decoder_dsc_t decoder_dsc;
lv_result_t res = lv_image_decoder_open(&decoder_dsc, p->src, p->recolor, -1);
lv_result_t res = lv_image_decoder_open(&decoder_dsc, p->src, NULL);
if(res != LV_RESULT_OK) {
LV_LOG_ERROR("Failed to open image");
return;

View File

@ -134,11 +134,14 @@ lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, const void * src,
* Open a lvgl binary image
* @param decoder the decoder where this function belongs
* @param dsc pointer to decoder descriptor. `src`, `color` are already initialized in it.
* @param args arguments of how to decode the image.
* @return LV_RESULT_OK: the info is successfully stored in `header`; LV_RESULT_INVALID: unknown format or other error.
*/
lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args)
{
LV_UNUSED(decoder);
LV_UNUSED(args);
lv_fs_res_t res = LV_RESULT_INVALID;
/*Open the file if it's a file*/

View File

@ -50,7 +50,8 @@ lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod
* @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.
* @return LV_RESULT_OK: the info is successfully stored in `header`; LV_RESULT_INVALID: unknown format or other error.
*/
lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args);
/**
* Close the pending decoding. Free resources etc.

View File

@ -32,7 +32,8 @@ typedef struct {
* STATIC PROTOTYPES
**********************/
static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header);
static lv_result_t decoder_open(lv_image_decoder_t * dec, lv_image_decoder_dsc_t * dsc);
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args);
static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_area_t * full_area, lv_area_t * decoded_area);
@ -139,9 +140,11 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src,
* @param style style of the image object (unused now but certain formats might use it)
* @return pointer to the decoded image or `LV_IMAGE_DECODER_OPEN_FAIL` if failed
*/
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args)
{
LV_UNUSED(decoder);
LV_UNUSED(args);
/*If it's a PNG file...*/
if(dsc->src_type == LV_IMAGE_SRC_FILE) {

View File

@ -66,7 +66,8 @@ struct lv_image_pixel_color_s {
**********************/
static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header);
static lv_result_t decoder_open(lv_image_decoder_t * dec, lv_image_decoder_dsc_t * dsc);
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args);
static void decoder_close(lv_image_decoder_t * dec, lv_image_decoder_dsc_t * dsc);
static struct ffmpeg_context_s * ffmpeg_open_file(const char * path);
@ -268,9 +269,11 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src,
return LV_RESULT_INVALID;
}
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args)
{
LV_UNUSED(decoder);
LV_UNUSED(args);
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
const char * path = dsc->src;

View File

@ -33,7 +33,8 @@ typedef struct error_mgr_s {
* STATIC PROTOTYPES
**********************/
static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header);
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args);
static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
static const void * decode_jpeg_file(const char * filename);
static bool get_jpeg_size(const char * filename, uint32_t * width, uint32_t * height);
@ -146,9 +147,11 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src,
* @param style style of the image object (unused now but certain formats might use it)
* @return pointer to the decoded image or `LV_IMAGE_DECODER_OPEN_FAIL` if failed
*/
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args)
{
LV_UNUSED(decoder); /*Unused*/
LV_UNUSED(args); /*Unused*/
/*Check the cache first*/
if(try_cache(dsc) == LV_RESULT_OK) return LV_RESULT_OK;

View File

@ -24,7 +24,8 @@
* STATIC PROTOTYPES
**********************/
static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header);
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args);
static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
static const void * decode_png_file(const char * filename);
static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc);
@ -121,9 +122,11 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src,
* @param style style of the image object (unused now but certain formats might use it)
* @return pointer to the decoded image or `LV_IMAGE_DECODER_OPEN_FAIL` if failed
*/
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args)
{
LV_UNUSED(decoder); /*Unused*/
LV_UNUSED(args); /*Unused*/
/*Check the cache first*/
if(try_cache(dsc) == LV_RESULT_OK) return LV_RESULT_OK;

View File

@ -28,7 +28,8 @@ typedef struct {
* STATIC PROTOTYPES
**********************/
static lv_result_t decoder_info(struct _lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header);
static lv_result_t decoder_open(lv_image_decoder_t * dec, lv_image_decoder_dsc_t * dsc);
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args);
static void decoder_close(lv_image_decoder_t * dec, lv_image_decoder_dsc_t * dsc);
static void convert_color_depth(uint8_t * img_p, uint32_t px_cnt);
static const void * decode_png_data(const void * png_data, size_t png_data_size);
@ -154,9 +155,11 @@ static lv_result_t decoder_info(struct _lv_image_decoder_t * decoder, const void
* @param dsc decoded image descriptor
* @return LV_RESULT_OK: no error; LV_RESULT_INVALID: can't open the image
*/
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args)
{
(void) decoder; /*Unused*/
LV_UNUSED(decoder);
LV_UNUSED(args);
/*Check the cache first*/
if(try_cache(dsc) == LV_RESULT_OK) return LV_RESULT_OK;

View File

@ -53,8 +53,8 @@ typedef struct {
**********************/
static lv_res_t decoder_info(struct _lv_image_decoder_t * decoder,
const void * src, lv_image_header_t * header);
static lv_res_t decoder_open(lv_image_decoder_t * dec,
lv_image_decoder_dsc_t * dsc);
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args);
static void decoder_close(lv_image_decoder_t * dec, lv_image_decoder_dsc_t * dsc);
/**********************
@ -452,9 +452,10 @@ static inline lv_res_t decode_from_variable(lv_image_decoder_t * decoder,
return LV_RES_OK;
}
static lv_res_t decoder_open(lv_image_decoder_t * decoder,
lv_image_decoder_dsc_t * dsc)
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args)
{
LV_UNUSED(args);
lv_fs_res_t res;
lv_rle_file_header_t fileheader;
lv_rle_decoder_data_t * data;
@ -491,7 +492,7 @@ static lv_res_t decoder_open(lv_image_decoder_t * decoder,
data->decoder_dsc.src_type = LV_IMAGE_SRC_VARIABLE;
data->decoder_dsc.src = &data->img_dsc;
res = lv_bin_decoder_open(decoder, &data->decoder_dsc);
res = lv_bin_decoder_open(decoder, &data->decoder_dsc, dsc->args);
if(res != LV_RES_OK) {
lv_free(img_data);
lv_free(data);

View File

@ -27,7 +27,8 @@
* STATIC PROTOTYPES
**********************/
static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header);
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args);
static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_area_t * full_area, lv_area_t * decoded_area);
@ -142,9 +143,11 @@ static size_t input_func(JDEC * jd, uint8_t * buff, size_t ndata)
return 0;
}
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
const lv_image_decoder_args_t * args)
{
LV_UNUSED(decoder);
LV_UNUSED(args);
lv_fs_file_t * f = lv_malloc(sizeof(lv_fs_file_t));
if(dsc->src_type == LV_IMAGE_SRC_VARIABLE) {
#if LV_USE_FS_MEMFS