mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
feat(libs): add libpng decoder (#4569)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
parent
2f67d804ce
commit
9937138392
3
Kconfig
3
Kconfig
@ -1011,6 +1011,9 @@ menu "LVGL configuration"
|
||||
config LV_USE_LODEPNG
|
||||
bool "PNG decoder library"
|
||||
|
||||
config LV_USE_LIBPNG
|
||||
bool "PNG decoder(libpng) library"
|
||||
|
||||
config LV_USE_BMP
|
||||
bool "BMP decoder library"
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
tjpgd
|
||||
libjpeg_turbo
|
||||
lodepng
|
||||
libpng
|
||||
gif
|
||||
freetype
|
||||
tiny_ttf
|
||||
|
42
docs/libs/libpng.rst
Normal file
42
docs/libs/libpng.rst
Normal file
@ -0,0 +1,42 @@
|
||||
==============
|
||||
libpng decoder
|
||||
==============
|
||||
|
||||
libpng is the official PNG reference library. It supports almost all PNG features, is extensible, and has been extensively tested for over 28 years.
|
||||
Detailed introduction: `libpng <http://www.libpng.org/pub/png/libpng.html>`__.
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
.. code:: bash
|
||||
|
||||
sudo apt install libpng-dev
|
||||
|
||||
Add libpng to your project
|
||||
--------------------------
|
||||
|
||||
.. code:: cmake
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
include_directories(${PNG_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${PNG_LIBRARIES})
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_LIBPNG` in ``lv_conf.h``.
|
||||
|
||||
See the examples below.
|
||||
It should be noted that each image of this decoder needs to consume ``image width x image height x 4`` bytes of RAM,
|
||||
and it needs to be combined with the ref:`image-caching` feature to ensure that the memory usage is within a reasonable range.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/libpng/index.rst
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`libpng`
|
||||
|
6
examples/libs/libpng/index.rst
Normal file
6
examples/libs/libpng/index.rst
Normal file
@ -0,0 +1,6 @@
|
||||
Open a PNG image from file
|
||||
--------------------------
|
||||
|
||||
.. lv_example:: libs/libpng/lv_example_libpng_1
|
||||
:language: c
|
||||
|
38
examples/libs/libpng/lv_example_libpng.h
Normal file
38
examples/libs/libpng/lv_example_libpng.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file lv_example_libpng.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EXAMPLE_LIBPNG_H
|
||||
#define LV_EXAMPLE_LIBPNG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_example_libpng_1(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_EXAMPLE_LIBPNG_H*/
|
31
examples/libs/libpng/lv_example_libpng_1.c
Normal file
31
examples/libs/libpng/lv_example_libpng_1.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES
|
||||
|
||||
#if LV_USE_LIBPNG
|
||||
|
||||
/**
|
||||
* Open a PNG image from a file
|
||||
*/
|
||||
void lv_example_libpng_1(void)
|
||||
{
|
||||
lv_obj_t * img;
|
||||
|
||||
img = lv_image_create(lv_scr_act());
|
||||
/* Assuming a File system is attached to letter 'A'
|
||||
* E.g. set LV_USE_FS_STDIO 'A' in lv_conf.h */
|
||||
lv_image_set_src(img, "A:lvgl/examples/libs/libpng/png_demo.png");
|
||||
lv_obj_center(img);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void lv_example_libpng_1(void)
|
||||
{
|
||||
lv_obj_t * label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "LibPNG is not installed");
|
||||
lv_obj_center(label);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
11
examples/libs/libpng/lv_example_libpng_1.py
Executable file
11
examples/libs/libpng/lv_example_libpng_1.py
Executable file
@ -0,0 +1,11 @@
|
||||
#!/opt/bin/lv_micropython -i
|
||||
import lvgl as lv
|
||||
import display_driver
|
||||
import fs_driver
|
||||
|
||||
fs_drv = lv.fs_drv_t()
|
||||
fs_driver.fs_register(fs_drv, 'S')
|
||||
|
||||
image = lv.image(lv.scr_act())
|
||||
image.set_src("S:png_demo.png")
|
||||
image.center()
|
BIN
examples/libs/libpng/png_demo.png
Normal file
BIN
examples/libs/libpng/png_demo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
@ -19,6 +19,7 @@ extern "C" {
|
||||
#include "freetype/lv_example_freetype.h"
|
||||
#include "gif/lv_example_gif.h"
|
||||
#include "lodepng/lv_example_lodepng.h"
|
||||
#include "libpng/lv_example_libpng.h"
|
||||
#include "qrcode/lv_example_qrcode.h"
|
||||
#include "rlottie/lv_example_rlottie.h"
|
||||
#include "tjpgd/lv_example_tjpgd.h"
|
||||
|
@ -579,6 +579,9 @@
|
||||
/*LODEPNG decoder library*/
|
||||
#define LV_USE_LODEPNG 0
|
||||
|
||||
/*PNG decoder(libpng) library*/
|
||||
#define LV_USE_LIBPNG 0
|
||||
|
||||
/*BMP decoder library*/
|
||||
#define LV_USE_BMP 0
|
||||
|
||||
|
1
lvgl.h
1
lvgl.h
@ -93,6 +93,7 @@ extern "C" {
|
||||
#include "src/libs/bmp/lv_bmp.h"
|
||||
#include "src/libs/fsdrv/lv_fsdrv.h"
|
||||
#include "src/libs/lodepng/lv_lodepng.h"
|
||||
#include "src/libs/libpng/lv_libpng.h"
|
||||
#include "src/libs/gif/lv_gif.h"
|
||||
#include "src/libs/qrcode/lv_qrcode.h"
|
||||
#include "src/libs/tjpgd/lv_tjpgd.h"
|
||||
|
304
src/libs/libpng/lv_libpng.c
Normal file
304
src/libs/libpng/lv_libpng.c
Normal file
@ -0,0 +1,304 @@
|
||||
/**
|
||||
* @file lv_libpng.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lvgl.h"
|
||||
#if LV_USE_LIBPNG
|
||||
|
||||
#include "lv_libpng.h"
|
||||
#include <png.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header);
|
||||
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
|
||||
static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
|
||||
static const void * decode_png_file(const char * filename);
|
||||
static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Register the PNG decoder functions in LVGL
|
||||
*/
|
||||
void lv_libpng_init(void)
|
||||
{
|
||||
lv_image_decoder_t * dec = lv_image_decoder_create();
|
||||
lv_image_decoder_set_info_cb(dec, decoder_info);
|
||||
lv_image_decoder_set_open_cb(dec, decoder_open);
|
||||
lv_image_decoder_set_close_cb(dec, decoder_close);
|
||||
}
|
||||
|
||||
void lv_libpng_deinit(void)
|
||||
{
|
||||
lv_image_decoder_t * dec = NULL;
|
||||
while((dec = lv_image_decoder_get_next(dec)) != NULL) {
|
||||
if(dec->info_cb == decoder_info) {
|
||||
lv_image_decoder_delete(dec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get info about a PNG image
|
||||
* @param src can be file name or pointer to a C array
|
||||
* @param header store the info here
|
||||
* @return LV_RESULT_OK: no error; LV_RESULT_INVALID: can't get the info
|
||||
*/
|
||||
static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header)
|
||||
{
|
||||
LV_UNUSED(decoder); /*Unused*/
|
||||
lv_image_src_t src_type = lv_image_src_get_type(src); /*Get the source type*/
|
||||
|
||||
/*If it's a PNG file...*/
|
||||
if(src_type == LV_IMAGE_SRC_FILE) {
|
||||
const char * fn = src;
|
||||
|
||||
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_RESULT_INVALID;
|
||||
|
||||
/* Read the width and height from the file. They have a constant location:
|
||||
* [16..19]: width
|
||||
* [20..23]: height
|
||||
*/
|
||||
uint8_t buf[24];
|
||||
uint32_t rn;
|
||||
lv_fs_read(&f, buf, sizeof(buf), &rn);
|
||||
lv_fs_close(&f);
|
||||
|
||||
if(rn != sizeof(buf)) return LV_RESULT_INVALID;
|
||||
|
||||
const uint8_t magic[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
|
||||
if(memcmp(buf, magic, sizeof(magic)) != 0) return LV_RESULT_INVALID;
|
||||
|
||||
uint32_t * size = (uint32_t *)&buf[16];
|
||||
/*Save the data in the header*/
|
||||
header->always_zero = 0;
|
||||
header->cf = LV_COLOR_FORMAT_ARGB8888;
|
||||
/*The width and height are stored in Big endian format so convert them to little endian*/
|
||||
header->w = (lv_coord_t)((size[0] & 0xff000000) >> 24) + ((size[0] & 0x00ff0000) >> 8);
|
||||
header->h = (lv_coord_t)((size[1] & 0xff000000) >> 24) + ((size[1] & 0x00ff0000) >> 8);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
return LV_RESULT_INVALID; /*If didn't succeeded earlier then it's an error*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open a PNG image and return the decided image
|
||||
* @param src can be file name or pointer to a C array
|
||||
* @param style style of the image object (unused now but certain formats might use it)
|
||||
* @return pointer to the decoded image or `LV_IMAGE_DECODER_OPEN_FAIL` if failed
|
||||
*/
|
||||
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
|
||||
{
|
||||
LV_UNUSED(decoder); /*Unused*/
|
||||
|
||||
/*Check the cache first*/
|
||||
if(try_cache(dsc) == LV_RESULT_OK) return LV_RESULT_OK;
|
||||
|
||||
/*If it's a PNG file...*/
|
||||
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
|
||||
const char * fn = dsc->src;
|
||||
lv_cache_lock();
|
||||
lv_cache_entry_t * cache = lv_cache_add(dsc->header.w * dsc->header.h * sizeof(uint32_t));
|
||||
if(cache == NULL) {
|
||||
lv_cache_unlock();
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
uint32_t t = lv_tick_get();
|
||||
const void * decoded_img = decode_png_file(fn);
|
||||
t = lv_tick_elaps(t);
|
||||
cache->weight = t;
|
||||
cache->data = decoded_img;
|
||||
cache->free_data = 1;
|
||||
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
|
||||
cache->src = lv_strdup(dsc->src);
|
||||
cache->src_type = LV_CACHE_SRC_TYPE_STR;
|
||||
cache->free_src = 1;
|
||||
}
|
||||
else {
|
||||
cache->src_type = LV_CACHE_SRC_TYPE_PTR;
|
||||
cache->src = dsc->src;
|
||||
}
|
||||
|
||||
dsc->img_data = lv_cache_get_data(cache);
|
||||
dsc->user_data = cache;
|
||||
|
||||
lv_cache_unlock();
|
||||
return LV_RESULT_OK; /*The image is fully decoded. Return with its pointer*/
|
||||
}
|
||||
|
||||
return LV_RESULT_INVALID; /*If not returned earlier then it failed*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the allocated resources
|
||||
*/
|
||||
static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
|
||||
{
|
||||
LV_UNUSED(decoder); /*Unused*/
|
||||
|
||||
lv_cache_lock();
|
||||
lv_cache_release(dsc->user_data);
|
||||
lv_cache_unlock();
|
||||
}
|
||||
|
||||
static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc)
|
||||
{
|
||||
lv_cache_lock();
|
||||
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
|
||||
const char * fn = dsc->src;
|
||||
|
||||
lv_cache_entry_t * cache = lv_cache_find(fn, LV_CACHE_SRC_TYPE_STR, 0, 0);
|
||||
if(cache) {
|
||||
dsc->img_data = lv_cache_get_data(cache);
|
||||
dsc->user_data = cache; /*Save the cache to release it in decoder_close*/
|
||||
lv_cache_unlock();
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_cache_unlock();
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
static uint8_t * alloc_file(const char * filename, uint32_t * size)
|
||||
{
|
||||
uint8_t * data = NULL;
|
||||
lv_fs_file_t f;
|
||||
uint32_t data_size;
|
||||
uint32_t rn;
|
||||
lv_fs_res_t res;
|
||||
|
||||
*size = 0;
|
||||
|
||||
res = lv_fs_open(&f, filename, LV_FS_MODE_RD);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
LV_LOG_WARN("can't open %s", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = lv_fs_seek(&f, 0, LV_FS_SEEK_END);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = lv_fs_tell(&f, &data_size);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = lv_fs_seek(&f, 0, LV_FS_SEEK_SET);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*Read file to buffer*/
|
||||
data = lv_malloc(data_size);
|
||||
if(data == NULL) {
|
||||
LV_LOG_WARN("malloc failed for data");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
res = lv_fs_read(&f, data, data_size, &rn);
|
||||
|
||||
if(res == LV_FS_RES_OK && rn == data_size) {
|
||||
*size = rn;
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("read file failed");
|
||||
lv_free(data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
failed:
|
||||
lv_fs_close(&f);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static const void * decode_png_file(const char * filename)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*Prepare png_image*/
|
||||
png_image image;
|
||||
lv_memzero(&image, sizeof(image));
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
|
||||
uint32_t data_size;
|
||||
uint8_t * data = alloc_file(filename, &data_size);
|
||||
if(data == NULL) {
|
||||
LV_LOG_WARN("can't load file: %s", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*Ready to read file*/
|
||||
ret = png_image_begin_read_from_memory(&image, data, data_size);
|
||||
if(!ret) {
|
||||
LV_LOG_ERROR("png file: %s read failed: %d", filename, ret);
|
||||
lv_free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*Set color format*/
|
||||
image.format = PNG_FORMAT_BGRA;
|
||||
|
||||
/*Alloc image buffer*/
|
||||
size_t image_size = PNG_IMAGE_SIZE(image);
|
||||
void * image_data = lv_draw_buf_malloc(image_size, LV_COLOR_FORMAT_ARGB8888);
|
||||
|
||||
if(image_data) {
|
||||
/*Start decoding*/
|
||||
ret = png_image_finish_read(&image, NULL, image_data, 0, NULL);
|
||||
if(!ret) {
|
||||
LV_LOG_ERROR("png decode failed: %d", ret);
|
||||
lv_draw_buf_free(image_data);
|
||||
image_data = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LV_LOG_ERROR("png alloc %zu failed", image_size);
|
||||
}
|
||||
|
||||
/*free decoder*/
|
||||
png_image_free(&image);
|
||||
lv_free(data);
|
||||
|
||||
return image_data;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_LIBPNG*/
|
48
src/libs/libpng/lv_libpng.h
Normal file
48
src/libs/libpng/lv_libpng.h
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @file lv_libpng.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_LIBPNG_H
|
||||
#define LV_LIBPNG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_LIBPNG
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Register the PNG decoder functions in LVGL
|
||||
*/
|
||||
void lv_libpng_init(void);
|
||||
|
||||
void lv_libpng_deinit(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_LIBPNG*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_LIBPNG_H*/
|
@ -1943,6 +1943,15 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*PNG decoder(libpng) library*/
|
||||
#ifndef LV_USE_LIBPNG
|
||||
#ifdef CONFIG_LV_USE_LIBPNG
|
||||
#define LV_USE_LIBPNG CONFIG_LV_USE_LIBPNG
|
||||
#else
|
||||
#define LV_USE_LIBPNG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*BMP decoder library*/
|
||||
#ifndef LV_USE_BMP
|
||||
#ifdef CONFIG_LV_USE_BMP
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "libs/tjpgd/lv_tjpgd.h"
|
||||
#include "libs/libjpeg_turbo/lv_libjpeg_turbo.h"
|
||||
#include "libs/lodepng/lv_lodepng.h"
|
||||
#include "libs/libpng/lv_libpng.h"
|
||||
#include "draw/lv_draw.h"
|
||||
#include "misc/lv_cache.h"
|
||||
#include "misc/lv_cache_builtin.h"
|
||||
@ -234,6 +235,10 @@ void lv_init(void)
|
||||
lv_lodepng_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_LIBPNG
|
||||
lv_libpng_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_TJPGD
|
||||
lv_tjpgd_init();
|
||||
#endif
|
||||
|
BIN
tests/ref_imgs/libs/png_2.png
Normal file
BIN
tests/ref_imgs/libs/png_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
@ -62,6 +62,7 @@
|
||||
#define LV_FS_MEMFS_LETTER 'M'
|
||||
|
||||
#define LV_USE_LODEPNG 1
|
||||
#define LV_USE_LIBPNG 1
|
||||
#define LV_USE_BMP 1
|
||||
#define LV_USE_TJPGD 1
|
||||
#define LV_USE_LIBJPEG_TURBO 1
|
||||
|
54
tests/src/test_cases/libs/test_libpng.c
Normal file
54
tests/src/test_cases/libs/test_libpng.c
Normal file
@ -0,0 +1,54 @@
|
||||
#if LV_BUILD_TEST
|
||||
#include "../lvgl.h"
|
||||
|
||||
#include "unity/unity.h"
|
||||
#include "lv_test_helpers.h"
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
/* Function run before every test */
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
/* Function run after every test */
|
||||
}
|
||||
|
||||
static void create_images(void)
|
||||
{
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_obj_t * img;
|
||||
|
||||
img = lv_img_create(lv_scr_act());
|
||||
lv_img_set_src(img, "A:src/test_assets/test_img_lvgl_logo.png");
|
||||
lv_obj_center(img);
|
||||
}
|
||||
|
||||
void test_libpng_1(void)
|
||||
{
|
||||
/* Temporarily remove lodepng decoder */
|
||||
lv_lodepng_deinit();
|
||||
|
||||
create_images();
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("libs/png_2.png");
|
||||
|
||||
|
||||
uint32_t mem_before = lv_test_get_free_mem();
|
||||
for(uint32_t i = 0; i < 20; i++) {
|
||||
create_images();
|
||||
|
||||
lv_obj_invalidate(lv_scr_act());
|
||||
lv_refr_now(NULL);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("libs/png_2.png");
|
||||
|
||||
TEST_ASSERT_EQUAL(mem_before, lv_test_get_free_mem());
|
||||
|
||||
/* Re-add lodepng decoder */
|
||||
lv_lodepng_init();
|
||||
}
|
||||
|
||||
#endif
|
@ -41,6 +41,9 @@ static void create_images(void)
|
||||
|
||||
void test_lodepng_1(void)
|
||||
{
|
||||
/* Temporarily remove libpng decoder */
|
||||
lv_libpng_deinit();
|
||||
|
||||
create_images();
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("libs/png_1.png");
|
||||
@ -58,6 +61,8 @@ void test_lodepng_1(void)
|
||||
|
||||
TEST_ASSERT_EQUAL(mem_before, lv_test_get_free_mem());
|
||||
|
||||
/* Re-add libpng decoder */
|
||||
lv_libpng_init();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user