mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
feat(bin_decoder) do not add image to cache if can be used directly (#5162)
Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
parent
7963ffbe9c
commit
aba8c3e0d4
@ -70,7 +70,6 @@ static lv_fs_res_t fs_read_file_at(lv_fs_file_t * f, uint32_t pos, void * buff,
|
|||||||
|
|
||||||
static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image_compressed_t * compressed);
|
static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image_compressed_t * compressed);
|
||||||
|
|
||||||
static bool bin_decoder_decode_data(lv_image_decoder_dsc_t * dsc);
|
|
||||||
static void bin_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data);
|
static void bin_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
@ -173,8 +172,118 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
|||||||
LV_UNUSED(decoder);
|
LV_UNUSED(decoder);
|
||||||
LV_UNUSED(args);
|
LV_UNUSED(args);
|
||||||
|
|
||||||
bool create_res = bin_decoder_decode_data(dsc);
|
lv_fs_res_t res = LV_RESULT_INVALID;
|
||||||
if(create_res == false) return LV_RESULT_INVALID;
|
bool use_directly = false; /*If the image is already decoded and can be used directly*/
|
||||||
|
|
||||||
|
/*Open the file if it's a file*/
|
||||||
|
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
|
||||||
|
/*Support only "*.bin" files*/
|
||||||
|
if(lv_strcmp(lv_fs_get_ext(dsc->src), "bin")) return LV_RESULT_INVALID;
|
||||||
|
|
||||||
|
/*If the file was open successfully save the file descriptor*/
|
||||||
|
decoder_data_t * decoder_data = get_decoder_data(dsc);
|
||||||
|
if(decoder_data == NULL) {
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
dsc->user_data = decoder_data;
|
||||||
|
lv_fs_file_t * f = lv_malloc(sizeof(*f));
|
||||||
|
if(f == NULL) {
|
||||||
|
free_decoder_data(dsc);
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = lv_fs_open(f, dsc->src, LV_FS_MODE_RD);
|
||||||
|
if(res != LV_FS_RES_OK) {
|
||||||
|
LV_LOG_WARN("Open file failed: %d", res);
|
||||||
|
lv_free(f);
|
||||||
|
free_decoder_data(dsc);
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder_data->f = f; /*Now free_decoder_data will take care of the file*/
|
||||||
|
|
||||||
|
lv_color_format_t cf = dsc->header.cf;
|
||||||
|
|
||||||
|
if(dsc->header.flags & LV_IMAGE_FLAGS_COMPRESSED) {
|
||||||
|
res = decode_compressed(decoder, dsc);
|
||||||
|
}
|
||||||
|
else if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
|
||||||
|
/*Palette for indexed image and whole image of A8 image are always loaded to RAM for simplicity*/
|
||||||
|
res = decode_indexed(decoder, dsc);
|
||||||
|
}
|
||||||
|
else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf)) {
|
||||||
|
res = decode_alpha_only(decoder, dsc);
|
||||||
|
}
|
||||||
|
#if LV_BIN_DECODER_RAM_LOAD
|
||||||
|
else if(cf == LV_COLOR_FORMAT_ARGB8888 \
|
||||||
|
|| cf == LV_COLOR_FORMAT_XRGB8888 \
|
||||||
|
|| cf == LV_COLOR_FORMAT_RGB888 \
|
||||||
|
|| cf == LV_COLOR_FORMAT_RGB565 \
|
||||||
|
|| cf == LV_COLOR_FORMAT_RGB565A8) {
|
||||||
|
res = decode_rgb(decoder, dsc);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
else {
|
||||||
|
/* decode them in get_area_cb */
|
||||||
|
res = LV_RESULT_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(dsc->src_type == LV_IMAGE_SRC_VARIABLE) {
|
||||||
|
/*The variables should have valid data*/
|
||||||
|
lv_image_dsc_t * image = (lv_image_dsc_t *)dsc->src;
|
||||||
|
if(image->data == NULL) {
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_color_format_t cf = image->header.cf;
|
||||||
|
if(dsc->header.flags & LV_IMAGE_FLAGS_COMPRESSED) {
|
||||||
|
res = decode_compressed(decoder, dsc);
|
||||||
|
}
|
||||||
|
else if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
|
||||||
|
/*Need decoder data to store converted image*/
|
||||||
|
decoder_data_t * decoder_data = get_decoder_data(dsc);
|
||||||
|
if(decoder_data == NULL) {
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = decode_indexed(decoder, dsc);
|
||||||
|
}
|
||||||
|
else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf)) {
|
||||||
|
/*Alpha only image will need decoder data to store pointer to decoded image, to free it when decoder closes*/
|
||||||
|
decoder_data_t * decoder_data = get_decoder_data(dsc);
|
||||||
|
if(decoder_data == NULL) {
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = decode_alpha_only(decoder, dsc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*In case of uncompressed formats the image stored in the ROM/RAM.
|
||||||
|
*So simply give its pointer*/
|
||||||
|
|
||||||
|
decoder_data_t * decoder_data = get_decoder_data(dsc);
|
||||||
|
lv_draw_buf_t * decoded = &decoder_data->c_array;
|
||||||
|
dsc->decoded = decoded;
|
||||||
|
lv_draw_buf_from_image(decoded, image);
|
||||||
|
|
||||||
|
if(decoded->header.stride == 0) {
|
||||||
|
/*Use the auto calculated value from decoder_info callback*/
|
||||||
|
decoded->header.stride = dsc->header.stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = LV_RESULT_OK;
|
||||||
|
use_directly = true; /*A variable image that can be used directly.*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res != LV_RESULT_OK) {
|
||||||
|
free_decoder_data(dsc);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
if(dsc->decoded == NULL) return LV_RESULT_OK; /*Need to read via get_area_cb*/
|
if(dsc->decoded == NULL) return LV_RESULT_OK; /*Need to read via get_area_cb*/
|
||||||
|
|
||||||
lv_draw_buf_t * decoded = (lv_draw_buf_t *)dsc->decoded;
|
lv_draw_buf_t * decoded = (lv_draw_buf_t *)dsc->decoded;
|
||||||
@ -186,12 +295,15 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
|||||||
|
|
||||||
/*The adjusted draw buffer is newly allocated.*/
|
/*The adjusted draw buffer is newly allocated.*/
|
||||||
if(adjusted != decoded) {
|
if(adjusted != decoded) {
|
||||||
|
use_directly = false; /*Cannot use original image directly*/
|
||||||
free_decoder_data(dsc);
|
free_decoder_data(dsc);
|
||||||
decoder_data_t * decoder_data = get_decoder_data(dsc);
|
decoder_data_t * decoder_data = get_decoder_data(dsc);
|
||||||
decoder_data->decoded = adjusted; /*Now this new buffer need to be free'd on decoder close*/
|
decoder_data->decoded = adjusted; /*Now this new buffer need to be free'd on decoder close*/
|
||||||
}
|
}
|
||||||
dsc->decoded = adjusted;
|
dsc->decoded = adjusted;
|
||||||
|
|
||||||
|
if(use_directly) return LV_RESULT_OK; /*Do not put image to cache if it can be used directly.*/
|
||||||
|
|
||||||
#if LV_CACHE_DEF_SIZE > 0
|
#if LV_CACHE_DEF_SIZE > 0
|
||||||
|
|
||||||
/*Add it to cache*/
|
/*Add it to cache*/
|
||||||
@ -899,123 +1011,6 @@ static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image
|
|||||||
return LV_RESULT_OK;
|
return LV_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool bin_decoder_decode_data(lv_image_decoder_dsc_t * dsc)
|
|
||||||
{
|
|
||||||
lv_image_decoder_t * decoder = dsc->decoder;
|
|
||||||
|
|
||||||
lv_fs_res_t res = LV_RESULT_INVALID;
|
|
||||||
|
|
||||||
/*Open the file if it's a file*/
|
|
||||||
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
|
|
||||||
/*Support only "*.bin" files*/
|
|
||||||
if(lv_strcmp(lv_fs_get_ext(dsc->src), "bin")) return false;
|
|
||||||
|
|
||||||
/*If the file was open successfully save the file descriptor*/
|
|
||||||
decoder_data_t * decoder_data = get_decoder_data(dsc);
|
|
||||||
if(decoder_data == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dsc->user_data = decoder_data;
|
|
||||||
lv_fs_file_t * f = lv_malloc(sizeof(*f));
|
|
||||||
if(f == NULL) {
|
|
||||||
free_decoder_data(dsc);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = lv_fs_open(f, dsc->src, LV_FS_MODE_RD);
|
|
||||||
if(res != LV_FS_RES_OK) {
|
|
||||||
LV_LOG_WARN("Open file failed: %d", res);
|
|
||||||
lv_free(f);
|
|
||||||
free_decoder_data(dsc);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
decoder_data->f = f; /*Now free_decoder_data will take care of the file*/
|
|
||||||
|
|
||||||
lv_color_format_t cf = dsc->header.cf;
|
|
||||||
|
|
||||||
if(dsc->header.flags & LV_IMAGE_FLAGS_COMPRESSED) {
|
|
||||||
res = decode_compressed(decoder, dsc);
|
|
||||||
}
|
|
||||||
else if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
|
|
||||||
/*Palette for indexed image and whole image of A8 image are always loaded to RAM for simplicity*/
|
|
||||||
res = decode_indexed(decoder, dsc);
|
|
||||||
}
|
|
||||||
else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf)) {
|
|
||||||
res = decode_alpha_only(decoder, dsc);
|
|
||||||
}
|
|
||||||
#if LV_BIN_DECODER_RAM_LOAD
|
|
||||||
else if(cf == LV_COLOR_FORMAT_ARGB8888 \
|
|
||||||
|| cf == LV_COLOR_FORMAT_XRGB8888 \
|
|
||||||
|| cf == LV_COLOR_FORMAT_RGB888 \
|
|
||||||
|| cf == LV_COLOR_FORMAT_RGB565 \
|
|
||||||
|| cf == LV_COLOR_FORMAT_RGB565A8) {
|
|
||||||
res = decode_rgb(decoder, dsc);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
else {
|
|
||||||
/* decode them in get_area_cb */
|
|
||||||
res = LV_RESULT_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(dsc->src_type == LV_IMAGE_SRC_VARIABLE) {
|
|
||||||
/*The variables should have valid data*/
|
|
||||||
lv_image_dsc_t * image = (lv_image_dsc_t *)dsc->src;
|
|
||||||
if(image->data == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_color_format_t cf = image->header.cf;
|
|
||||||
if(dsc->header.flags & LV_IMAGE_FLAGS_COMPRESSED) {
|
|
||||||
res = decode_compressed(decoder, dsc);
|
|
||||||
}
|
|
||||||
else if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
|
|
||||||
/*Need decoder data to store converted image*/
|
|
||||||
decoder_data_t * decoder_data = get_decoder_data(dsc);
|
|
||||||
if(decoder_data == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = decode_indexed(decoder, dsc);
|
|
||||||
}
|
|
||||||
else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf)) {
|
|
||||||
/*Alpha only image will need decoder data to store pointer to decoded image, to free it when decoder closes*/
|
|
||||||
decoder_data_t * decoder_data = get_decoder_data(dsc);
|
|
||||||
if(decoder_data == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = decode_alpha_only(decoder, dsc);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*In case of uncompressed formats the image stored in the ROM/RAM.
|
|
||||||
*So simply give its pointer*/
|
|
||||||
|
|
||||||
decoder_data_t * decoder_data = get_decoder_data(dsc);
|
|
||||||
lv_draw_buf_t * decoded = &decoder_data->c_array;
|
|
||||||
dsc->decoded = decoded;
|
|
||||||
lv_draw_buf_from_image(decoded, image);
|
|
||||||
|
|
||||||
if(decoded->header.stride == 0) {
|
|
||||||
/*Use the auto calculated value from decoder_info callback*/
|
|
||||||
decoded->header.stride = dsc->header.stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = LV_RESULT_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(res != LV_RESULT_OK) {
|
|
||||||
free_decoder_data(dsc);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bin_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data)
|
static void bin_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data)
|
||||||
{
|
{
|
||||||
LV_UNUSED(user_data); /*Unused*/
|
LV_UNUSED(user_data); /*Unused*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user