From 636ac69a4b7eeb023e2c53f067cb7f8c65a571d5 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 12 Jan 2022 22:17:55 +0100 Subject: [PATCH] lvgl use native lv_png instead of library --- lib/libesp32_lvgl/lv_lib_png/README.md | 50 -------------- lib/libesp32_lvgl/lv_lib_png/library.json | 21 ------ .../lvgl/src/extra/libs/lv_libs.h | 2 +- .../src => lvgl/src/extra/libs/png}/lodepng.c | 65 +++++++----------- .../src => lvgl/src/extra/libs/png}/lodepng.h | 16 ++--- .../src => lvgl/src/extra/libs/png}/lv_png.c | 66 ++++++++----------- .../src => lvgl/src/extra/libs/png}/lv_png.h | 3 + tasmota/lvgl_berry/tasmota_lv_conf.h | 2 +- tasmota/xdrv_54_lvgl.ino | 4 -- 9 files changed, 58 insertions(+), 171 deletions(-) delete mode 100644 lib/libesp32_lvgl/lv_lib_png/README.md delete mode 100644 lib/libesp32_lvgl/lv_lib_png/library.json rename lib/libesp32_lvgl/{lv_lib_png/src => lvgl/src/extra/libs/png}/lodepng.c (99%) rename lib/libesp32_lvgl/{lv_lib_png/src => lvgl/src/extra/libs/png}/lodepng.h (99%) rename lib/libesp32_lvgl/{lv_lib_png/src => lvgl/src/extra/libs/png}/lv_png.c (85%) rename lib/libesp32_lvgl/{lv_lib_png/src => lvgl/src/extra/libs/png}/lv_png.h (88%) diff --git a/lib/libesp32_lvgl/lv_lib_png/README.md b/lib/libesp32_lvgl/lv_lib_png/README.md deleted file mode 100644 index 693de2b5171b..000000000000 --- a/lib/libesp32_lvgl/lv_lib_png/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# PNG decoder for LVGL - -Allow the use of PNG images in LVGL. This implementation uses [lodepng](https://github.com/lvandeve/lodepng) library. - -## Get started -- Download or clone this repository - - [Download from GitHub](https://github.com/littlevgl/lv_lib_lodepng/archive/master.zip) - - Clone: `git clone https://github.com/littlevgl/lv_lib_png.git` -- Include the library: `#include "lv_lib_png/lv_png.h"` -- Initalize the decocer with `lv_png_init()` -- Test with the following code: -```c - LV_IMG_DECLARE(png_decoder_test); - lv_obj_t * img = lv_img_create(lv_scr_act(), NULL); - lv_img_set_src(img, &png_decoder_test); -``` - -## Use PNG images from file -By deafult `lodepng` uses C file IO API (e.g. `fopen`) and images can be opened like this: -```c -lv_img_set_src(img, "./lv_lib_lodepng/png_decoder_test.png"); -``` - -If you want to make `lodepng` to use LVGL's file system API add `#define LV_PNG_USE_LV_FILESYSTEM 1` to the end of your`lv_conf.h`. -In this case you need to [register a driver](https://docs.lvgl.io/latest/en/html/overview/file-system.html) fo LVGL. The following functions are required: -- `open_cb()` -- `read_cb()` -- `close_cb()` -- `size_cb()` - -After that fiels can be opened like this: -```c -lv_img_set_src(img, "P:lv_lib_lodepng/png_decoder_test.png"); -``` - - -Note that the path of the file might be different. - -## Use PNG images from flash -To store a PNG image in flash it needs to be converted to C array with [Online Image converter](https://lvgl.io/tools/imageconverter). Choose `Raw with alpha` Color format and `C array` Output format. Copy the result C array to your project and use it like this: -```c - LV_IMG_DECLARE(my_test_img); - lv_obj_t * img = lv_img_create(lv_scr_act(), NULL); - lv_img_set_src(img, &my_test_img); -``` - -## Learn more -To learn more about the PNG decoder itself read [this blog post](https://blog.littlevgl.com/2018-10-05/png_converter) - -To learn more about the Image decoder interface of LittlevGL read the realevant part of the [documentation](https://docs.littlevgl.com/en/html/overview/image.html#image-decoder). diff --git a/lib/libesp32_lvgl/lv_lib_png/library.json b/lib/libesp32_lvgl/lv_lib_png/library.json deleted file mode 100644 index 61e9720e32f2..000000000000 --- a/lib/libesp32_lvgl/lv_lib_png/library.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name":"lv_lib_png", - "description":"Allow the use of PNG images in LVGL. This implementation uses lodepng library.", - "keywords":"lvgl, png", - "license": "MIT License", - "repository": { - "type": "git", - "url": "https://github.com/lvgl/lv_lib_png" - }, - "frameworks": "arduino", - "platforms": "espressif32", - "build": { - "flags": [ "-DLV_PNG_USE_LV_FILESYSTEM=1", - "-DLODEPNG_NO_COMPILE_ALLOCATORS", - "-DLODEPNG_NO_COMPILE_ERROR_TEXT", - "-DLODEPNG_NO_COMPILE_ANCILLARY_CHUNKS", - "-DLV_LVGL_H_INCLUDE_SIMPLE", - "-I$PROJECT_DIR/include", - "-includetasmota_options.h" ] - } -} \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/extra/libs/lv_libs.h b/lib/libesp32_lvgl/lvgl/src/extra/libs/lv_libs.h index 2e87b4320afb..c8e4fbb91ead 100644 --- a/lib/libesp32_lvgl/lvgl/src/extra/libs/lv_libs.h +++ b/lib/libesp32_lvgl/lvgl/src/extra/libs/lv_libs.h @@ -16,7 +16,7 @@ extern "C" { // TODO Tasmota // #include "bmp/lv_bmp.h" // #include "fsdrv/lv_fsdrv.h" -// #include "png/lv_png.h" +#include "png/lv_png.h" // #include "gif/lv_gif.h" // #include "qrcode/lv_qrcode.h" // #include "sjpg/lv_sjpg.h" diff --git a/lib/libesp32_lvgl/lv_lib_png/src/lodepng.c b/lib/libesp32_lvgl/lvgl/src/extra/libs/png/lodepng.c similarity index 99% rename from lib/libesp32_lvgl/lv_lib_png/src/lodepng.c rename to lib/libesp32_lvgl/lvgl/src/extra/libs/png/lodepng.c index 6c1facd2afc3..65139bc5b489 100644 --- a/lib/libesp32_lvgl/lv_lib_png/src/lodepng.c +++ b/lib/libesp32_lvgl/lvgl/src/extra/libs/png/lodepng.c @@ -29,10 +29,10 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for */ #include "lodepng.h" +#if LV_USE_PNG #ifdef LODEPNG_COMPILE_DISK #include /* LONG_MAX */ -#include /* file handling */ #endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ALLOCATORS @@ -75,7 +75,7 @@ static void* lodepng_malloc(size_t size) { #ifdef LODEPNG_MAX_ALLOC if(size > LODEPNG_MAX_ALLOC) return 0; #endif - return malloc(size); + return lv_mem_alloc(size); } /* NOTE: when realloc returns NULL, it leaves the original memory untouched */ @@ -83,11 +83,11 @@ static void* lodepng_realloc(void* ptr, size_t new_size) { #ifdef LODEPNG_MAX_ALLOC if(new_size > LODEPNG_MAX_ALLOC) return 0; #endif - return realloc(ptr, new_size); + return lv_mem_realloc(ptr, new_size); } static void lodepng_free(void* ptr) { - free(ptr); + lv_mem_free(ptr); } #else /*LODEPNG_COMPILE_ALLOCATORS*/ /* TODO: support giving additional void* payload to the custom allocators */ @@ -343,12 +343,11 @@ static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) { /* returns negative value on error. This should be pure C compatible, so no fstat. */ static long lodepng_filesize(const char* filename) { -#if LV_PNG_USE_LV_FILESYSTEM lv_fs_file_t f; lv_fs_res_t res = lv_fs_open(&f, filename, LV_FS_MODE_RD); if(res != LV_FS_RES_OK) return -1; uint32_t size = 0; - if(lv_fs_seek(&f, 0, SEEK_END) != 0) { + if(lv_fs_seek(&f, 0, LV_FS_SEEK_END) != 0) { lv_fs_close(&f); return -1; } @@ -356,29 +355,10 @@ static long lodepng_filesize(const char* filename) { lv_fs_tell(&f, &size); lv_fs_close(&f); return size; -#else - FILE* file; - long size; - file = fopen(filename, "rb"); - if(!file) return -1; - - if(fseek(file, 0, SEEK_END) != 0) { - fclose(file); - return -1; - } - - size = ftell(file); - /* It may give LONG_MAX as directory size, this is invalid for us. */ - if(size == LONG_MAX) size = -1; - - fclose(file); - return size; -#endif } /* load file into buffer that already has the correct allocated size. Returns error code.*/ static unsigned lodepng_buffer_file(unsigned char* out, size_t size, const char* filename) { -#if LV_PNG_USE_LV_FILESYSTEM lv_fs_file_t f; lv_fs_res_t res = lv_fs_open(&f, filename, LV_FS_MODE_RD); if(res != LV_FS_RES_OK) return 78; @@ -389,18 +369,6 @@ static unsigned lodepng_buffer_file(unsigned char* out, size_t size, const char* if (br != size) return 78; lv_fs_close(&f); return 0; -#else - FILE* file; - size_t readsize; - file = fopen(filename, "rb"); - if(!file) return 78; - - readsize = fread(out, 1, size, file); - fclose(file); - - if(readsize != size) return 78; - return 0; -#endif } unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) { @@ -416,11 +384,13 @@ unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* fil /*write given buffer to the file, overwriting the file, it doesn't append to it.*/ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) { - FILE* file; - file = fopen(filename, "wb" ); - if(!file) return 79; - fwrite(buffer, 1, buffersize, file); - fclose(file); + lv_fs_file_t f; + lv_fs_res_t res = lv_fs_open(&f, filename, LV_FS_MODE_WR); + if(res != LV_FS_RES_OK) return 79; + + uint32_t bw; + res = lv_fs_write(&f, buffer, buffersize, &bw); + lv_fs_close(&f); return 0; } @@ -611,6 +581,7 @@ static unsigned readBits(LodePNGBitReader* reader, size_t nbits) { return result; } +#if 0 /*Disable because tests fail due to unused declaration*/ /* Public for testing only. steps and result must have numsteps values. */ static unsigned lode_png_test_bitreader(const unsigned char* data, size_t size, size_t numsteps, const size_t* steps, unsigned* result) { @@ -630,6 +601,8 @@ static unsigned lode_png_test_bitreader(const unsigned char* data, size_t size, } return 1; } +#endif + #endif /*LODEPNG_COMPILE_DECODER*/ static unsigned reverseBits(unsigned bits, unsigned num) { @@ -2337,7 +2310,7 @@ static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsign static unsigned zlib_decompress(unsigned char** out, size_t* outsize, size_t expected_size, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ - (void)expected_size; + LV_UNUSED(expected_size); return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -2579,6 +2552,8 @@ unsigned char* lodepng_chunk_find(unsigned char* chunk, unsigned char* end, cons if(lodepng_chunk_type_equals(chunk, type)) return chunk; chunk = lodepng_chunk_next(chunk, end); } + + return 0; /*Shouldn't reach this*/ } const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]) { @@ -2587,6 +2562,8 @@ const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const if(lodepng_chunk_type_equals(chunk, type)) return chunk; chunk = lodepng_chunk_next_const(chunk, end); } + + return 0; /*Shouldn't reach this*/ } unsigned lodepng_chunk_append(unsigned char** out, size_t* outsize, const unsigned char* chunk) { @@ -6490,3 +6467,5 @@ unsigned encode(const std::string& filename, #endif /* LODEPNG_COMPILE_PNG */ } /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ + +#endif /*LV_USE_PNG*/ diff --git a/lib/libesp32_lvgl/lv_lib_png/src/lodepng.h b/lib/libesp32_lvgl/lvgl/src/extra/libs/png/lodepng.h similarity index 99% rename from lib/libesp32_lvgl/lv_lib_png/src/lodepng.h rename to lib/libesp32_lvgl/lvgl/src/extra/libs/png/lodepng.h index 75bffe245029..dbfed72e5cd1 100644 --- a/lib/libesp32_lvgl/lv_lib_png/src/lodepng.h +++ b/lib/libesp32_lvgl/lvgl/src/extra/libs/png/lodepng.h @@ -28,18 +28,8 @@ freely, subject to the following restrictions: #include /*for size_t*/ -#ifndef LV_PNG_USE_LV_FILESYSTEM -#define LV_PNG_USE_LV_FILESYSTEM 0 -#endif - -#if LV_PNG_USE_LV_FILESYSTEM -#if defined(LV_LVGL_H_INCLUDE_SIMPLE) -#include "lvgl.h" -#else -#include "lvgl/lvgl.h" -#endif -#endif /* LV_PNG_USE_LV_FILESYSTEM */ - +#include "../../../lvgl.h" +#if LV_USE_PNG extern const char* LODEPNG_VERSION_STRING; /* @@ -1095,6 +1085,8 @@ unsigned compress(std::vector& out, const std::vector -#if LV_MEM_CUSTOM != 0 - #include LV_MEM_CUSTOM_INCLUDE -#endif -#include /********************* * DEFINES @@ -84,7 +77,6 @@ static lv_res_t decoder_info(struct _lv_img_decoder_t * decoder, const void * sr * [24..27]: height */ uint32_t size[2]; -#if LV_PNG_USE_LV_FILESYSTEM lv_fs_file_t f; lv_fs_res_t res = lv_fs_open(&f, fn, LV_FS_MODE_RD); if(res != LV_FS_RES_OK) return LV_RES_INV; @@ -93,15 +85,6 @@ static lv_res_t decoder_info(struct _lv_img_decoder_t * decoder, const void * sr lv_fs_read(&f, &size, 8, &rn); if(rn != 8) return LV_RES_INV; lv_fs_close(&f); -#else - FILE* file; - file = fopen(fn, "rb" ); - if(!file) return LV_RES_INV; - fseek(file, 16, SEEK_SET); - size_t rn = fread(size, 1 , 8, file); - fclose(file); - if(rn != 8) return LV_RES_INV; -#endif /*Save the data in the header*/ header->always_zero = 0; header->cf = LV_IMG_CF_RAW_ALPHA; @@ -152,11 +135,7 @@ static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * error = lodepng_load_file(&png_data, &png_data_size, fn); /*Load the file*/ if(error) { -#ifdef LODEPNG_COMPILE_ERROR_TEXT - LV_LOG_ERROR("lv_png error %u: %s\n", error, lodepng_error_text(error)); -#else - LV_LOG_ERROR("lv_png error %u\n", error); -#endif + LV_LOG_WARN("error %u: %s\n", error, lodepng_error_text(error)); return LV_RES_INV; } @@ -166,13 +145,9 @@ static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * /*Decode the loaded image in ARGB8888 */ error = lodepng_decode32(&img_data, &png_width, &png_height, png_data, png_data_size); - LV_MEM_CUSTOM_FREE(png_data); /*Free the loaded file*/ + lv_mem_free(png_data); /*Free the loaded file*/ if(error) { -#ifdef LODEPNG_COMPILE_ERROR_TEXT - LV_LOG_ERROR("lv_png error %u: %s\n", error, lodepng_error_text(error)); -#else - LV_LOG_ERROR("lv_png error %u\n", error); -#endif + LV_LOG_WARN("error %u: %s\n", error, lodepng_error_text(error)); return LV_RES_INV; } @@ -210,8 +185,11 @@ static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * */ static void decoder_close(lv_img_decoder_t *decoder, lv_img_decoder_dsc_t *dsc) { - (void) decoder; /*Unused*/ - if(dsc->img_data) LV_MEM_CUSTOM_FREE((uint8_t *)dsc->img_data); + LV_UNUSED(decoder); /*Unused*/ + if (dsc->img_data) { + lv_mem_free((uint8_t *)dsc->img_data); + dsc->img_data = NULL; + } } /** @@ -243,15 +221,25 @@ static void convert_color_depth(uint8_t * img, uint32_t px_cnt) } #elif LV_COLOR_DEPTH == 8 lv_color32_t * img_argb = (lv_color32_t*)img; - lv_color_t c; - uint32_t i; - for(i = 0; i < px_cnt; i++) { - c = lv_color_make(img_argb[i].red, img_argb[i].green, img_argb[i].blue); - img[i*2 + 1] = img_argb[i].alpha; - img[i*2 + 0] = c.full - } + lv_color_t c; + uint32_t i; + for(i = 0; i < px_cnt; i++) { + c = lv_color_make(img_argb[i].ch.red, img_argb[i].ch.green, img_argb[i].ch.blue); + img[i*2 + 1] = img_argb[i].ch.alpha; + img[i*2 + 0] = c.full; + } +#elif LV_COLOR_DEPTH == 1 + lv_color32_t * img_argb = (lv_color32_t*)img; + uint8_t b; + uint32_t i; + for(i = 0; i < px_cnt; i++) { + b = img_argb[i].ch.red | img_argb[i].ch.green | img_argb[i].ch.blue; + img[i*2 + 1] = img_argb[i].ch.alpha; + img[i*2 + 0] = b > 128 ? 1 : 0; + } #endif } +#endif /*LV_USE_PNG*/ diff --git a/lib/libesp32_lvgl/lv_lib_png/src/lv_png.h b/lib/libesp32_lvgl/lvgl/src/extra/libs/png/lv_png.h similarity index 88% rename from lib/libesp32_lvgl/lv_lib_png/src/lv_png.h rename to lib/libesp32_lvgl/lvgl/src/extra/libs/png/lv_png.h index d47f77fad917..1e9b02d65697 100644 --- a/lib/libesp32_lvgl/lv_lib_png/src/lv_png.h +++ b/lib/libesp32_lvgl/lvgl/src/extra/libs/png/lv_png.h @@ -13,6 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ +#include "../../../lv_conf_internal.h" +#if LV_USE_PNG /********************* * DEFINES @@ -35,6 +37,7 @@ void lv_png_init(void); * MACROS **********************/ +#endif /*LV_USE_PNG*/ #ifdef __cplusplus } /* extern "C" */ diff --git a/tasmota/lvgl_berry/tasmota_lv_conf.h b/tasmota/lvgl_berry/tasmota_lv_conf.h index 0c6975c40cfa..63afa7ec9ded 100644 --- a/tasmota/lvgl_berry/tasmota_lv_conf.h +++ b/tasmota/lvgl_berry/tasmota_lv_conf.h @@ -555,7 +555,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ #define LV_USE_FS_FATFS '\0' /*Uses f_open, f_read, etc*/ /*PNG decoder library*/ -#define LV_USE_PNG 0 +#define LV_USE_PNG 1 /*BMP decoder library*/ #define LV_USE_BMP 0 diff --git a/tasmota/xdrv_54_lvgl.ino b/tasmota/xdrv_54_lvgl.ino index d36a8f098192..763c55b54389 100644 --- a/tasmota/xdrv_54_lvgl.ino +++ b/tasmota/xdrv_54_lvgl.ino @@ -32,10 +32,6 @@ #include "Adafruit_LvGL_Glue.h" -#ifdef USE_LVGL_PNG_DECODER - #include "lv_png.h" -#endif // USE_LVGL_PNG_DECODER - #ifdef USE_LVGL_FREETYPE #include "lv_freetype.h" #endif // USE_LVGL_FREETYPE