From 28e321f223d1c479ffc68e114276de9bbd1f015f Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sun, 30 Jun 2019 22:05:28 -0400 Subject: [PATCH 1/4] Add lv_img_buf_alloc and lv_img_buf_free functions --- src/lv_draw/lv_draw_img.c | 35 +++++++++++++++++++++++++++++++++++ src/lv_draw/lv_draw_img.h | 16 ++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index 2ad32cd5e..125a99067 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -425,6 +425,41 @@ lv_img_src_t lv_img_src_get_type(const void * src) return img_src_type; } +lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) +{ + /*Get the pixel size in bytes*/ + uint8_t px_b = lv_img_color_format_get_px_size(cf) / 8; + + lv_img_dsc_t *dsc = lv_mem_alloc(sizeof(lv_img_dsc_t)); + if(dsc == NULL) + return NULL; + + memset(dsc, 0, sizeof(lv_img_dsc_t)); + dsc->data_size = px_b * w * h; + dsc->data = lv_mem_alloc(dsc->data_size); + if(dsc->data == NULL) { + lv_mem_free(dsc); + return NULL; + } + memset(dsc->data, 0, dsc->data_size); + + dsc->header.always_zero = 0; + dsc->header.w = w; + dsc->header.h = h; + dsc->header.cf = cf; + return dsc; +} + +void lv_img_buf_free(lv_img_dsc_t *dsc) +{ + if(dsc != NULL) { + if(dsc->data != NULL) + lv_mem_free(dsc->data); + + lv_mem_free(dsc); + } +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index 61c604805..fb39a4ee5 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -120,6 +120,22 @@ bool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf); */ bool lv_img_color_format_has_alpha(lv_img_cf_t cf); +/** + * Allocate an image buffer in RAM + * @param w width of image + * @param h height of image + * @param cf a color format (`LV_IMG_CF_...`) + * @return an allocated image, or NULL on failure + */ +lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf); + +/** + * Free an allocated image buffer + * @param dsc image buffer to free + */ +void lv_img_buf_free(lv_img_dsc_t *dsc); + + /********************** * MACROS **********************/ From 9ad51e529e7711464a1934530809ab1454ef3da5 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Mon, 1 Jul 2019 21:38:01 -0400 Subject: [PATCH 2/4] Add API for retrieving raw image bitmap size --- src/lv_draw/lv_draw_img.c | 15 +++++++++---- src/lv_draw/lv_draw_img.h | 47 ++++++++++++++++++++++++++++++++++++--- src/lv_objx/lv_canvas.h | 23 ++++++++++--------- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index 125a99067..9d4e7ffa6 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -427,15 +427,21 @@ lv_img_src_t lv_img_src_get_type(const void * src) lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) { - /*Get the pixel size in bytes*/ - uint8_t px_b = lv_img_color_format_get_px_size(cf) / 8; - + /* Allocate image descriptor */ lv_img_dsc_t *dsc = lv_mem_alloc(sizeof(lv_img_dsc_t)); if(dsc == NULL) return NULL; memset(dsc, 0, sizeof(lv_img_dsc_t)); - dsc->data_size = px_b * w * h; + + /* Get image data size */ + dsc->data_size = lv_img_buf_get_img_size(w, h, cf); + if(dsc->data_size == 0) { + lv_mem_free(dsc); + return NULL; + } + + /* Allocate raw buffer */ dsc->data = lv_mem_alloc(dsc->data_size); if(dsc->data == NULL) { lv_mem_free(dsc); @@ -443,6 +449,7 @@ lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) } memset(dsc->data, 0, dsc->data_size); + /* Fill in header */ dsc->header.always_zero = 0; dsc->header.w = w; dsc->header.h = h; diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index fb39a4ee5..a3cb56a27 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -20,6 +20,26 @@ extern "C" { * DEFINES *********************/ +/********************** + * MACROS + **********************/ + +#define LV_IMG_BUF_SIZE_TRUE_COLOR(w, h) ((LV_COLOR_SIZE / 8) * w * h) +#define LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) ((LV_COLOR_SIZE / 8) * w * h) +#define LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h) + +/*+ 1: to be sure no fractional row*/ +#define LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) ((((w / 8) + 1) * h)) +#define LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) ((((w / 4) + 1) * h)) +#define LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) ((((w / 2) + 1) * h)) +#define LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) ((w * h)) + +/*4 * X: for palette*/ +#define LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2) +#define LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) + 4 * 4) +#define LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) + 4 * 16) +#define LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) + 4 * 256) + /********************** * TYPEDEFS **********************/ @@ -135,10 +155,31 @@ lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf); */ void lv_img_buf_free(lv_img_dsc_t *dsc); +/** + * Get the memory consumption of a raw bitmap, given color format and dimensions. + * @param w width + * @param h height + * @param cf color format + * @return size in bytes + */ +static inline size_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) +{ + switch(cf) { + case LV_IMG_CF_TRUE_COLOR: return LV_IMG_BUF_SIZE_TRUE_COLOR(w, h); + case LV_IMG_CF_TRUE_COLOR_ALPHA: return LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h); + case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: return LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h); + case LV_IMG_CF_ALPHA_1BIT: return LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h); + case LV_IMG_CF_ALPHA_2BIT: return LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h); + case LV_IMG_CF_ALPHA_4BIT: return LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h); + case LV_IMG_CF_ALPHA_8BIT: return LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h); + case LV_IMG_CF_INDEXED_1BIT: return LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h); + case LV_IMG_CF_INDEXED_2BIT: return LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h); + case LV_IMG_CF_INDEXED_4BIT: return LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h); + case LV_IMG_CF_INDEXED_8BIT: return LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h); + default: return 0; + } +} -/********************** - * MACROS - **********************/ #ifdef __cplusplus } /* extern "C" */ diff --git a/src/lv_objx/lv_canvas.h b/src/lv_objx/lv_canvas.h index 1d59d44d6..9f9cf03ed 100644 --- a/src/lv_objx/lv_canvas.h +++ b/src/lv_objx/lv_canvas.h @@ -23,6 +23,7 @@ extern "C" { #include "../lv_core/lv_obj.h" #include "../lv_objx/lv_img.h" +#include "../lv_draw/lv_draw_img.h" /********************* * DEFINES @@ -239,21 +240,21 @@ void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_ /********************** * MACROS **********************/ -#define LV_CANVAS_BUF_SIZE_TRUE_COLOR(w, h) ((LV_COLOR_SIZE / 8) * w * h) -#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) ((LV_COLOR_SIZE / 8) * w * h) -#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h) +#define LV_CANVAS_BUF_SIZE_TRUE_COLOR(w, h) LV_IMG_BUF_SIZE_TRUE_COLOR(w, h) +#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) +#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) /*+ 1: to be sure no fractional row*/ -#define LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w, h) ((((w / 8) + 1) * h)) -#define LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w, h) ((((w / 4) + 1) * h)) -#define LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w, h) ((((w / 2) + 1) * h)) -#define LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w, h) ((w * h)) +#define LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w, h) LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) +#define LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w, h) LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) +#define LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w, h) LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) +#define LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w, h) LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) /*4 * X: for palette*/ -#define LV_CANVAS_BUF_SIZE_INDEXED_1BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2) -#define LV_CANVAS_BUF_SIZE_INDEXED_2BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w, h) + 4 * 4) -#define LV_CANVAS_BUF_SIZE_INDEXED_4BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w, h) + 4 * 16) -#define LV_CANVAS_BUF_SIZE_INDEXED_8BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w, h) + 4 * 256) +#define LV_CANVAS_BUF_SIZE_INDEXED_1BIT(w, h) LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h) +#define LV_CANVAS_BUF_SIZE_INDEXED_2BIT(w, h) LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h) +#define LV_CANVAS_BUF_SIZE_INDEXED_4BIT(w, h) LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h) +#define LV_CANVAS_BUF_SIZE_INDEXED_8BIT(w, h) LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h) #endif /*LV_USE_CANVAS*/ From 27155720d5243988be905cba20f8536364b528cc Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Tue, 2 Jul 2019 14:26:52 -0400 Subject: [PATCH 3/4] Switch from size_t to uint32_t --- src/lv_draw/lv_draw_img.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index a3cb56a27..6c9589f7f 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -162,7 +162,7 @@ void lv_img_buf_free(lv_img_dsc_t *dsc); * @param cf color format * @return size in bytes */ -static inline size_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) +static inline uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) { switch(cf) { case LV_IMG_CF_TRUE_COLOR: return LV_IMG_BUF_SIZE_TRUE_COLOR(w, h); From 55740d2a96aabc934a775d5da207e5d9ae8cfb2e Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Wed, 3 Jul 2019 09:47:08 -0400 Subject: [PATCH 4/4] Move lv_img_buf_get_img_size to C file instead of inlining --- src/lv_draw/lv_draw_img.c | 18 ++++++++++++++++++ src/lv_draw/lv_draw_img.h | 18 +----------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index 9d4e7ffa6..2475836a5 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -467,6 +467,24 @@ void lv_img_buf_free(lv_img_dsc_t *dsc) } } +uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) +{ + switch(cf) { + case LV_IMG_CF_TRUE_COLOR: return LV_IMG_BUF_SIZE_TRUE_COLOR(w, h); + case LV_IMG_CF_TRUE_COLOR_ALPHA: return LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h); + case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: return LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h); + case LV_IMG_CF_ALPHA_1BIT: return LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h); + case LV_IMG_CF_ALPHA_2BIT: return LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h); + case LV_IMG_CF_ALPHA_4BIT: return LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h); + case LV_IMG_CF_ALPHA_8BIT: return LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h); + case LV_IMG_CF_INDEXED_1BIT: return LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h); + case LV_IMG_CF_INDEXED_2BIT: return LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h); + case LV_IMG_CF_INDEXED_4BIT: return LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h); + case LV_IMG_CF_INDEXED_8BIT: return LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h); + default: return 0; + } +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index 6c9589f7f..794dd79e6 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -162,23 +162,7 @@ void lv_img_buf_free(lv_img_dsc_t *dsc); * @param cf color format * @return size in bytes */ -static inline uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) -{ - switch(cf) { - case LV_IMG_CF_TRUE_COLOR: return LV_IMG_BUF_SIZE_TRUE_COLOR(w, h); - case LV_IMG_CF_TRUE_COLOR_ALPHA: return LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h); - case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: return LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h); - case LV_IMG_CF_ALPHA_1BIT: return LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h); - case LV_IMG_CF_ALPHA_2BIT: return LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h); - case LV_IMG_CF_ALPHA_4BIT: return LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h); - case LV_IMG_CF_ALPHA_8BIT: return LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h); - case LV_IMG_CF_INDEXED_1BIT: return LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h); - case LV_IMG_CF_INDEXED_2BIT: return LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h); - case LV_IMG_CF_INDEXED_4BIT: return LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h); - case LV_IMG_CF_INDEXED_8BIT: return LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h); - default: return 0; - } -} +uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf); #ifdef __cplusplus