feat(vg_lite): add index format decode support (#5476)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
@@ -17,20 +17,23 @@
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_VG_LITE_IMAGE_NO_CACHE LV_IMAGE_FLAGS_USER1
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
#pragma pack(1)
|
||||
/* If the original image can directly satisfy the GPU requirements, there is no need to create a copy */
|
||||
#define LV_VG_LITE_IMAGE_NO_DUP LV_IMAGE_FLAGS_USER1
|
||||
|
||||
typedef struct {
|
||||
lv_color16_t c;
|
||||
uint8_t alpha;
|
||||
} lv_color16_alpha_t;
|
||||
/* VG_LITE_INDEX1, 2, and 4 require endian flipping + bit flipping,
|
||||
* so for simplicity, they are uniformly converted to I8 for display.
|
||||
*/
|
||||
#define DEST_IMG_FORMAT LV_COLOR_FORMAT_I8
|
||||
|
||||
#pragma pack()
|
||||
/* Since the palette and index image are next to each other,
|
||||
* the palette size needs to be aligned to ensure that the image is aligned.
|
||||
*/
|
||||
#define DEST_IMG_OFFSET \
|
||||
LV_VG_LITE_ALIGN(LV_COLOR_INDEXED_PALETTE_SIZE(DEST_IMG_FORMAT) * sizeof(lv_color32_t), LV_DRAW_BUF_ALIGN)
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
@@ -40,12 +43,7 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src,
|
||||
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
|
||||
static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
|
||||
static void decoder_cache_free(lv_image_cache_data_t * cached_data, void * user_data);
|
||||
static void image_try_self_pre_mul(lv_image_decoder_dsc_t * dsc);
|
||||
static void image_color32_pre_mul(lv_color32_t * img_data, uint32_t px_size);
|
||||
static void image_color16_pre_mul(lv_color16_alpha_t * img_data, uint32_t px_size);
|
||||
static void image_copy(uint8_t * dest, const uint8_t * src,
|
||||
size_t dest_stride, size_t src_stride,
|
||||
uint32_t height);
|
||||
static void image_invalidate_cache(void * buf, uint32_t stride,
|
||||
uint32_t width, uint32_t height,
|
||||
lv_color_format_t cf);
|
||||
@@ -89,83 +87,11 @@ void lv_vg_lite_decoder_deinit(void)
|
||||
static void image_color32_pre_mul(lv_color32_t * img_data, uint32_t px_size)
|
||||
{
|
||||
while(px_size--) {
|
||||
img_data->red = LV_UDIV255(img_data->red * img_data->alpha);
|
||||
img_data->green = LV_UDIV255(img_data->green * img_data->alpha);
|
||||
img_data->blue = LV_UDIV255(img_data->blue * img_data->alpha);
|
||||
lv_color_premultiply(img_data);
|
||||
img_data++;
|
||||
}
|
||||
}
|
||||
|
||||
static void image_color16_pre_mul(lv_color16_alpha_t * img_data, uint32_t px_size)
|
||||
{
|
||||
while(px_size--) {
|
||||
img_data->c.red = LV_UDIV255(img_data->c.red * img_data->alpha);
|
||||
img_data->c.green = LV_UDIV255(img_data->c.green * img_data->alpha);
|
||||
img_data->c.blue = LV_UDIV255(img_data->c.blue * img_data->alpha);
|
||||
img_data++;
|
||||
}
|
||||
}
|
||||
|
||||
static void image_try_self_pre_mul(lv_image_decoder_dsc_t * dsc)
|
||||
{
|
||||
/* !!! WARNING !!!
|
||||
* self-premultiplied images
|
||||
* should be width-aligned and in modifiable RAM
|
||||
*/
|
||||
if(lv_vg_lite_support_blend_normal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(dsc->header.flags & LV_IMAGE_FLAGS_PREMULTIPLIED) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_color_format_t cf = dsc->header.cf;
|
||||
if(!lv_color_format_has_alpha(cf)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t image_w = dsc->header.w;
|
||||
int32_t image_h = dsc->header.h;
|
||||
uint32_t stride = lv_draw_buf_width_to_stride(image_w, cf);
|
||||
uint32_t aligned_w = lv_vg_lite_width_align(image_w);
|
||||
size_t px_size = aligned_w * image_h;
|
||||
void * image_data = dsc->decoded->data;
|
||||
|
||||
if(cf == LV_COLOR_FORMAT_ARGB8888) {
|
||||
image_color32_pre_mul(image_data, px_size);
|
||||
}
|
||||
else if(cf == LV_COLOR_FORMAT_RGB565A8) {
|
||||
image_color16_pre_mul(image_data, px_size);
|
||||
}
|
||||
else if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
|
||||
lv_color32_t * palette = (lv_color32_t *)image_data;
|
||||
uint32_t palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(cf);
|
||||
image_color32_pre_mul(palette, palette_size);
|
||||
}
|
||||
else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf)) {
|
||||
/* do nothing */
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("unsupported cf: %d", cf);
|
||||
}
|
||||
|
||||
image_invalidate_cache(image_data, stride, image_w, image_h, cf);
|
||||
|
||||
dsc->header.flags |= LV_IMAGE_FLAGS_PREMULTIPLIED;
|
||||
}
|
||||
|
||||
static void image_copy(uint8_t * dest, const uint8_t * src,
|
||||
size_t dest_stride, size_t src_stride,
|
||||
uint32_t height)
|
||||
{
|
||||
for(uint32_t y = 0; y < height; y++) {
|
||||
lv_memcpy(dest, src, src_stride);
|
||||
src += src_stride;
|
||||
dest += dest_stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void image_invalidate_cache(void * buf, uint32_t stride,
|
||||
uint32_t width, uint32_t height,
|
||||
lv_color_format_t cf)
|
||||
@@ -176,92 +102,159 @@ static void image_invalidate_cache(void * buf, uint32_t stride,
|
||||
lv_draw_buf_invalidate_cache(buf, stride, cf, &image_area);
|
||||
}
|
||||
|
||||
static uint32_t image_stride(const lv_image_header_t * header)
|
||||
{
|
||||
/* use stride in header */
|
||||
if(header->stride) {
|
||||
return header->stride;
|
||||
}
|
||||
|
||||
/* guess stride */
|
||||
uint32_t ori_stride = header->w * lv_color_format_get_bpp(header->cf);
|
||||
ori_stride = (ori_stride + 7) >> 3; /*Round up*/
|
||||
return ori_stride;
|
||||
}
|
||||
|
||||
static void image_decode_to_index8_line(uint8_t * dest, const uint8_t * src, int32_t w_px,
|
||||
lv_color_format_t color_format)
|
||||
{
|
||||
uint8_t px_size;
|
||||
uint16_t mask;
|
||||
|
||||
int8_t shift = 0;
|
||||
switch(color_format) {
|
||||
case LV_COLOR_FORMAT_I1:
|
||||
px_size = 1;
|
||||
shift = 7;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_I2:
|
||||
px_size = 2;
|
||||
shift = 6;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_I4:
|
||||
px_size = 4;
|
||||
shift = 4;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_I8:
|
||||
lv_memcpy(dest, src, w_px);
|
||||
return;
|
||||
default:
|
||||
LV_ASSERT_FORMAT_MSG(false, "Unsupported color format: %d", color_format);
|
||||
return;
|
||||
}
|
||||
|
||||
mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/
|
||||
|
||||
for(int32_t i = 0; i < w_px; i++) {
|
||||
uint8_t val_act = (*src >> shift) & mask;
|
||||
dest[i] = val_act;
|
||||
|
||||
shift -= px_size;
|
||||
if(shift < 0) {
|
||||
shift = 8 - px_size;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header)
|
||||
{
|
||||
return lv_bin_decoder_info(decoder, src, header);
|
||||
lv_result_t res = lv_bin_decoder_info(decoder, src, header);
|
||||
if(res != LV_RESULT_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if(LV_COLOR_FORMAT_IS_YUV(header->cf)) {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
if(LV_COLOR_FORMAT_IS_INDEXED(header->cf)) {
|
||||
header->cf = DEST_IMG_FORMAT;
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
|
||||
{
|
||||
LV_UNUSED(decoder); /*Unused*/
|
||||
|
||||
lv_color_format_t cf = dsc->header.cf;
|
||||
lv_draw_buf_t src_img_buf;
|
||||
lv_draw_buf_from_image(&src_img_buf, dsc->src);
|
||||
|
||||
/* Since dsc->header.cf is uniformly set to I8,
|
||||
* the original format is obtained from src for conversion.
|
||||
*/
|
||||
lv_color_format_t src_cf = src_img_buf.header.cf;
|
||||
|
||||
int32_t width = dsc->header.w;
|
||||
int32_t height = dsc->header.h;
|
||||
|
||||
/* native stride */
|
||||
uint32_t width_byte;
|
||||
width_byte = width * lv_color_format_get_bpp(cf);
|
||||
width_byte = (width_byte + 7) >> 3; /*Round up*/
|
||||
|
||||
bool support_blend_normal = lv_vg_lite_support_blend_normal();
|
||||
|
||||
/*In case of uncompressed formats the image stored in the ROM/RAM.
|
||||
*So simply give its pointer*/
|
||||
const uint8_t * image_data = ((lv_image_dsc_t *)dsc->src)->data;
|
||||
uint32_t image_data_size = ((lv_image_dsc_t *)dsc->src)->data_size;
|
||||
|
||||
bool has_alpha = lv_color_format_has_alpha(cf);
|
||||
bool is_indexed = LV_COLOR_FORMAT_IS_INDEXED(cf);
|
||||
bool is_yuv = LV_COLOR_FORMAT_IS_YUV(cf);
|
||||
bool is_addr_aligned = (image_data == lv_draw_buf_align((void *)image_data, cf)) ? true : false;
|
||||
|
||||
uint32_t stride = lv_draw_buf_width_to_stride(width, cf);
|
||||
bool is_stride_aligned = (stride == width_byte) ? true : false;
|
||||
|
||||
/* When the following conditions are met,
|
||||
* there is no need to copy image resource preprocessing.
|
||||
*/
|
||||
if((is_addr_aligned
|
||||
&& is_stride_aligned
|
||||
&& !is_indexed
|
||||
&& (!has_alpha || (has_alpha && support_blend_normal))) || is_yuv) {
|
||||
|
||||
/* if is YUV format, no need to copy */
|
||||
if(LV_COLOR_FORMAT_IS_YUV(src_cf)) {
|
||||
lv_draw_buf_t * draw_buf = lv_malloc_zeroed(sizeof(lv_draw_buf_t));
|
||||
LV_ASSERT_MALLOC(draw_buf);
|
||||
lv_draw_buf_init(draw_buf, width, height, cf, stride, (void *)image_data, image_data_size);
|
||||
uint32_t stride = lv_draw_buf_width_to_stride(width, src_cf);
|
||||
lv_draw_buf_init(draw_buf, width, height, src_cf, stride, (void *)image_data, image_data_size);
|
||||
|
||||
/* mark no dup */
|
||||
draw_buf->header.flags |= LV_VG_LITE_IMAGE_NO_DUP;
|
||||
|
||||
dsc->decoded = draw_buf;
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
uint32_t palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(cf);
|
||||
uint32_t palette_size_bytes = palette_size * sizeof(lv_color32_t);
|
||||
|
||||
/* Since the palette and index image are next to each other,
|
||||
* the palette size needs to be aligned to ensure that the image is aligned.
|
||||
*/
|
||||
uint32_t palette_size_bytes_aligned = LV_VG_LITE_ALIGN(palette_size_bytes, LV_DRAW_BUF_ALIGN);
|
||||
|
||||
lv_draw_buf_t * draw_buf = lv_draw_buf_create(width, height, cf, stride);
|
||||
/* create draw buf */
|
||||
lv_draw_buf_t * draw_buf = lv_draw_buf_create(width, height, DEST_IMG_FORMAT, LV_STRIDE_AUTO);
|
||||
if(draw_buf == NULL) {
|
||||
LV_LOG_ERROR("create draw buf failed, cf = %d", cf);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
dsc->decoded = draw_buf;
|
||||
|
||||
uint32_t src_stride = image_stride(&src_img_buf.header);
|
||||
uint32_t dest_stride = draw_buf->header.stride;
|
||||
|
||||
const uint8_t * src = image_data;
|
||||
uint8_t * dest = draw_buf->data;
|
||||
|
||||
/* copy palette */
|
||||
if(palette_size_bytes) {
|
||||
lv_memcpy(dest, src, palette_size_bytes);
|
||||
src += palette_size_bytes;
|
||||
/* index format only */
|
||||
uint32_t palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(src_cf);
|
||||
LV_ASSERT(palette_size > 0);
|
||||
|
||||
/* move to align size */
|
||||
dest += palette_size_bytes_aligned;
|
||||
uint32_t palette_size_bytes = palette_size * sizeof(lv_color32_t);
|
||||
|
||||
/* copy palette */
|
||||
lv_memcpy(dest, src, palette_size_bytes);
|
||||
|
||||
if(!dsc->args.premultiply) {
|
||||
/* pre-multiply palette */
|
||||
image_color32_pre_mul((lv_color32_t *)dest, palette_size);
|
||||
draw_buf->header.flags |= LV_IMAGE_FLAGS_PREMULTIPLIED;
|
||||
}
|
||||
|
||||
image_copy(dest, src, stride, width_byte, height);
|
||||
/* move to index image map */
|
||||
src += palette_size_bytes;
|
||||
dest += DEST_IMG_OFFSET;
|
||||
|
||||
/* premul alpha */
|
||||
image_try_self_pre_mul(dsc);
|
||||
/* copy index image */
|
||||
for(int32_t y = 0; y < height; y++) {
|
||||
image_decode_to_index8_line(dest, src, width, src_cf);
|
||||
src += src_stride;
|
||||
dest += dest_stride;
|
||||
}
|
||||
|
||||
/* invalidate D-Cache */
|
||||
image_invalidate_cache(draw_buf->data, stride, width, height, cf);
|
||||
image_invalidate_cache(draw_buf->data, dest_stride, width, height, DEST_IMG_FORMAT);
|
||||
|
||||
LV_LOG_INFO("image %p (W%" LV_PRId32 " x H%" LV_PRId32 ", buffer: %p, cf: %d) decode finish",
|
||||
image_data, width, height, draw_buf->data, cf);
|
||||
image_data, width, height, draw_buf->data, src_cf);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
@@ -269,10 +262,10 @@ static lv_result_t decoder_open_file(lv_image_decoder_t * decoder, lv_image_deco
|
||||
{
|
||||
LV_UNUSED(decoder); /*Unused*/
|
||||
|
||||
lv_color_format_t cf = dsc->header.cf;
|
||||
uint32_t width = dsc->header.w;
|
||||
uint32_t height = dsc->header.h;
|
||||
const char * path = dsc->src;
|
||||
uint8_t * src_temp = NULL;
|
||||
|
||||
lv_fs_file_t file;
|
||||
lv_fs_res_t res = lv_fs_open(&file, path, LV_FS_MODE_RD);
|
||||
@@ -281,84 +274,91 @@ static lv_result_t decoder_open_file(lv_image_decoder_t * decoder, lv_image_deco
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/* skip image header bytes */
|
||||
res = lv_fs_seek(&file, sizeof(lv_image_header_t), LV_FS_SEEK_SET);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
LV_LOG_ERROR("seek %s lv_image_header_t failed", path);
|
||||
/* get real src header */
|
||||
lv_image_header_t src_header;
|
||||
uint32_t header_br = 0;
|
||||
res = lv_fs_read(&file, &src_header, sizeof(src_header), &header_br);
|
||||
if(res != LV_FS_RES_OK || header_br != sizeof(src_header)) {
|
||||
LV_LOG_ERROR("read %s lv_image_header_t failed", path);
|
||||
lv_fs_close(&file);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/* native stride */
|
||||
uint32_t width_byte;
|
||||
width_byte = width * lv_color_format_get_bpp(cf);
|
||||
width_byte = (width_byte + 7) >> 3; /*Round up*/
|
||||
|
||||
bool support_blend_normal = lv_vg_lite_support_blend_normal();
|
||||
|
||||
uint32_t stride = lv_draw_buf_width_to_stride(width, cf);
|
||||
|
||||
uint32_t palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(cf);
|
||||
uint32_t palette_size_bytes = palette_size * sizeof(lv_color32_t);
|
||||
|
||||
/* Since the palette and index image are next to each other,
|
||||
* the palette size needs to be aligned to ensure that the image is aligned.
|
||||
*/
|
||||
uint32_t palette_size_bytes_aligned = LV_VG_LITE_ALIGN(palette_size_bytes, LV_DRAW_BUF_ALIGN);
|
||||
|
||||
lv_draw_buf_t * draw_buf = lv_draw_buf_create(width, height, cf, stride);
|
||||
lv_draw_buf_t * draw_buf = lv_draw_buf_create(width, height, DEST_IMG_FORMAT, LV_STRIDE_AUTO);
|
||||
if(draw_buf == NULL) {
|
||||
LV_LOG_ERROR("create draw buf failed, cf = %d", cf);
|
||||
lv_fs_close(&file);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/* get stride */
|
||||
uint32_t src_stride = image_stride(&src_header);
|
||||
uint32_t dest_stride = draw_buf->header.stride;
|
||||
|
||||
dsc->decoded = draw_buf;
|
||||
uint8_t * dest = draw_buf->data;
|
||||
|
||||
/* copy palette */
|
||||
if(palette_size_bytes) {
|
||||
uint32_t br;
|
||||
/* read palette */
|
||||
res = lv_fs_read(&file, dest, palette_size_bytes, &br);
|
||||
if(res != LV_FS_RES_OK || br != palette_size_bytes) {
|
||||
LV_LOG_ERROR("read %s (palette: %" LV_PRIu32 ", br: %" LV_PRIu32 ") failed",
|
||||
path, palette_size_bytes, br);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if(!support_blend_normal) {
|
||||
image_color32_pre_mul((lv_color32_t *)dest, palette_size);
|
||||
}
|
||||
|
||||
/* move to index image map */
|
||||
dest += palette_size_bytes_aligned;
|
||||
/* index format only */
|
||||
uint32_t palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(src_header.cf);
|
||||
if(palette_size == 0) {
|
||||
LV_LOG_ERROR("file %s invalid palette size: %" LV_PRIu32, path, palette_size);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
uint32_t palette_size_bytes = palette_size * sizeof(lv_color32_t);
|
||||
|
||||
/* read palette */
|
||||
uint32_t palette_br = 0;
|
||||
res = lv_fs_read(&file, dest, palette_size_bytes, &palette_br);
|
||||
if(res != LV_FS_RES_OK || palette_br != palette_size_bytes) {
|
||||
LV_LOG_ERROR("read %s (palette: %" LV_PRIu32 ", br: %" LV_PRIu32 ") failed",
|
||||
path, palette_size_bytes, palette_br);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if(dsc->args.premultiply) {
|
||||
/* pre-multiply palette */
|
||||
image_color32_pre_mul((lv_color32_t *)dest, palette_size);
|
||||
draw_buf->header.flags |= LV_IMAGE_FLAGS_PREMULTIPLIED;
|
||||
}
|
||||
|
||||
src_temp = lv_malloc(src_stride);
|
||||
if(src_temp == NULL) {
|
||||
LV_LOG_ERROR("malloc src_temp failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* move to index image map */
|
||||
dest += DEST_IMG_OFFSET;
|
||||
|
||||
for(uint32_t y = 0; y < height; y++) {
|
||||
uint32_t br;
|
||||
res = lv_fs_read(&file, dest, width_byte, &br);
|
||||
if(res != LV_FS_RES_OK || br != width_byte) {
|
||||
LV_LOG_ERROR("read %s (y: %" LV_PRIu32 ", width_byte: %" LV_PRIu32 ", br: %" LV_PRIu32 ") failed",
|
||||
path, y, width_byte, br);
|
||||
uint32_t br = 0;
|
||||
res = lv_fs_read(&file, src_temp, src_stride, &br);
|
||||
if(res != LV_FS_RES_OK || br != src_stride) {
|
||||
LV_LOG_ERROR("read %s (y: %" LV_PRIu32 ", src_stride: %" LV_PRIu32 ", br: %" LV_PRIu32 ") failed",
|
||||
path, y, src_stride, br);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
dest += stride;
|
||||
/* convert to index8 */
|
||||
image_decode_to_index8_line(dest, src_temp, width, src_header.cf);
|
||||
dest += dest_stride;
|
||||
}
|
||||
|
||||
lv_free(src_temp);
|
||||
|
||||
lv_fs_close(&file);
|
||||
|
||||
/* premul alpha */
|
||||
image_try_self_pre_mul(dsc);
|
||||
|
||||
/* invalidate D-Cache */
|
||||
image_invalidate_cache(draw_buf->data, stride, width, height, cf);
|
||||
image_invalidate_cache(draw_buf->data, dest_stride, width, height, src_header.cf);
|
||||
|
||||
LV_LOG_INFO("image %s (W%" LV_PRId32 " x H%" LV_PRId32 ", buffer: %p cf: %d) decode finish",
|
||||
path, width, height, draw_buf->data, cf);
|
||||
path, width, height, draw_buf->data, src_header.cf);
|
||||
return LV_RESULT_OK;
|
||||
|
||||
failed:
|
||||
if(src_temp) {
|
||||
lv_free(src_temp);
|
||||
}
|
||||
lv_fs_close(&file);
|
||||
lv_draw_buf_destroy(draw_buf);
|
||||
dsc->decoded = NULL;
|
||||
@@ -366,6 +366,17 @@ failed:
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
static void decoder_draw_buf_free(lv_draw_buf_t * draw_buf)
|
||||
{
|
||||
if(draw_buf->header.flags & LV_VG_LITE_IMAGE_NO_DUP) {
|
||||
/* free draw buf struct only */
|
||||
lv_free(draw_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_draw_buf_destroy(draw_buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an image using the vg_lite gpu.
|
||||
* @param decoder pointer to the decoder
|
||||
@@ -374,7 +385,6 @@ failed:
|
||||
*/
|
||||
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
|
||||
{
|
||||
|
||||
lv_result_t res = LV_RESULT_INVALID;
|
||||
|
||||
switch(dsc->src_type) {
|
||||
@@ -388,7 +398,7 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
||||
break;
|
||||
}
|
||||
|
||||
if(dsc->args.no_cache) return LV_RES_OK;
|
||||
if(dsc->args.no_cache) return res;
|
||||
|
||||
#if LV_CACHE_DEF_SIZE > 0
|
||||
if(res == LV_RESULT_OK) {
|
||||
@@ -400,7 +410,7 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
||||
lv_cache_entry_t * entry = lv_image_decoder_add_to_cache(decoder, &search_key, dsc->decoded, NULL);
|
||||
|
||||
if(entry == NULL) {
|
||||
lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded);
|
||||
decoder_draw_buf_free((lv_draw_buf_t *)dsc->decoded);
|
||||
dsc->decoded = NULL;
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
@@ -411,22 +421,12 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
||||
return res;
|
||||
}
|
||||
|
||||
static void decoder_draw_buf_free(lv_draw_buf_t * draw_buf)
|
||||
{
|
||||
if(draw_buf->header.flags & LV_VG_LITE_IMAGE_NO_CACHE) {
|
||||
lv_free(draw_buf);
|
||||
}
|
||||
else {
|
||||
lv_draw_buf_destroy(draw_buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
|
||||
{
|
||||
LV_UNUSED(decoder); /*Unused*/
|
||||
|
||||
if(dsc->args.no_cache || LV_CACHE_DEF_SIZE == 0)
|
||||
lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded);
|
||||
decoder_draw_buf_free((lv_draw_buf_t *)dsc->decoded);
|
||||
else
|
||||
lv_cache_release(dsc->cache, dsc->cache_entry, NULL);
|
||||
}
|
||||
@@ -436,7 +436,6 @@ static void decoder_cache_free(lv_image_cache_data_t * cached_data, void * user_
|
||||
LV_UNUSED(user_data);
|
||||
|
||||
if(cached_data->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)cached_data->src);
|
||||
|
||||
decoder_draw_buf_free((lv_draw_buf_t *)cached_data->decoded);
|
||||
}
|
||||
|
||||
|
||||
@@ -325,12 +325,17 @@ bool lv_vg_lite_is_src_cf_supported(lv_color_format_t cf)
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_A4:
|
||||
case LV_COLOR_FORMAT_A8:
|
||||
case LV_COLOR_FORMAT_I8:
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
return true;
|
||||
|
||||
case LV_COLOR_FORMAT_I1:
|
||||
case LV_COLOR_FORMAT_I2:
|
||||
case LV_COLOR_FORMAT_I4:
|
||||
case LV_COLOR_FORMAT_I8:
|
||||
return vg_lite_query_feature(gcFEATURE_BIT_VG_IM_INDEX_FORMAT) ? true : false;
|
||||
|
||||
case LV_COLOR_FORMAT_RGB565A8:
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
return vg_lite_query_feature(gcFEATURE_BIT_VG_24BIT) ? true : false;
|
||||
@@ -560,8 +565,12 @@ void lv_vg_lite_buffer_from_draw_buf(vg_lite_buffer_t * buffer, const lv_draw_bu
|
||||
int32_t height = draw_buf->header.h;
|
||||
vg_lite_buffer_format_t format = lv_vg_lite_vg_fmt(draw_buf->header.cf);
|
||||
|
||||
if(LV_COLOR_FORMAT_IS_INDEXED(draw_buf->header.cf))
|
||||
ptr += LV_COLOR_INDEXED_PALETTE_SIZE(draw_buf->header.cf) * 4;
|
||||
if(LV_COLOR_FORMAT_IS_INDEXED(draw_buf->header.cf)) {
|
||||
uint32_t palette_size_bytes = LV_COLOR_INDEXED_PALETTE_SIZE(draw_buf->header.cf) * sizeof(uint32_t);
|
||||
|
||||
/* Skip palette */
|
||||
ptr += LV_VG_LITE_ALIGN(palette_size_bytes, LV_DRAW_BUF_ALIGN);
|
||||
}
|
||||
|
||||
width = lv_vg_lite_width_align(width);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user