mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
feat(bin_decoder): post process decoded image to fulfill decoder's args (#5082)
Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
parent
2fa9847201
commit
755810bf8e
@ -166,7 +166,7 @@ lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf,
|
|||||||
draw_buf->header.w = w;
|
draw_buf->header.w = w;
|
||||||
draw_buf->header.h = h;
|
draw_buf->header.h = h;
|
||||||
draw_buf->header.cf = cf;
|
draw_buf->header.cf = cf;
|
||||||
draw_buf->header.flags = LV_IMAGE_FLAGS_MODIFIABLE;
|
draw_buf->header.flags = LV_IMAGE_FLAGS_MODIFIABLE | LV_IMAGE_FLAGS_ALLOCATED;
|
||||||
draw_buf->header.stride = stride;
|
draw_buf->header.stride = stride;
|
||||||
draw_buf->data = lv_draw_buf_align(buf, cf);
|
draw_buf->data = lv_draw_buf_align(buf, cf);
|
||||||
draw_buf->unaligned_data = buf;
|
draw_buf->unaligned_data = buf;
|
||||||
@ -174,14 +174,32 @@ lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf,
|
|||||||
return draw_buf;
|
return draw_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf)
|
||||||
|
{
|
||||||
|
const lv_image_header_t * header = &draw_buf->header;
|
||||||
|
lv_draw_buf_t * new_buf = lv_draw_buf_create(header->w, header->h, header->cf, header->stride);
|
||||||
|
if(new_buf == NULL) return NULL;
|
||||||
|
|
||||||
|
/*Choose the smaller size to copy*/
|
||||||
|
uint32_t size = LV_MIN(draw_buf->data_size, new_buf->data_size);
|
||||||
|
|
||||||
|
/*Copy image data*/
|
||||||
|
lv_memcpy(new_buf->data, draw_buf->data, size);
|
||||||
|
return new_buf;
|
||||||
|
}
|
||||||
|
|
||||||
void lv_draw_buf_destroy(lv_draw_buf_t * buf)
|
void lv_draw_buf_destroy(lv_draw_buf_t * buf)
|
||||||
{
|
{
|
||||||
LV_ASSERT_NULL(buf);
|
LV_ASSERT_NULL(buf);
|
||||||
if(buf == NULL) return;
|
if(buf == NULL) return;
|
||||||
if(buf->header.flags & LV_IMAGE_FLAGS_MODIFIABLE)
|
|
||||||
lv_draw_buf_free(buf->unaligned_data);
|
|
||||||
|
|
||||||
lv_free(buf);
|
if(buf->header.flags & LV_IMAGE_FLAGS_ALLOCATED) {
|
||||||
|
lv_draw_buf_free(buf->unaligned_data);
|
||||||
|
lv_free(buf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LV_LOG_ERROR("draw buffer is not allocated, ignored");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void * lv_draw_buf_goto_xy(lv_draw_buf_t * buf, uint32_t x, uint32_t y)
|
void * lv_draw_buf_goto_xy(lv_draw_buf_t * buf, uint32_t x, uint32_t y)
|
||||||
@ -230,6 +248,69 @@ lv_draw_buf_t * lv_draw_buf_adjust_stride(const lv_draw_buf_t * src, uint32_t st
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf)
|
||||||
|
{
|
||||||
|
LV_ASSERT_NULL(draw_buf);
|
||||||
|
if(draw_buf == NULL) return LV_RESULT_INVALID;
|
||||||
|
|
||||||
|
if(draw_buf->header.flags & LV_IMAGE_FLAGS_PREMULTIPLIED) return LV_RESULT_INVALID;
|
||||||
|
if((draw_buf->header.flags & LV_IMAGE_FLAGS_MODIFIABLE) == 0) {
|
||||||
|
LV_LOG_WARN("draw buf is not modifiable: 0x%04x", draw_buf->header.flags);
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Premultiply color with alpha, do case by case by judging color format*/
|
||||||
|
lv_color_format_t cf = draw_buf->header.cf;
|
||||||
|
if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
|
||||||
|
int size = LV_COLOR_INDEXED_PALETTE_SIZE(cf);
|
||||||
|
lv_color32_t * palette = (lv_color32_t *)draw_buf->data;
|
||||||
|
for(int i = 0; i < size; i++) {
|
||||||
|
lv_color_premultiply(&palette[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(cf == LV_COLOR_FORMAT_ARGB8888) {
|
||||||
|
uint32_t h = draw_buf->header.h;
|
||||||
|
uint32_t w = draw_buf->header.w;
|
||||||
|
uint32_t stride = draw_buf->header.stride;
|
||||||
|
uint8_t * line = (uint8_t *)draw_buf->data;
|
||||||
|
for(uint32_t y = 0; y < h; y++) {
|
||||||
|
lv_color32_t * pixel = (lv_color32_t *)line;
|
||||||
|
for(uint32_t x = 0; x < w; x++) {
|
||||||
|
lv_color_premultiply(pixel);
|
||||||
|
pixel++;
|
||||||
|
}
|
||||||
|
line += stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(cf == LV_COLOR_FORMAT_RGB565A8) {
|
||||||
|
uint32_t h = draw_buf->header.h;
|
||||||
|
uint32_t w = draw_buf->header.w;
|
||||||
|
uint32_t stride = draw_buf->header.stride;
|
||||||
|
uint32_t alpha_stride = stride / 2;
|
||||||
|
uint8_t * line = (uint8_t *)draw_buf->data;
|
||||||
|
lv_opa_t * alpha = (lv_opa_t *)(line + stride * h);
|
||||||
|
for(uint32_t y = 0; y < h; y++) {
|
||||||
|
lv_color16_t * pixel = (lv_color16_t *)line;
|
||||||
|
for(uint32_t x = 0; x < w; x++) {
|
||||||
|
lv_color16_premultiply(pixel, alpha[x]);
|
||||||
|
pixel++;
|
||||||
|
}
|
||||||
|
line += stride;
|
||||||
|
alpha += alpha_stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf)) {
|
||||||
|
/*Pass*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LV_LOG_WARN("draw buf has no alpha, cf: %d", cf);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_buf->header.flags |= LV_IMAGE_FLAGS_PREMULTIPLIED;
|
||||||
|
|
||||||
|
return LV_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -181,6 +181,13 @@ void lv_draw_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const l
|
|||||||
*/
|
*/
|
||||||
lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride);
|
lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duplicate a draw buf with same image size, stride and color format. Copy the image data too.
|
||||||
|
* @param draw_buf the draw buf to duplicate
|
||||||
|
* @return the duplicated draw buf on success, NULL if failed
|
||||||
|
*/
|
||||||
|
lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a draw buf by free the actual buffer if it's marked as LV_IMAGE_FLAGS_MODIFIABLE in header.
|
* Destroy a draw buf by free the actual buffer if it's marked as LV_IMAGE_FLAGS_MODIFIABLE in header.
|
||||||
* Then free the lv_draw_buf_t struct.
|
* Then free the lv_draw_buf_t struct.
|
||||||
@ -197,6 +204,20 @@ void * lv_draw_buf_goto_xy(lv_draw_buf_t * buf, uint32_t x, uint32_t y);
|
|||||||
*/
|
*/
|
||||||
lv_draw_buf_t * lv_draw_buf_adjust_stride(const lv_draw_buf_t * src, uint32_t stride);
|
lv_draw_buf_t * lv_draw_buf_adjust_stride(const lv_draw_buf_t * src, uint32_t stride);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Premultiply draw buffer color with alpha channel.
|
||||||
|
* If it's already premultiplied, return directly.
|
||||||
|
* Only color formats with alpha channel will be processed.
|
||||||
|
*
|
||||||
|
* @return LV_RESULT_OK: premultiply success
|
||||||
|
*/
|
||||||
|
lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf);
|
||||||
|
|
||||||
|
static inline bool lv_draw_buf_has_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag)
|
||||||
|
{
|
||||||
|
return draw_buf->header.flags & flag;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* As of now, draw buf share same definition as `lv_image_dsc_t`.
|
* As of now, draw buf share same definition as `lv_image_dsc_t`.
|
||||||
* And is interchangeable with `lv_image_dsc_t`.
|
* And is interchangeable with `lv_image_dsc_t`.
|
||||||
|
@ -75,6 +75,11 @@ typedef enum _lv_image_flags_t {
|
|||||||
*/
|
*/
|
||||||
LV_IMAGE_FLAGS_COMPRESSED = (1 << 3),
|
LV_IMAGE_FLAGS_COMPRESSED = (1 << 3),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The image is alloced from heap, thus should be freed after use.
|
||||||
|
*/
|
||||||
|
LV_IMAGE_FLAGS_ALLOCATED = (1 << 4),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flags reserved for user, lvgl won't use these bits.
|
* Flags reserved for user, lvgl won't use these bits.
|
||||||
*/
|
*/
|
||||||
|
@ -115,17 +115,14 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src
|
|||||||
lv_image_decoder_t * decoder;
|
lv_image_decoder_t * decoder;
|
||||||
lv_image_decoder_args_t * args_copy = NULL;
|
lv_image_decoder_args_t * args_copy = NULL;
|
||||||
|
|
||||||
|
static const lv_image_decoder_args_t def_args = {
|
||||||
|
.stride_align = LV_DRAW_BUF_STRIDE_ALIGN != 1,
|
||||||
|
.premultiply = false,
|
||||||
|
.no_cache = false,
|
||||||
|
};
|
||||||
|
|
||||||
/*Make a copy of args */
|
/*Make a copy of args */
|
||||||
if(args) {
|
dsc->args = args ? *args : def_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) {
|
_LV_LL_READ(img_decoder_ll_p, decoder) {
|
||||||
/*Info and Open callbacks are required*/
|
/*Info and Open callbacks are required*/
|
||||||
@ -174,7 +171,6 @@ void lv_image_decoder_close(lv_image_decoder_dsc_t * dsc)
|
|||||||
{
|
{
|
||||||
if(dsc->decoder) {
|
if(dsc->decoder) {
|
||||||
if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc);
|
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) {
|
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
|
||||||
lv_free((void *)dsc->src);
|
lv_free((void *)dsc->src);
|
||||||
@ -233,6 +229,48 @@ void lv_image_decoder_set_close_cb(lv_image_decoder_t * decoder, lv_image_decode
|
|||||||
decoder->close_cb = close_cb;
|
decoder->close_cb = close_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lv_draw_buf_t * lv_image_decoder_post_process(lv_image_decoder_dsc_t * dsc, lv_draw_buf_t * decoded)
|
||||||
|
{
|
||||||
|
if(decoded == NULL) return NULL; /*No need to adjust*/
|
||||||
|
|
||||||
|
lv_image_decoder_args_t * args = &dsc->args;
|
||||||
|
if(args->stride_align && decoded->header.cf != LV_COLOR_FORMAT_RGB565A8) {
|
||||||
|
uint32_t stride_expect = lv_draw_buf_width_to_stride(decoded->header.w, decoded->header.cf);
|
||||||
|
if(decoded->header.stride != stride_expect) {
|
||||||
|
LV_LOG_WARN("Stride mismatch");
|
||||||
|
lv_draw_buf_t * aligned = lv_draw_buf_adjust_stride(decoded, stride_expect);
|
||||||
|
if(aligned == NULL) {
|
||||||
|
LV_LOG_ERROR("No memory for Stride adjust.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
decoded = aligned;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Premultiply alpha channel*/
|
||||||
|
if(args->premultiply
|
||||||
|
&& !lv_draw_buf_has_flag(decoded, LV_IMAGE_FLAGS_PREMULTIPLIED) /*Hasn't done yet*/
|
||||||
|
) {
|
||||||
|
LV_LOG_WARN("Alpha premultiply.");
|
||||||
|
if(lv_draw_buf_has_flag(decoded, LV_IMAGE_FLAGS_MODIFIABLE)) {
|
||||||
|
/*Do it directly*/
|
||||||
|
lv_draw_buf_premultiply(decoded);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
decoded = lv_draw_buf_dup(decoded);
|
||||||
|
if(decoded == NULL) {
|
||||||
|
LV_LOG_ERROR("No memory for premulitplying.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_draw_buf_premultiply(decoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return decoded;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t img_width_to_stride(lv_image_header_t * header)
|
static uint32_t img_width_to_stride(lv_image_header_t * header)
|
||||||
{
|
{
|
||||||
if(header->cf == LV_COLOR_FORMAT_RGB565A8) {
|
if(header->cf == LV_COLOR_FORMAT_RGB565A8) {
|
||||||
@ -242,4 +280,3 @@ static uint32_t img_width_to_stride(lv_image_header_t * header)
|
|||||||
return ((uint32_t)header->w * lv_color_format_get_bpp(header->cf) + 7) >> 3;
|
return ((uint32_t)header->w * lv_color_format_get_bpp(header->cf) + 7) >> 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ typedef struct _lv_image_decoder_dsc_t {
|
|||||||
lv_image_decoder_t * decoder;
|
lv_image_decoder_t * decoder;
|
||||||
|
|
||||||
/*A copy of parameters of how this image is decoded*/
|
/*A copy of parameters of how this image is decoded*/
|
||||||
lv_image_decoder_args_t * args;
|
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*/
|
/**The image source. A file path like "S:my_img.png" or pointer to an `lv_image_dsc_t` variable*/
|
||||||
const void * src;
|
const void * src;
|
||||||
@ -268,6 +268,15 @@ void lv_image_decoder_set_get_area_cb(lv_image_decoder_t * decoder, lv_image_dec
|
|||||||
*/
|
*/
|
||||||
void lv_image_decoder_set_close_cb(lv_image_decoder_t * decoder, lv_image_decoder_close_f_t close_cb);
|
void lv_image_decoder_set_close_cb(lv_image_decoder_t * decoder, lv_image_decoder_close_f_t close_cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the decoded image, make any modification if decoder `args` requires.
|
||||||
|
* @note A new draw buf will be allocated if provided `decoded` is not modifiable or stride mismatch etc.
|
||||||
|
* @param dsc pointer to a decoder descriptor
|
||||||
|
* @param decoded pointer to a decoded image to post process to meet dsc->args requirement.
|
||||||
|
* @return post processed draw buffer, when it differs with `decoded`, it's newly allocated.
|
||||||
|
*/
|
||||||
|
lv_draw_buf_t * lv_image_decoder_post_process(lv_image_decoder_dsc_t * dsc, lv_draw_buf_t * decoded);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -132,8 +132,8 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c
|
|||||||
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 = _lv_image_decoder_get_data(&decoder_dsc);
|
||||||
blend_dsc.src_color_format = decoder_dsc.header.cf;
|
blend_dsc.src_color_format = decoder_dsc.decoded->header.cf;
|
||||||
blend_dsc.src_stride = decoder_dsc.header.stride;
|
blend_dsc.src_stride = decoder_dsc.decoded->header.stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_opa_t * circle_mask = NULL;
|
lv_opa_t * circle_mask = NULL;
|
||||||
|
@ -291,7 +291,8 @@ static void _set_paint_fill_pattern(Tvg_Paint * obj, Tvg_Canvas * canvas, const
|
|||||||
const lv_matrix_t * m)
|
const lv_matrix_t * m)
|
||||||
{
|
{
|
||||||
lv_image_decoder_dsc_t decoder_dsc;
|
lv_image_decoder_dsc_t decoder_dsc;
|
||||||
lv_result_t res = lv_image_decoder_open(&decoder_dsc, p->src, NULL);
|
lv_image_decoder_args_t args = { 0 };
|
||||||
|
lv_result_t res = lv_image_decoder_open(&decoder_dsc, p->src, &args);
|
||||||
if(res != LV_RESULT_OK) {
|
if(res != LV_RESULT_OK) {
|
||||||
LV_LOG_ERROR("Failed to open image");
|
LV_LOG_ERROR("Failed to open image");
|
||||||
return;
|
return;
|
||||||
|
@ -160,7 +160,9 @@ lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, const void * src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*For backward compatibility, all images are not premultiplied for now.*/
|
/*For backward compatibility, all images are not premultiplied for now.*/
|
||||||
header->flags &= ~LV_IMAGE_FLAGS_PREMULTIPLIED;
|
if(header->magic != LV_IMAGE_HEADER_MAGIC) {
|
||||||
|
header->flags &= ~LV_IMAGE_FLAGS_PREMULTIPLIED;
|
||||||
|
}
|
||||||
|
|
||||||
return LV_RESULT_OK;
|
return LV_RESULT_OK;
|
||||||
}
|
}
|
||||||
@ -276,24 +278,6 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
|||||||
decoded->header.stride = dsc->header.stride;
|
decoded->header.stride = dsc->header.stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo need to convert c-array image stride if not match
|
|
||||||
*
|
|
||||||
* lv_draw_buf_create(); //create new draw buf that meets requirement
|
|
||||||
* lv_draw_buf_copy(); //copy from c-array image to new draw buf
|
|
||||||
*/
|
|
||||||
uint32_t stride_expect = lv_draw_buf_width_to_stride(dsc->header.w, dsc->header.cf);
|
|
||||||
if(dsc->header.stride != stride_expect) {
|
|
||||||
LV_LOG_WARN("Stride mismatch");
|
|
||||||
#if 0
|
|
||||||
/**
|
|
||||||
* @fixme ignore for now
|
|
||||||
*/
|
|
||||||
free_decoder_data(dsc);
|
|
||||||
return LV_RESULT_INVALID;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
res = LV_RESULT_OK;
|
res = LV_RESULT_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,6 +289,22 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
|||||||
|
|
||||||
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 * adjusted = lv_image_decoder_post_process(dsc, decoded);
|
||||||
|
if(adjusted == NULL) {
|
||||||
|
free_decoder_data(dsc);
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*The adjusted draw buffer is newly allocated.*/
|
||||||
|
if(adjusted != decoded) {
|
||||||
|
free_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*/
|
||||||
|
}
|
||||||
|
|
||||||
|
dsc->decoded = adjusted;
|
||||||
|
|
||||||
/*Add it to cache*/
|
/*Add it to cache*/
|
||||||
t = lv_tick_elaps(t);
|
t = lv_tick_elaps(t);
|
||||||
lv_cache_lock();
|
lv_cache_lock();
|
||||||
|
@ -407,6 +407,20 @@ static inline lv_color_t lv_color_black(void)
|
|||||||
return lv_color_make(0x00, 0x00, 0x00);
|
return lv_color_make(0x00, 0x00, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void lv_color_premultiply(lv_color32_t * c)
|
||||||
|
{
|
||||||
|
c->red = LV_OPA_MIX2(c->red, c->alpha);
|
||||||
|
c->green = LV_OPA_MIX2(c->green, c->alpha);
|
||||||
|
c->blue = LV_OPA_MIX2(c->blue, c->alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lv_color16_premultiply(lv_color16_t * c, lv_opa_t a)
|
||||||
|
{
|
||||||
|
c->red = LV_OPA_MIX2(c->red, a);
|
||||||
|
c->green = LV_OPA_MIX2(c->green, a);
|
||||||
|
c->blue = LV_OPA_MIX2(c->blue, a);
|
||||||
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -100,13 +100,13 @@ lv_result_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_color_format_t cf, lv_ima
|
|||||||
lv_area_increase(&snapshot_area, ext_size, ext_size);
|
lv_area_increase(&snapshot_area, ext_size, ext_size);
|
||||||
|
|
||||||
lv_memzero(buf, buf_size);
|
lv_memzero(buf, buf_size);
|
||||||
lv_memzero(dsc, sizeof(lv_image_dsc_t));
|
|
||||||
dsc->data = buf;
|
dsc->data = buf;
|
||||||
dsc->data_size = buf_size_needed;
|
dsc->data_size = buf_size_needed;
|
||||||
|
/*Keep header flags unchanged, because we don't know if it's allocated or not.*/
|
||||||
dsc->header.w = w;
|
dsc->header.w = w;
|
||||||
dsc->header.h = h;
|
dsc->header.h = h;
|
||||||
dsc->header.cf = cf;
|
dsc->header.cf = cf;
|
||||||
dsc->header.flags = LV_IMAGE_FLAGS_MODIFIABLE;
|
dsc->header.magic = LV_IMAGE_HEADER_MAGIC;
|
||||||
|
|
||||||
lv_layer_t layer;
|
lv_layer_t layer;
|
||||||
lv_memzero(&layer, sizeof(layer));
|
lv_memzero(&layer, sizeof(layer));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user