feat(decoder): remove img_data and use decoded draw buffer instead (#4985)
Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
@@ -258,7 +258,7 @@ open/close the PNG files. It should look like this:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a PNG image and decode it into dsc.img_data
|
* Open a PNG image and decode it into dsc.decoded
|
||||||
* @param decoder pointer to the decoder where this function belongs
|
* @param decoder pointer to the decoder where this function belongs
|
||||||
* @param dsc image descriptor
|
* @param dsc image descriptor
|
||||||
* @return LV_RESULT_OK: no error; LV_RESULT_INVALID: can't open the image
|
* @return LV_RESULT_OK: no error; LV_RESULT_INVALID: can't open the image
|
||||||
@@ -270,11 +270,11 @@ open/close the PNG files. It should look like this:
|
|||||||
/*Check whether the type `src` is known by the decoder*/
|
/*Check whether the type `src` is known by the decoder*/
|
||||||
if(is_png(dsc->src) == false) return LV_RESULT_INVALID;
|
if(is_png(dsc->src) == false) return LV_RESULT_INVALID;
|
||||||
|
|
||||||
/*Decode and store the image. If `dsc->img_data` is `NULL`, the `read_line` function will be called to get the image data line-by-line*/
|
/*Decode and store the image. If `dsc->decoded` is `NULL`, the `read_line` function will be called to get the image data line-by-line*/
|
||||||
dsc->img_data = my_png_decoder(dsc->src);
|
dsc->decoded = my_png_decoder(dsc->src);
|
||||||
|
|
||||||
/*Change the color format if required. For PNG usually 'Raw' is fine*/
|
/*Change the color format if decoded image format is different than original format. For PNG it's usually decoded to ARGB8888 format*/
|
||||||
dsc->header.cf = LV_COLOR_FORMAT_...
|
dsc->decoded.header.cf = LV_COLOR_FORMAT_...
|
||||||
|
|
||||||
/*Call a binary image decoder function if required. It's not required if `my_png_decoder` opened the image in true color format.*/
|
/*Call a binary image decoder function if required. It's not required if `my_png_decoder` opened the image in true color format.*/
|
||||||
lv_result_t res = lv_bin_decoder_open(decoder, dsc);
|
lv_result_t res = lv_bin_decoder_open(decoder, dsc);
|
||||||
@@ -316,13 +316,13 @@ So in summary:
|
|||||||
- In ``decoder_open``, you should try to open the image source pointed by
|
- In ``decoder_open``, you should try to open the image source pointed by
|
||||||
``dsc->src``. Its type is already in ``dsc->src_type == LV_IMG_SRC_FILE/VARIABLE``.
|
``dsc->src``. Its type is already in ``dsc->src_type == LV_IMG_SRC_FILE/VARIABLE``.
|
||||||
If this format/type is not supported by the decoder, return :cpp:enumerator:`LV_RESULT_INVALID`.
|
If this format/type is not supported by the decoder, return :cpp:enumerator:`LV_RESULT_INVALID`.
|
||||||
However, if you can open the image, a pointer to the decoded *True color* image should be
|
However, if you can open the image, a pointer to the decoded image should be
|
||||||
set in ``dsc->img_data``. If the format is known, but you don't want to
|
set in ``dsc->decoded``. If the format is known, but you don't want to
|
||||||
decode the entire image (e.g. no memory for it), set ``dsc->img_data = NULL`` and
|
decode the entire image (e.g. no memory for it), set ``dsc->decoded = NULL`` and
|
||||||
use ``decoder_get_area`` to get the image area pixels.
|
use ``decoder_get_area`` to get the image area pixels.
|
||||||
- In ``decoder_close`` you should free all allocated resources.
|
- In ``decoder_close`` you should free all allocated resources.
|
||||||
- ``decoder_get_area`` is optional. In this case you should decode the whole image In
|
- ``decoder_get_area`` is optional. In this case you should decode the whole image In
|
||||||
``decoder_open`` function and store image data in ``dsc->img_data``.
|
``decoder_open`` function and store image data in ``dsc->decoded``.
|
||||||
Decoding the whole image requires extra memory and some computational overhead.
|
Decoding the whole image requires extra memory and some computational overhead.
|
||||||
|
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ images to tell color of the image.
|
|||||||
res = lv_image_decoder_open(&dsc, &my_img_dsc, &args);
|
res = lv_image_decoder_open(&dsc, &my_img_dsc, &args);
|
||||||
|
|
||||||
if(res == LV_RESULT_OK) {
|
if(res == LV_RESULT_OK) {
|
||||||
/*Do something with `dsc->img_data`*/
|
/*Do something with `dsc->decoded`. You can copy out the decoded image by `lv_draw_buf_dup(dsc.decoded)`*/
|
||||||
lv_image_decoder_close(&dsc);
|
lv_image_decoder_close(&dsc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,58 +385,23 @@ See the detailed code below:
|
|||||||
lv_cache_entry_t * entry = dsc->cache_entry;
|
lv_cache_entry_t * entry = dsc->cache_entry;
|
||||||
|
|
||||||
if(!(entry->process_state & IMAGE_PROCESS_STATE_PREMULTIPLIED_ALPHA)) {
|
if(!(entry->process_state & IMAGE_PROCESS_STATE_PREMULTIPLIED_ALPHA)) {
|
||||||
lv_color32_t * image = (lv_color32_t *)dsc->img_data;
|
lv_draw_buf_premultiply(dsc->decoded);
|
||||||
uint32_t px_cnt = dsc->header.w * dsc->header.h;
|
|
||||||
|
|
||||||
/* premultiply alpha */
|
|
||||||
while(px_cnt--) {
|
|
||||||
image->red = LV_UDIV255(image->red * image->alpha);
|
|
||||||
image->green = LV_UDIV255(image->green * image->alpha);
|
|
||||||
image->blue = LV_UDIV255(image->blue * image->alpha);
|
|
||||||
image++;
|
|
||||||
}
|
|
||||||
|
|
||||||
LV_LOG_USER("premultiplied alpha OK");
|
LV_LOG_USER("premultiplied alpha OK");
|
||||||
|
|
||||||
entry->process_state |= IMAGE_PROCESS_STATE_PREMULTIPLIED_ALPHA;
|
entry->process_state |= IMAGE_PROCESS_STATE_PREMULTIPLIED_ALPHA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(entry->process_state & IMAGE_PROCESS_STATE_STRIDE_ALIGNED)) {
|
if(!(entry->process_state & IMAGE_PROCESS_STATE_STRIDE_ALIGNED)) {
|
||||||
int32_t image_w = dsc->header.w;
|
uint32_t stride_expect = lv_draw_buf_width_to_stride(decoded->header.w, decoded->header.cf);
|
||||||
int32_t image_h = dsc->header.h;
|
if(decoded->header.stride != stride_expect) {
|
||||||
uint32_t width_byte = image_w * lv_color_format_get_size(color_format);
|
LV_LOG_WARN("Stride mismatch");
|
||||||
uint32_t stride = lv_draw_buf_width_to_stride(image_w, color_format);
|
lv_draw_buf_t * aligned = lv_draw_buf_adjust_stride(decoded, stride_expect);
|
||||||
|
if(aligned == NULL) {
|
||||||
/* Check stride alignment requirements */
|
LV_LOG_ERROR("No memory for Stride adjust.");
|
||||||
if(stride != width_byte) {
|
return NULL;
|
||||||
LV_LOG_USER("need to realign stride: %" LV_PRIu32 " -> %" LV_PRIu32, width_byte, stride);
|
|
||||||
|
|
||||||
const uint8_t * ori_image = lv_cache_get_data(entry);
|
|
||||||
size_t size_bytes = stride * dsc->header.h;
|
|
||||||
uint8_t * new_image = lv_draw_buf_malloc(size_bytes, color_format);
|
|
||||||
if(!new_image) {
|
|
||||||
LV_LOG_ERROR("alloc failed");
|
|
||||||
res = LV_RESULT_INVALID;
|
|
||||||
goto alloc_failed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replace the image data pointer */
|
decoded = aligned;
|
||||||
entry->data = new_image;
|
|
||||||
dsc->img_data = new_image;
|
|
||||||
|
|
||||||
/* Copy image data */
|
|
||||||
const uint8_t * cur = ori_image;
|
|
||||||
for(int32_t y = 0; y < image_h; y++) {
|
|
||||||
lv_memcpy(new_image, cur, width_byte);
|
|
||||||
new_image += stride;
|
|
||||||
cur += width_byte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free memory for old image */
|
|
||||||
lv_draw_buf_free((void *)ori_image);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_USER("no need to realign stride: %" LV_PRIu32, stride);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->process_state |= IMAGE_PROCESS_STATE_STRIDE_ALIGNED;
|
entry->process_state |= IMAGE_PROCESS_STATE_STRIDE_ALIGNED;
|
||||||
@@ -482,7 +447,7 @@ inefficient and detrimental to the user experience.
|
|||||||
|
|
||||||
Therefore, LVGL caches image data. Caching means some
|
Therefore, LVGL caches image data. Caching means some
|
||||||
images will be left open, hence LVGL can quickly access them from
|
images will be left open, hence LVGL can quickly access them from
|
||||||
``dsc->img_data`` instead of needing to decode them again.
|
``dsc->decoded`` instead of needing to decode them again.
|
||||||
|
|
||||||
Of course, caching images is resource intensive as it uses more RAM to
|
Of course, caching images is resource intensive as it uses more RAM to
|
||||||
store the decoded image. LVGL tries to optimize the process as much as
|
store the decoded image. LVGL tries to optimize the process as much as
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ static void img_decode_and_draw(lv_draw_unit_t * draw_unit, const lv_draw_image_
|
|||||||
sup.palette_size = decoder_dsc->palette_size;
|
sup.palette_size = decoder_dsc->palette_size;
|
||||||
|
|
||||||
/*The whole image is available, just draw it*/
|
/*The whole image is available, just draw it*/
|
||||||
if(decoder_dsc->decoded || decoder_dsc->img_data) {
|
if(decoder_dsc->decoded) {
|
||||||
draw_core_cb(draw_unit, draw_dsc, decoder_dsc, &sup, img_area, clipped_img_area);
|
draw_core_cb(draw_unit, draw_dsc, decoder_dsc, &sup, img_area, clipped_img_area);
|
||||||
}
|
}
|
||||||
/*Draw in smaller pieces*/
|
/*Draw in smaller pieces*/
|
||||||
|
|||||||
@@ -171,7 +171,6 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src
|
|||||||
lv_memzero(&dsc->header, sizeof(lv_image_header_t));
|
lv_memzero(&dsc->header, sizeof(lv_image_header_t));
|
||||||
|
|
||||||
dsc->error_msg = NULL;
|
dsc->error_msg = NULL;
|
||||||
dsc->img_data = NULL;
|
|
||||||
dsc->decoded = NULL;
|
dsc->decoded = NULL;
|
||||||
dsc->cache_entry = NULL;
|
dsc->cache_entry = NULL;
|
||||||
dsc->user_data = NULL;
|
dsc->user_data = NULL;
|
||||||
|
|||||||
@@ -145,10 +145,8 @@ typedef struct _lv_image_decoder_dsc_t {
|
|||||||
/**Info about the opened image: color format, size, etc. MUST be set in `open` function*/
|
/**Info about the opened image: color format, size, etc. MUST be set in `open` function*/
|
||||||
lv_image_header_t header;
|
lv_image_header_t header;
|
||||||
|
|
||||||
/** Pointer to a buffer where the image's data (pixels) are stored in a decoded, plain format.
|
/** Pointer to a draw buffer where the image's data (pixels) are stored in a decoded, plain format.
|
||||||
* MUST be set in `open` function*/
|
* MUST be set in `open` or `get_area_cb`function*/
|
||||||
const uint8_t * img_data;
|
|
||||||
|
|
||||||
const lv_draw_buf_t * decoded; /*A draw buffer to described decoded image.*/
|
const lv_draw_buf_t * decoded; /*A draw buffer to described decoded image.*/
|
||||||
|
|
||||||
const lv_color32_t * palette;
|
const lv_color32_t * palette;
|
||||||
@@ -175,14 +173,6 @@ typedef struct _lv_image_decoder_dsc_t {
|
|||||||
* GLOBAL PROTOTYPES
|
* GLOBAL PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo remove it when all decoder migrates to new draw buf interface.
|
|
||||||
*/
|
|
||||||
static inline const void * _lv_image_decoder_get_data(const lv_image_decoder_dsc_t * dsc)
|
|
||||||
{
|
|
||||||
return dsc->decoded ? dsc->decoded->data : dsc->img_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the image decoder module
|
* Initialize the image decoder module
|
||||||
*/
|
*/
|
||||||
@@ -215,7 +205,7 @@ lv_result_t lv_image_decoder_get_info(const void * src, lv_image_header_t * head
|
|||||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||||
* @param color The color of the image with `LV_COLOR_FORMAT_ALPHA_...`
|
* @param color The color of the image with `LV_COLOR_FORMAT_ALPHA_...`
|
||||||
* @param args args about how the image should be opened.
|
* @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.
|
* @return LV_RESULT_OK: opened the image. `dsc->decoded` and `dsc->header` are set.
|
||||||
* LV_RESULT_INVALID: none of the registered image decoders were able to open the image.
|
* 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, const lv_image_decoder_args_t * args);
|
lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src, const lv_image_decoder_args_t * args);
|
||||||
|
|||||||
@@ -55,14 +55,16 @@ static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * d
|
|||||||
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
|
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
|
||||||
const lv_area_t * img_coords, const lv_area_t * clipped_img_area)
|
const lv_area_t * img_coords, const lv_area_t * clipped_img_area)
|
||||||
{
|
{
|
||||||
|
if(decoder_dsc->decoded == NULL) return;
|
||||||
|
|
||||||
lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)u_base;
|
lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)u_base;
|
||||||
|
|
||||||
bool transformed = draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE ||
|
bool transformed = draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE ||
|
||||||
draw_dsc->scale_y != LV_SCALE_NONE ? true : false;
|
draw_dsc->scale_y != LV_SCALE_NONE ? true : false;
|
||||||
|
|
||||||
const uint8_t * src_buf = decoder_dsc->img_data;
|
lv_draw_buf_t decoded = decoder_dsc->decoded;
|
||||||
const lv_image_header_t * header = &decoder_dsc->header;
|
const uint8_t * src_buf = decoded->data;
|
||||||
|
const lv_image_header_t * header = &decoder_dsc->decoded.header;
|
||||||
lv_area_t buffer_area;
|
lv_area_t buffer_area;
|
||||||
lv_area_t draw_area;
|
lv_area_t draw_area;
|
||||||
lv_area_t clipped_area;
|
lv_area_t clipped_area;
|
||||||
@@ -78,14 +80,6 @@ static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * d
|
|||||||
uint32_t img_stride = header->stride;
|
uint32_t img_stride = header->stride;
|
||||||
lv_color_format_t cf = header->cf;
|
lv_color_format_t cf = header->cf;
|
||||||
|
|
||||||
cf = LV_COLOR_FORMAT_IS_INDEXED(cf) ? LV_COLOR_FORMAT_ARGB8888 : cf;
|
|
||||||
|
|
||||||
if(decoder_dsc->decoded) {
|
|
||||||
src_buf = decoder_dsc->decoded->data;
|
|
||||||
img_stride = decoder_dsc->decoded->header.stride;
|
|
||||||
cf = decoder_dsc->decoded->header.cf;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LV_USE_OS
|
#if LV_USE_OS
|
||||||
lv_result_t status;
|
lv_result_t status;
|
||||||
status = lv_mutex_lock(u->pd2Mutex);
|
status = lv_mutex_lock(u->pd2Mutex);
|
||||||
@@ -131,7 +125,7 @@ static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * d
|
|||||||
#if defined(RENESAS_CORTEX_M85)
|
#if defined(RENESAS_CORTEX_M85)
|
||||||
#if (BSP_CFG_DCACHE_ENABLED)
|
#if (BSP_CFG_DCACHE_ENABLED)
|
||||||
d1_cacheblockflush(u->d2_handle, 0, src_buf,
|
d1_cacheblockflush(u->d2_handle, 0, src_buf,
|
||||||
img_stride * decoder_dsc->header.h); //Stride is in bytes, not pixels/texels
|
img_stride * header->h); //Stride is in bytes, not pixels/texels
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -162,14 +156,14 @@ static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * d
|
|||||||
|
|
||||||
lv_point_t p[4] = { //Points in clockwise order
|
lv_point_t p[4] = { //Points in clockwise order
|
||||||
{0, 0},
|
{0, 0},
|
||||||
{decoder_dsc->header.w - 1, 0},
|
{header->w - 1, 0},
|
||||||
{decoder_dsc->header.w - 1, decoder_dsc->header.h - 1},
|
{header->w - 1, header->h - 1},
|
||||||
{0, decoder_dsc->header.h - 1},
|
{0, header->h - 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
d2_settexture(u->d2_handle, (void *)src_buf,
|
d2_settexture(u->d2_handle, (void *)src_buf,
|
||||||
(d2_s32)(img_stride / lv_color_format_get_size(header->cf)),
|
(d2_s32)(img_stride / lv_color_format_get_size(header->cf)),
|
||||||
decoder_dsc->header.w, decoder_dsc->header.h, lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(header->cf));
|
header->w, header->h, lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(header->cf));
|
||||||
|
|
||||||
d2_settexturemode(u->d2_handle, d2_tm_filter);
|
d2_settexturemode(u->d2_handle, d2_tm_filter);
|
||||||
d2_setfillmode(u->d2_handle, d2_fm_texture);
|
d2_setfillmode(u->d2_handle, d2_fm_texture);
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c
|
|||||||
int32_t ofs = decoder_dsc.header.w / 2;
|
int32_t ofs = decoder_dsc.header.w / 2;
|
||||||
lv_area_move(&img_area, dsc->center.x - ofs, dsc->center.y - ofs);
|
lv_area_move(&img_area, dsc->center.x - ofs, dsc->center.y - ofs);
|
||||||
blend_dsc.src_area = &img_area;
|
blend_dsc.src_area = &img_area;
|
||||||
blend_dsc.src_buf = _lv_image_decoder_get_data(&decoder_dsc);
|
blend_dsc.src_buf = decoder_dsc.decoded->data;
|
||||||
blend_dsc.src_color_format = decoder_dsc.decoded->header.cf;
|
blend_dsc.src_color_format = decoder_dsc.decoded->header.cf;
|
||||||
blend_dsc.src_stride = decoder_dsc.decoded->header.stride;
|
blend_dsc.src_stride = decoder_dsc.decoded->header.stride;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,18 +173,11 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
|
|||||||
draw_dsc->scale_y != LV_SCALE_NONE ? true : false;
|
draw_dsc->scale_y != LV_SCALE_NONE ? true : false;
|
||||||
|
|
||||||
lv_draw_sw_blend_dsc_t blend_dsc;
|
lv_draw_sw_blend_dsc_t blend_dsc;
|
||||||
const uint8_t * src_buf = decoder_dsc->img_data;
|
const lv_draw_buf_t * decoded = decoder_dsc->decoded;
|
||||||
const lv_image_header_t * header = &decoder_dsc->header;
|
const uint8_t * src_buf = decoded->data;
|
||||||
uint32_t img_stride = header->stride;
|
const lv_image_header_t * header = &decoded->header;
|
||||||
lv_color_format_t cf = header->cf;
|
uint32_t img_stride = decoded->header.stride;
|
||||||
|
lv_color_format_t cf = decoded->header.cf;
|
||||||
cf = LV_COLOR_FORMAT_IS_INDEXED(cf) ? LV_COLOR_FORMAT_ARGB8888 : cf;
|
|
||||||
|
|
||||||
if(decoder_dsc->decoded) {
|
|
||||||
src_buf = decoder_dsc->decoded->data;
|
|
||||||
img_stride = decoder_dsc->decoded->header.stride;
|
|
||||||
cf = decoder_dsc->decoded->header.cf;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_memzero(&blend_dsc, sizeof(lv_draw_sw_blend_dsc_t));
|
lv_memzero(&blend_dsc, sizeof(lv_draw_sw_blend_dsc_t));
|
||||||
blend_dsc.opa = draw_dsc->opa;
|
blend_dsc.opa = draw_dsc->opa;
|
||||||
|
|||||||
@@ -298,13 +298,13 @@ static void _set_paint_fill_pattern(Tvg_Paint * obj, Tvg_Canvas * canvas, const
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!decoder_dsc.decoded && !decoder_dsc.img_data) {
|
if(!decoder_dsc.decoded) {
|
||||||
lv_image_decoder_close(&decoder_dsc);
|
lv_image_decoder_close(&decoder_dsc);
|
||||||
LV_LOG_ERROR("Image not ready");
|
LV_LOG_ERROR("Image not ready");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t * src_buf = _lv_image_decoder_get_data(&decoder_dsc);
|
const uint8_t * src_buf = decoder_dsc.decoded->data;
|
||||||
const lv_image_header_t * header = &decoder_dsc.header;
|
const lv_image_header_t * header = &decoder_dsc.header;
|
||||||
lv_color_format_t cf = header->cf;
|
lv_color_format_t cf = header->cf;
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ struct ffmpeg_context_s {
|
|||||||
int video_dst_linesize[4];
|
int video_dst_linesize[4];
|
||||||
enum AVPixelFormat video_dst_pix_fmt;
|
enum AVPixelFormat video_dst_pix_fmt;
|
||||||
bool has_alpha;
|
bool has_alpha;
|
||||||
|
lv_draw_buf_t draw_buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
@@ -300,7 +301,13 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
|||||||
uint8_t * img_data = ffmpeg_get_image_data(ffmpeg_ctx);
|
uint8_t * img_data = ffmpeg_get_image_data(ffmpeg_ctx);
|
||||||
|
|
||||||
dsc->user_data = ffmpeg_ctx;
|
dsc->user_data = ffmpeg_ctx;
|
||||||
dsc->img_data = img_data;
|
lv_draw_buf_t * decoded = &ffmpeg_ctx->draw_buf;
|
||||||
|
decoded->header = dsc->header;
|
||||||
|
decoded->header.flags |= LV_IMAGE_FLAGS_MODIFIABLE;
|
||||||
|
decoded->data = img_data;
|
||||||
|
decoded->data_size = (uint32_t)dsc->header.stride * dsc->header.h;
|
||||||
|
decoded->unaligned_data = NULL;
|
||||||
|
dsc->decoded = decoded;
|
||||||
|
|
||||||
/* The image is fully decoded. Return with its pointer */
|
/* The image is fully decoded. Return with its pointer */
|
||||||
return LV_RESULT_OK;
|
return LV_RESULT_OK;
|
||||||
@@ -575,6 +582,7 @@ static int ffmpeg_get_image_header(const char * filepath,
|
|||||||
header->w = video_dec_ctx->width;
|
header->w = video_dec_ctx->width;
|
||||||
header->h = video_dec_ctx->height;
|
header->h = video_dec_ctx->height;
|
||||||
header->cf = has_alpha ? LV_COLOR_FORMAT_ARGB8888 : LV_COLOR_FORMAT_NATIVE;
|
header->cf = has_alpha ? LV_COLOR_FORMAT_ARGB8888 : LV_COLOR_FORMAT_NATIVE;
|
||||||
|
header->stride = header->w * lv_color_format_get_size(header->cf);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,13 +251,12 @@ static lv_draw_buf_t * decode_png_data(const void * png_data, size_t png_data_si
|
|||||||
{
|
{
|
||||||
unsigned png_width; /*Not used, just required by the decoder*/
|
unsigned png_width; /*Not used, just required by the decoder*/
|
||||||
unsigned png_height; /*Not used, just required by the decoder*/
|
unsigned png_height; /*Not used, just required by the decoder*/
|
||||||
uint8_t * img_data = NULL;
|
lv_draw_buf_t * decoded = NULL;
|
||||||
|
|
||||||
lv_draw_buf_t * decoded;
|
|
||||||
/*Decode the image in ARGB8888 */
|
/*Decode the image in ARGB8888 */
|
||||||
unsigned error = lodepng_decode32((unsigned char **)&decoded, &png_width, &png_height, png_data, png_data_size);
|
unsigned error = lodepng_decode32((unsigned char **)&decoded, &png_width, &png_height, png_data, png_data_size);
|
||||||
if(error) {
|
if(error) {
|
||||||
if(img_data != NULL) lv_draw_buf_destroy(decoded);
|
if(decoded != NULL) lv_draw_buf_destroy(decoded);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user