Add png support

This commit is contained in:
fvanroie 2021-05-10 06:36:05 +02:00
parent 33e3fbb71e
commit cb4daf442c
10 changed files with 233 additions and 175 deletions

View File

@ -187,16 +187,16 @@ typedef void* lv_group_user_data_t;
typedef void* lv_fs_drv_user_data_t;
/*File system interface*/
#define LV_USE_FS_IF 0
#define LV_USE_FS_IF 1
#if LV_USE_FS_IF
# define LV_FS_IF_FATFS '\0'
#if defined(STM32F4xx) // || defined(ARDUINO_ARCH_ESP8266)
# define LV_FS_IF_PC '\0'
# define LV_FS_IF_SPIFFS '\0' // internal esp Flash
//# define LV_FS_IF_SPIFFS '\0' // internal esp Flash
#else
# define LV_FS_IF_PC '\0'
# define LV_FS_IF_PC 'L' // Local filesystem
# define LV_FS_IF_POSIX '\0'
# define LV_FS_IF_SPIFFS '\0' // no internal esp Flash
//# define LV_FS_IF_SPIFFS '\0' // no internal esp Flash
#endif
#endif /*LV_USE_FS_IF*/
@ -226,6 +226,10 @@ typedef void* lv_fs_drv_user_data_t;
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
typedef void* lv_img_decoder_user_data_t;
#if (HASP_USE_PNGDECODE > 0) && (LV_USE_FILESYSTEM > 0)
//#define LV_PNG_USE_LV_FILESYSTEM 1
#endif
/*=====================
* Compiler settings
*====================*/

View File

@ -24,10 +24,12 @@
* DEFINES
*********************/
#ifndef LV_FS_PC_PATH
#ifndef WIN32
#define LV_FS_PC_PATH "/fs" /*Projet root*/
#if defined(ESP32)
#define LV_FS_PC_PATH "/littlefs" /*Projet root*/
#elif defined(WIN32)
#define LV_FS_PC_PATH "./" /*Projet root*/
#else
#define LV_FS_PC_PATH ".\\" /*Projet root*/
#define LV_FS_PC_PATH "" /*Projet root*/
#endif
#endif /*LV_FS_PATH*/
@ -144,11 +146,11 @@ static lv_fs_res_t fs_open(lv_fs_drv_t* drv, void* file_p, const char* path, lv_
#ifndef WIN32
char buf[256];
sprintf(buf, LV_FS_PC_PATH "/%s", path);
printf("%s\n", buf);
#else
char buf[256];
sprintf(buf, LV_FS_PC_PATH "\\%s", path);
#endif
printf("Opening file: %s\n", path);
file_t f = fopen(buf, flags);
if(f == NULL) {

View File

@ -22,6 +22,8 @@
#define LV_FS_SPIFFS SPIFFS
#elif HASP_USE_LITTLEFS > 0
#include "LITTLEFS.h"
#include "esp_littlefs.h"
#define LV_FS_SPIFFS LITTLEFS
#endif
#elif defined(ARDUINO_ARCH_ESP8266)
@ -45,13 +47,13 @@
**********************/
/* Create a type to store the required data about your file.*/
typedef File lv_spiffs_file_t;
typedef FILE* lv_spiffs_file_t;
/*Similarly to `file_t` create a type for directory reading too */
#if defined(ARDUINO_ARCH_ESP32)
typedef File lv_spiffs_dir_t;
typedef FILE* lv_spiffs_dir_t;
#elif defined(ARDUINO_ARCH_ESP8266)
typedef Dir lv_spiffs_dir_t;
typedef Dir* lv_spiffs_dir_t;
#define FILE_READ "r"
#define FILE_WRITE "r+"
#endif
@ -93,6 +95,7 @@ void lv_fs_if_spiffs_init(void)
/*----------------------------------------------------
* Initialize your storage device and File System
* -------------------------------------------------*/
Log.verbose(88, "File system init start");
fs_init();
/*---------------------------------------------------
@ -114,16 +117,17 @@ void lv_fs_if_spiffs_init(void)
fs_drv.tell_cb = fs_tell;
fs_drv.free_space_cb = fs_free;
fs_drv.size_cb = fs_size;
fs_drv.remove_cb = fs_remove;
fs_drv.rename_cb = fs_rename;
fs_drv.trunc_cb = fs_trunc;
// fs_drv.remove_cb = fs_remove;
// fs_drv.rename_cb = fs_rename;
// fs_drv.trunc_cb = fs_trunc;
fs_drv.rddir_size = sizeof(lv_spiffs_dir_t);
fs_drv.dir_close_cb = fs_dir_close;
fs_drv.dir_open_cb = fs_dir_open;
fs_drv.dir_read_cb = fs_dir_read;
// fs_drv.rddir_size = sizeof(lv_spiffs_dir_t);
// fs_drv.dir_close_cb = fs_dir_close;
// fs_drv.dir_open_cb = fs_dir_open;
// fs_drv.dir_read_cb = fs_dir_read;
lv_fs_drv_register(&fs_drv);
Log.verbose(88, "File system init complete");
}
/**********************
@ -133,7 +137,42 @@ void lv_fs_if_spiffs_init(void)
/* Initialize your Storage device and File system. */
static void fs_init(void)
{
LV_FS_SPIFFS.begin();
esp_vfs_littlefs_conf_t conf = {.base_path = "/lfs", .partition_label = "spiffs", .format_if_mount_failed = false};
esp_err_t res = esp_vfs_littlefs_register(&conf);
if(res != ESP_OK) {
if(res == ESP_FAIL) {
Log.error(88, "Failed to mount or format filesystem");
} else if(res == ESP_ERR_NOT_FOUND) {
Log.error(88, "Failed to find LittleFS partition");
} else {
Log.error(88, "Failed to initialize LittleFS (%s)", esp_err_to_name(res));
}
return;
}
size_t total = 0, used = 0;
res = esp_littlefs_info(conf.partition_label, &total, &used);
if(res != ESP_OK) {
Log.error(88, "Failed to get LittleFS partition information (%s)", esp_err_to_name(res));
} else {
Log.verbose(88, "Partition size: total: %d, used: %d", total, used);
}
// Use POSIX and C standard library functions to work with files.
// First create a file.
Log.verbose(88, "Opening file /lfs/hello.txt");
FILE* f = fopen("/lfs/hello.txt", "w");
if(f == NULL) {
Log.error(88, "Failed to open file for writing");
return;
}
fprintf(f, "LittleFS Rocks!\n");
fclose(f);
Log.verbose(88, "File written");
Log.verbose(88, "LittleFS init OK");
}
/**
@ -148,36 +187,36 @@ static lv_fs_res_t fs_open(lv_fs_drv_t* drv, void* file_p, const char* path, lv_
{
(void)drv; /*Unused*/
char filename[32];
snprintf_P(filename, sizeof(filename), PSTR("/%s"), path);
const char* flags = "";
lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p;
if(fp == NULL) return LV_FS_RES_INV_PARAM;
if(mode == LV_FS_MODE_WR)
flags = "w";
else if(mode == LV_FS_MODE_RD)
flags = "r";
else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD))
flags = "rb+";
LOG_VERBOSE(TAG_LVFS, F("Opening %s"), filename);
lv_spiffs_file_t file = LV_FS_SPIFFS.open(filename, mode == LV_FS_MODE_WR ? FILE_WRITE : FILE_READ);
/*Make the path relative to the current directory (the projects root folder)*/
LOG_VERBOSE(TAG_LVFS, F("%d"), __LINE__);
if(!file) {
LOG_VERBOSE(TAG_LVFS, F("Invalid file"));
return LV_FS_RES_NOT_EX;
char complete_path[strlen(path) + 1];
complete_path[0] = '/';
complete_path[1] = '\0';
strcat(complete_path, path);
// } else if((*fp).isDirectory()) {
// LOG_VERBOSE(TAG_LVFS, F("Cannot open directory as a file"));
// return LV_FS_RES_UNKNOWN;
Log.verbose(88, "Opening file %s", path);
lv_spiffs_file_t f = fopen(path, flags);
if(f == NULL) return LV_FS_RES_UNKNOWN;
} else {
// f.seek(0, SeekSet);
// LOG_VERBOSE(TAG_LVFS,F("Assigning %s"), f.name());
LOG_VERBOSE(TAG_LVFS, F("%d"), __LINE__);
// LOG_VERBOSE(TAG_LVFS,F("Copying %s"), f.name());
LOG_VERBOSE(TAG_LVFS, F("%d - %x - %d"), __LINE__, fp, sizeof(lv_spiffs_file_t));
// memcpy(fp,&file,sizeof(lv_spiffs_file_t));
LOG_VERBOSE(TAG_LVFS, F("%d"), __LINE__);
*fp = file;
/*Be sure we are the beginning of the file*/
fseek(f, 0, SEEK_SET);
/* 'file_p' is pointer to a file descriptor and
* we need to store our file descriptor here*/
lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/
*fp = f;
Log.verbose(88, "Open eof file_p %d", feof(*fp));
return LV_FS_RES_OK;
}
}
/**
* Close an opened file
@ -189,23 +228,10 @@ static lv_fs_res_t fs_open(lv_fs_drv_t* drv, void* file_p, const char* path, lv_
static lv_fs_res_t fs_close(lv_fs_drv_t* drv, void* file_p)
{
(void)drv; /*Unused*/
lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p;
if(fp == NULL) return LV_FS_RES_INV_PARAM;
lv_spiffs_file_t file = *fp;
if(!file) {
LOG_VERBOSE(TAG_LVFS, F("Invalid file"));
return LV_FS_RES_NOT_EX;
} else if(file.isDirectory()) {
return LV_FS_RES_UNKNOWN;
} else {
file.close();
lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/
fclose(*fp);
return LV_FS_RES_OK;
}
}
/**
* Read data from an opened file
@ -220,33 +246,11 @@ static lv_fs_res_t fs_close(lv_fs_drv_t* drv, void* file_p)
static lv_fs_res_t fs_read(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br)
{
(void)drv; /*Unused*/
lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p;
if(fp == NULL) return LV_FS_RES_INV_PARAM;
lv_spiffs_file_t file = *fp;
if(!file) {
LOG_ERROR(TAG_LVFS, F("Invalid file"));
return LV_FS_RES_NOT_EX;
} else {
// LOG_VERBOSE(TAG_LVFS, F("Reading %u bytes from %s at position %u"), btr, file.name(), file.position());
uint32_t len = 0;
char* chp = (char*)buf;
if(chp != NULL && btr > 0)
len = file.readBytes(chp, btr);
else
LOG_VERBOSE(TAG_LVFS, F("Buffer is NULL"), btr, file.name(), file.position());
if(br != NULL)
*br = len;
else
LOG_VERBOSE(TAG_LVFS, F("BYTESREAD is NULL"), btr, file.name(), file.position());
Serial.print("!");
lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/
Log.verbose(88, "Read eof %d", feof(*fp));
*br = fread(buf, 1, btr, *fp);
return LV_FS_RES_OK;
}
}
/**
* Write into a file
@ -260,17 +264,9 @@ static lv_fs_res_t fs_read(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t b
static lv_fs_res_t fs_write(lv_fs_drv_t* drv, void* file_p, const void* buf, uint32_t btw, uint32_t* bw)
{
(void)drv; /*Unused*/
lv_spiffs_file_t file = *(lv_spiffs_file_t*)file_p;
// File file = fp;
if(!file) {
// LOG_VERBOSE(TAG_LVFS,F("Invalid file"));
return LV_FS_RES_NOT_EX;
} else {
*bw = (uint32_t)file.write((byte*)buf, btw);
return LV_FS_RES_OK;
}
lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/
Log.verbose(88, "Write eof %d", feof(*fp));
*bw = fwrite(buf, 1, btw, *fp);
}
/**
@ -284,18 +280,10 @@ static lv_fs_res_t fs_write(lv_fs_drv_t* drv, void* file_p, const void* buf, uin
static lv_fs_res_t fs_seek(lv_fs_drv_t* drv, void* file_p, uint32_t pos)
{
(void)drv; /*Unused*/
lv_spiffs_file_t file = *(lv_spiffs_file_t*)file_p;
// File file = fp;
if(!file) {
// LOG_VERBOSE(TAG_LVFS,F("Invalid file"));
return LV_FS_RES_NOT_EX;
} else {
file.seek(pos, SeekSet);
lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/
fseek(*fp, pos, SEEK_SET);
return LV_FS_RES_OK;
}
}
/**
* Give the size of a file bytes
@ -307,18 +295,12 @@ static lv_fs_res_t fs_seek(lv_fs_drv_t* drv, void* file_p, uint32_t pos)
static lv_fs_res_t fs_size(lv_fs_drv_t* drv, void* file_p, uint32_t* size_p)
{
(void)drv; /*Unused*/
lv_spiffs_file_t file = *(lv_spiffs_file_t*)file_p;
// File file = fp;
if(!file) {
// LOG_VERBOSE(TAG_LVFS,F("Invalid file"));
return LV_FS_RES_NOT_EX;
} else {
*size_p = (uint32_t)file.size();
lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/
fseek(*fp, 0L, SEEK_END);
*size_p = ftell(*fp);
fseek(*fp, 0L, SEEK_SET);
return LV_FS_RES_OK;
}
}
/**
* Give the position of the read write pointer
@ -331,18 +313,10 @@ static lv_fs_res_t fs_size(lv_fs_drv_t* drv, void* file_p, uint32_t* size_p)
static lv_fs_res_t fs_tell(lv_fs_drv_t* drv, void* file_p, uint32_t* pos_p)
{
(void)drv; /*Unused*/
lv_spiffs_file_t file = *(lv_spiffs_file_t*)file_p;
// File file = fp;
if(!file) {
// LOG_VERBOSE(TAG_LVFS,F("Invalid file"));
return LV_FS_RES_NOT_EX;
} else {
*pos_p = (uint32_t)file.position();
lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/
*pos_p = ftell(*fp);
return LV_FS_RES_OK;
}
}
/**
* Delete a file
@ -439,25 +413,25 @@ static lv_fs_res_t fs_free(lv_fs_drv_t* drv, uint32_t* total_p, uint32_t* free_p
* @param path path to a directory
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_open(lv_fs_drv_t* drv, void* dir_p, const char* path)
{
lv_spiffs_dir_t dir;
// static lv_fs_res_t fs_dir_open(lv_fs_drv_t* drv, void* dir_p, const char* path)
// {
// lv_spiffs_dir_t dir;
#if defined(ARDUINO_ARCH_ESP32)
dir = LV_FS_SPIFFS.open(path);
if(!dir) {
return LV_FS_RES_UNKNOWN;
}
#endif
// #if defined(ARDUINO_ARCH_ESP32)
// dir = &LV_FS_SPIFFS.open(path);
// if(!dir) {
// return LV_FS_RES_UNKNOWN;
// }
// #endif
#if defined(ARDUINO_ARCH_ESP8266)
dir = LV_FS_SPIFFS.openDir(path);
#endif
// #if defined(ARDUINO_ARCH_ESP8266)
// dir = LV_FS_SPIFFS.openDir(path);
// #endif
lv_spiffs_dir_t* dp = (lv_spiffs_dir_t*)dir_p; /*Just avoid the confusing casings*/
*dp = dir;
return LV_FS_RES_OK;
}
// lv_spiffs_dir_t* dp = (lv_spiffs_dir_t*)dir_p; /*Just avoid the confusing casings*/
// *dp = dir;
// return LV_FS_RES_OK;
// }
/**
* Read the next filename form a directory.
@ -467,31 +441,31 @@ static lv_fs_res_t fs_dir_open(lv_fs_drv_t* drv, void* dir_p, const char* path)
* @param fn pointer to a buffer to store the filename
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_read(lv_fs_drv_t* drv, void* dir_p, char* fn)
{
lv_spiffs_dir_t dir = *(lv_spiffs_dir_t*)dir_p; /*Convert type*/
// static lv_fs_res_t fs_dir_read(lv_fs_drv_t* drv, void* dir_p, char* fn)
// {
// lv_spiffs_dir_t dir = *(lv_spiffs_dir_t*)dir_p; /*Convert type*/
#if defined(ARDUINO_ARCH_ESP32)
File file = dir.openNextFile();
if(file) {
strcpy(fn, file.name());
return LV_FS_RES_OK;
} else {
return LV_FS_RES_UNKNOWN;
}
#endif
// #if defined(ARDUINO_ARCH_ESP32)
// File file = dir.openNextFile();
// if(file) {
// strcpy(fn, file.name());
// return LV_FS_RES_OK;
// } else {
// return LV_FS_RES_UNKNOWN;
// }
// #endif
#if defined(ARDUINO_ARCH_ESP8266)
if(dir.next()) {
strcpy(fn, dir.fileName().c_str());
return LV_FS_RES_OK;
} else {
return LV_FS_RES_UNKNOWN;
}
#endif
// #if defined(ARDUINO_ARCH_ESP8266)
// if(dir.next()) {
// strcpy(fn, dir.fileName().c_str());
// return LV_FS_RES_OK;
// } else {
// return LV_FS_RES_UNKNOWN;
// }
// #endif
return LV_FS_RES_NOT_IMP;
}
// return LV_FS_RES_NOT_IMP;
// }
/**
* Close the directory reading

View File

@ -117,7 +117,8 @@ build_flags =
; -- lvgl build options -----------------------------
-D LV_MEM_SIZE=61440U ; 60kB lvgl memory
-D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR
;-D LV_FS_PC_PATH="/lfs" ; this needs to match the vfs mount pount
;-D LV_FS_PC_PATH="//littlefs" ; this needs to match the vfs mount pount
-D LODEPNG_NO_COMPILE_ALLOCATORS ; use PSram functions
; -- ArduinoJson build options ----------------------------
-D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments
; -- tft_espi build options ------------------------
@ -130,6 +131,7 @@ build_flags =
;-D HASP_USE_EEPROM=1
-D HASP_USE_CONFIG=1 ; Native application, not library
-D LV_LOG_TRACE_TIMER=1
-D HASP_USE_PNGDECODE=1
; -- LittleFS build options ------------------------
;-D CONFIG_LITTLEFS_FOR_IDF_3_2 ; obsolete in IDF 3.3
@ -146,6 +148,7 @@ lib_ignore =
lib_deps =
LittleFS_esp32
git+https://github.com/lvgl/lv_lib_png.git
ps_ram =
-DBOARD_HAS_PSRAM

View File

@ -305,7 +305,7 @@ void haspSetup(void)
/******* File System Test ********************************************************************/
// lv_fs_file_t f;
// lv_fs_res_t res;
// res = lv_fs_open(&f, "E:/config.json", LV_FS_MODE_RD);
// res = lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD);
// if(res == LV_FS_RES_OK)
// LOG_VERBOSE(TAG_HASP, F("Opening config.json OK"));
// else

View File

@ -1777,6 +1777,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p
case ATTR_SRC:
if(obj_check_type(obj, LV_HASP_IMAGE)) {
if(update) {
lv_img_cache_invalidate_src(lv_img_get_src(obj));
lv_img_set_src(obj, payload);
} else {
switch(lv_img_src_get_type(obj)) {

View File

@ -53,6 +53,10 @@ static void event_delete_object(lv_obj_t* obj)
my_msgbox_map_clear(obj);
break;
case LV_HASP_IMAGE:
lv_img_cache_invalidate_src(NULL);
break;
case LV_HASP_GAUGE:
break;

43
src/hasp_png.cpp Normal file
View File

@ -0,0 +1,43 @@
/* MIT License - Copyright (c) 2019-2021 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifdef LODEPNG_NO_COMPILE_ALLOCATORS
#include <stdlib.h>
#include "hasplib.h"
#include "hasp_png.h"
void* lodepng_malloc(size_t size)
{
#ifdef LODEPNG_MAX_ALLOC
if(size > LODEPNG_MAX_ALLOC) return 0;
#endif
#ifdef ESP32
return psramFound() ? ps_malloc(size) : malloc(size);
#else
return malloc(size);
#endif
}
/* NOTE: when realloc returns NULL, it leaves the original memory untouched */
void* lodepng_realloc(void* ptr, size_t new_size)
{
#ifdef LODEPNG_MAX_ALLOC
if(new_size > LODEPNG_MAX_ALLOC) return 0;
#endif
#ifdef ESP32
return psramFound() ? ps_realloc(ptr, new_size) : realloc(ptr, new_size);
#else
return realloc(ptr, new_size);
#endif
}
void lodepng_free(void* ptr)
{
free(ptr);
}
#endif // LODEPNG_NO_COMPILE_ALLOCATORS

25
src/hasp_png.h Normal file
View File

@ -0,0 +1,25 @@
/* MIT License - Copyright (c) 2019-2021 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_PNG_H
#define HASP_PNG_H
#include <stdlib.h>
#ifdef LODEPNG_NO_COMPILE_ALLOCATORS
#ifdef __cplusplus
extern "C" {
#endif
void* lodepng_malloc(size_t size);
void* lodepng_realloc(void* ptr, size_t new_size);
void lodepng_free(void* ptr);
#ifdef __cplusplus
}
#endif
#endif // LODEPNG_NO_COMPILE_ALLOCATORS
#endif // HASP_PNG_H

View File

@ -28,6 +28,7 @@ build_flags =
-D HASP_USE_GPIO=1
-D HASP_USE_CONFIG=0 ; Standalone application, as library
-D HASP_USE_DEBUG=1
-D HASP_USE_PNGDECODE=1
-D HASP_USE_MQTT=1
-D MQTT_MAX_PACKET_SIZE=2048
-D HASP_ATTRIBUTE_FAST_MEM=
@ -83,6 +84,7 @@ lib_deps =
https://github.com/eclipse/paho.mqtt.c.git
bblanchon/ArduinoJson@^6.17.2 ; Json(l) parser
https://github.com/fvanroie/lv_drivers
git+https://github.com/lvgl/lv_lib_png.git
lib_ignore =
paho