diff --git a/lv_conf_template.h b/lv_conf_template.h index e3c340025..8ee14a1c4 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -43,6 +43,9 @@ /*Images pixels with this color will not be drawn (with chroma keying)*/ #define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/ +/* Enable chroma keying for indexed images. */ +#define LV_INDEXED_CHROMA 1 + /* Enable anti-aliasing (lines, and radiuses will be smoothed) */ #define LV_ANTIALIAS 1 diff --git a/src/lv_conf_checker.h b/src/lv_conf_checker.h index f78fbfaa0..9bc2b1a3b 100644 --- a/src/lv_conf_checker.h +++ b/src/lv_conf_checker.h @@ -50,6 +50,11 @@ #define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/ #endif +/* Enable chroma keying for indexed images. */ +#ifndef LV_INDEXED_CHROMA +#define LV_INDEXED_CHROMA 1 +#endif + /* Enable anti-aliasing (lines, and radiuses will be smoothed) */ #ifndef LV_ANTIALIAS #define LV_ANTIALIAS 1 diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index 6a03d9d74..65d54703d 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -401,11 +401,7 @@ bool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf) switch(cf) { case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: - case LV_IMG_CF_RAW_CHROMA_KEYED: - case LV_IMG_CF_INDEXED_1BIT: - case LV_IMG_CF_INDEXED_2BIT: - case LV_IMG_CF_INDEXED_4BIT: - case LV_IMG_CF_INDEXED_8BIT: is_chroma_keyed = true; break; + case LV_IMG_CF_RAW_CHROMA_KEYED: is_chroma_keyed = true; break; default: is_chroma_keyed = false; break; } @@ -424,6 +420,10 @@ bool lv_img_color_format_has_alpha(lv_img_cf_t cf) switch(cf) { case LV_IMG_CF_TRUE_COLOR_ALPHA: case LV_IMG_CF_RAW_ALPHA: + case LV_IMG_CF_INDEXED_1BIT: + case LV_IMG_CF_INDEXED_2BIT: + case LV_IMG_CF_INDEXED_4BIT: + case LV_IMG_CF_INDEXED_8BIT: case LV_IMG_CF_ALPHA_1BIT: case LV_IMG_CF_ALPHA_2BIT: case LV_IMG_CF_ALPHA_4BIT: diff --git a/src/lv_draw/lv_img_decoder.c b/src/lv_draw/lv_img_decoder.c index 730739c16..f6445cf55 100644 --- a/src/lv_draw/lv_img_decoder.c +++ b/src/lv_draw/lv_img_decoder.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ #include "lv_img_decoder.h" +#include "../lv_core/lv_refr.h" #include "../lv_draw/lv_draw_img.h" #include "../lv_misc/lv_ll.h" #include "../lv_misc/lv_color.h" @@ -31,6 +32,7 @@ typedef struct lv_fs_file_t * f; #endif lv_color_t * palette; + lv_opa_t * opa; } lv_img_decoder_built_in_data_t; /********************** @@ -375,7 +377,8 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder lv_img_decoder_built_in_data_t * user_data = dsc->user_data; user_data->palette = lv_mem_alloc(palette_size * sizeof(lv_color_t)); - if(user_data->palette == NULL) { + user_data->opa = lv_mem_alloc(palette_size * sizeof(lv_opa_t)); + if(user_data->palette == NULL || user_data->opa == NULL) { LV_LOG_ERROR("img_decoder_built_in_open: out of memory"); #if LV_USE_FILESYSTEM lv_mem_assert(user_data->f); @@ -386,7 +389,13 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder /*Read the palette from file*/ #if LV_USE_FILESYSTEM lv_fs_seek(user_data->f, 4); /*Skip the header*/ - lv_fs_read(user_data->f, user_data->palette, palette_size * sizeof(lv_color_t), NULL); + lv_color32_t cur_color; + uint32_t i; + for(i = 0; i < palette_size; i++) { + lv_fs_read(user_data->f, &cur_color, sizeof(lv_color32_t), NULL); + user_data->palette[i] = lv_color_make(cur_color.ch.red, cur_color.ch.green, cur_color.ch.blue); + user_data->opa[i] = cur_color.ch.alpha; + } #else LV_LOG_WARN("Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0"); return LV_RES_INV; @@ -398,9 +407,21 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder uint32_t i; for(i = 0; i < palette_size; i++) { user_data->palette[i] = lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue); + user_data->opa[i] = palette_p[i].ch.alpha; } } +#if LV_INDEXED_CHROMA + /* Set the chroma color to transparent. */ + lv_disp_t * disp = lv_refr_get_disp_refreshing(); + uint32_t i; + for(i = 0; i < palette_size; i++) { + if(user_data->palette[i].full == disp->driver.color_chroma_key.full) { + user_data->opa[i] = 0; + } + } +#endif + dsc->img_data = NULL; return LV_RES_OK; #else @@ -705,7 +726,20 @@ static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_color_t * cbuf = (lv_color_t *)buf; for(i = 0; i < len; i++) { val_act = (data_tmp[byte_act] & (mask << pos)) >> pos; - cbuf[i] = user_data->palette[val_act]; + + lv_color_t color = user_data->palette[val_act]; +#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1 + buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = color.full; +#elif LV_COLOR_DEPTH == 16 + /*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/ + buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = color.full & 0xFF; + buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (color.full >> 8) & 0xFF; +#elif LV_COLOR_DEPTH == 32 + *((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = color.full; +#else +#error "Invalid LV_COLOR_DEPTH. Check it in lv_conf.h" +#endif + buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] = user_data->opa[val_act]; pos -= px_size; if(pos < 0) {