mirror of https://github.com/arendst/Tasmota.git
lvgl use native lv_png instead of library
This commit is contained in:
parent
955d807cec
commit
636ac69a4b
|
@ -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).
|
|
@ -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" ]
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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 <limits.h> /* LONG_MAX */
|
||||
#include <stdio.h> /* 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*/
|
|
@ -28,18 +28,8 @@ freely, subject to the following restrictions:
|
|||
|
||||
#include <string.h> /*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 @@ TODO:
|
|||
[X] provide alternatives for C library functions not present on some platforms (memcpy, ...)
|
||||
*/
|
||||
|
||||
#endif /*LV_USE_PNG*/
|
||||
|
||||
#endif /*LODEPNG_H inclusion guard*/
|
||||
|
||||
/*
|
|
@ -6,19 +6,12 @@
|
|||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
#include "../../../lvgl.h"
|
||||
#if LV_USE_PNG
|
||||
|
||||
#include "lv_png.h"
|
||||
#include "lodepng.h"
|
||||
#include <stdlib.h>
|
||||
#if LV_MEM_CUSTOM != 0
|
||||
#include LV_MEM_CUSTOM_INCLUDE
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
/*********************
|
||||
* 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*/
|
||||
|
||||
|
|
@ -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" */
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue