Skip to content

Commit a7a883a

Browse files
committed
Merge branch 'feat/update_esp_lvgl_adapter' into 'master'
feat(lcd): Update esp_lvgl_adapter to support multi-touch and adapt to IDF 6.0 See merge request ae_group/esp-iot-solution!1497
2 parents f54660f + 21b690c commit a7a883a

43 files changed

Lines changed: 517 additions & 138 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

components/display/tools/esp_lv_decoder/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# ChangeLog
22

3+
## v0.3.4 (2026-02-26)
4+
5+
* Used `jpeg_decoder_get_info` from `esp_driver_jpeg` instead of the software `jpeg_decode_header` for JPEG header parsing in the hardware decode path, eliminating the mixing of software and hardware JPEG interfaces.
6+
37
## v0.3.3 (2026-01-22)
48

59
* Fixed missing `esp_mm` and `esp_driver_jpeg` dependency declarations in CMakeLists.txt which caused build failures when using the component from the component registry.

components/display/tools/esp_lv_decoder/idf_component.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: "0.3.3"
1+
version: "0.3.4"
22
targets:
33
- esp32
44
- esp32s2

components/display/tools/esp_lv_decoder/src/lvgl8/esp_lv_decoder.c

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ static lv_res_t pjpg_decode(uint8_t **out, uint32_t *w, uint32_t *h, const uint8
131131
#endif
132132

133133
static const char *TAG = "lv_decoder_v8";
134+
static uint32_t s_jpeg_header_read_size = 1024;
134135

135136
#if ESP_LV_ENABLE_HW_JPEG
136137
static jpeg_decoder_handle_t jpgd_handle;
@@ -565,51 +566,63 @@ static lv_res_t decoder_info(struct _lv_img_decoder_t *decoder, const void *src,
565566
return lv_ret;
566567
} else if (strcmp(lv_fs_get_ext(fn), "jpg") == 0) {
567568

568-
if (load_image_file(fn, &load_img_data, &load_img_size, true) != LV_FS_RES_OK) {
569-
if (load_img_data) {
570-
free(load_img_data);
571-
}
569+
lv_fs_file_t f;
570+
lv_fs_res_t res = lv_fs_open(&f, fn, LV_FS_MODE_RD);
571+
if (res != LV_FS_RES_OK) {
572+
return LV_RES_INV;
573+
}
574+
uint32_t file_len;
575+
lv_fs_seek(&f, 0, LV_FS_SEEK_END);
576+
lv_fs_tell(&f, &file_len);
577+
lv_fs_seek(&f, 0, LV_FS_SEEK_SET);
578+
579+
uint32_t read_len = (file_len > s_jpeg_header_read_size) ? s_jpeg_header_read_size : file_len;
580+
load_img_data = decoder_malloc(read_len);
581+
if (!load_img_data) {
582+
lv_fs_close(&f);
583+
return LV_RES_INV;
584+
}
585+
uint32_t rn = 0;
586+
if (lv_fs_read(&f, load_img_data, read_len, &rn) != LV_FS_RES_OK || rn != read_len) {
587+
free(load_img_data);
588+
lv_fs_close(&f);
572589
return LV_RES_INV;
573590
}
591+
load_img_size = read_len;
574592

575593
uint32_t width, height;
576594
lv_ret = jpeg_decode_header(&width, &height, load_img_data, load_img_size);
577595

578-
if (lv_ret != LV_RES_OK && load_img_size == 1024) {
596+
if (lv_ret != LV_RES_OK && load_img_size < 8192 && file_len > load_img_size) {
597+
ESP_LOGW(TAG, "JPEG header parse failed with %lu bytes, retrying with up to 8KB",
598+
(unsigned long)load_img_size);
579599
free(load_img_data);
580-
load_img_data = NULL;
581-
582-
// Read up to 8KB
583-
lv_fs_file_t f;
584-
lv_fs_res_t res = lv_fs_open(&f, fn, LV_FS_MODE_RD);
585-
if (res == LV_FS_RES_OK) {
586-
uint32_t file_len;
587-
lv_fs_seek(&f, 0, LV_FS_SEEK_END);
588-
lv_fs_tell(&f, &file_len);
589-
lv_fs_seek(&f, 0, LV_FS_SEEK_SET);
590600

591-
uint32_t read_len = (file_len > 8192) ? 8192 : file_len;
592-
load_img_data = decoder_malloc(read_len);
593-
if (load_img_data) {
594-
uint32_t rn = 0;
595-
if (lv_fs_read(&f, load_img_data, read_len, &rn) == LV_FS_RES_OK && rn == read_len) {
596-
load_img_size = read_len;
597-
lv_ret = jpeg_decode_header(&width, &height, load_img_data, load_img_size);
598-
} else {
599-
free(load_img_data);
600-
load_img_data = NULL;
601-
lv_ret = LV_RES_INV;
601+
read_len = (file_len > 8192) ? 8192 : file_len;
602+
load_img_data = decoder_malloc(read_len);
603+
if (load_img_data) {
604+
lv_fs_seek(&f, 0, LV_FS_SEEK_SET);
605+
rn = 0;
606+
if (lv_fs_read(&f, load_img_data, read_len, &rn) == LV_FS_RES_OK && rn == read_len) {
607+
load_img_size = read_len;
608+
lv_ret = jpeg_decode_header(&width, &height, load_img_data, load_img_size);
609+
if (lv_ret == LV_RES_OK) {
610+
s_jpeg_header_read_size = 8192;
602611
}
612+
} else {
613+
free(load_img_data);
614+
load_img_data = NULL;
615+
lv_ret = LV_RES_INV;
603616
}
604-
lv_fs_close(&f);
605617
}
618+
}
619+
lv_fs_close(&f);
606620

607-
if (lv_ret != LV_RES_OK) {
608-
if (load_img_data) {
609-
free(load_img_data);
610-
}
611-
return LV_RES_INV;
621+
if (lv_ret != LV_RES_OK) {
622+
if (load_img_data) {
623+
free(load_img_data);
612624
}
625+
return LV_RES_INV;
613626
}
614627

615628
header->cf = LV_IMG_CF_TRUE_COLOR;
@@ -1269,8 +1282,11 @@ static lv_res_t jpeg_decode_hw_or_sw(uint8_t **out, uint32_t *w, uint32_t *h, co
12691282
if (out_is_hw) {
12701283
*out_is_hw = false;
12711284
}
1272-
if (jpeg_decode_header(w, h, in, insize) == LV_RES_OK) {
1273-
if (((*w) % 16 == 0) && ((*h) % 16 == 0) && (*w >= 64) && (*h >= 64) && jpgd_handle) {
1285+
jpeg_decode_picture_info_t pic_info = {0};
1286+
if (jpgd_handle && jpeg_decoder_get_info(in, insize, &pic_info) == ESP_OK) {
1287+
*w = pic_info.width;
1288+
*h = pic_info.height;
1289+
if (((*w) % 16 == 0) && ((*h) % 16 == 0) && (*w >= 64) && (*h >= 64)) {
12741290
size_t req_size = (*w) * (*h) * DEC_RGB_BPP;
12751291
jpeg_decode_memory_alloc_cfg_t mem_cfg = { .buffer_direction = JPEG_DEC_ALLOC_OUTPUT_BUFFER };
12761292
size_t out_size = 0;
@@ -1297,9 +1313,7 @@ static lv_res_t jpeg_decode_hw_or_sw(uint8_t **out, uint32_t *w, uint32_t *h, co
12971313
}
12981314
jpeg_free_align(*out);
12991315
*out = NULL;
1300-
} else { }
1301-
} else {
1302-
ESP_LOGE(TAG, "HW JPG header parse fail");
1316+
}
13031317
}
13041318
#endif
13051319
{

components/display/tools/esp_lv_decoder/src/lvgl9/esp_lv_decoder.c

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ static const jpeg_decode_cfg_t decode_cfg_rgb565 = {
9999
};
100100
#endif
101101

102-
static bool s_hw_output_allocation = false;
103102
#if ESP_LV_ENABLE_HW_JPEG
103+
static bool s_hw_output_allocation = false;
104104
typedef struct hw_buf_node {
105105
void *ptr;
106106
struct hw_buf_node *next;
@@ -184,6 +184,7 @@ static inline bool sp_is_sp_tag(const uint8_t *hdr8, bool *is_sjpg);
184184
static inline void sp_read_meta(const uint8_t *meta8, uint16_t *w, uint16_t *h, uint16_t *splits, uint16_t *split_h);
185185

186186
static const char *TAG = "lv_decoder_v9";
187+
static uint32_t s_jpeg_header_read_size = 1024;
187188

188189
static bool png_dimensions_allowed(uint32_t width, uint32_t height)
189190
{
@@ -563,7 +564,7 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_d
563564
lv_fs_tell(&dsc->file, &jpeg_size);
564565
lv_fs_seek(&dsc->file, 0, LV_FS_SEEK_SET);
565566

566-
uint32_t read_size = (jpeg_size > 1024) ? 1024 : jpeg_size;
567+
uint32_t read_size = (jpeg_size > s_jpeg_header_read_size) ? s_jpeg_header_read_size : jpeg_size;
567568
jpeg_data = decoder_malloc(read_size);
568569
if (jpeg_data) {
569570
lv_fs_read(&dsc->file, jpeg_data, read_size, &rn);
@@ -600,13 +601,15 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_d
600601
jpeg_pixel_format_t out_fmt = (tgt == LV_COLOR_FORMAT_RGB565) ? JPEG_PIXEL_FORMAT_RGB565_LE : JPEG_PIXEL_FORMAT_RGB888;
601602
lv_res_t res = jpeg_decode_header(&width, &height, jpeg_data, jpeg_size, out_fmt, NULL, NULL, NULL);
602603

603-
if (res != LV_RES_OK && src_type == LV_IMAGE_SRC_FILE && jpeg_size == 1024) {
604+
if (res != LV_RES_OK && src_type == LV_IMAGE_SRC_FILE && jpeg_size < 8192) {
605+
ESP_LOGW(TAG, "JPEG header parse failed with %"PRIu32" bytes, retrying with up to 8KB",
606+
jpeg_size);
604607
lv_fs_seek(&dsc->file, 0, LV_FS_SEEK_END);
605608
uint32_t file_size;
606609
lv_fs_tell(&dsc->file, &file_size);
607610
lv_fs_seek(&dsc->file, 0, LV_FS_SEEK_SET);
608611

609-
if (file_size > 1024) {
612+
if (file_size > jpeg_size) {
610613
free(jpeg_data);
611614
uint32_t new_read_size = (file_size > 8192) ? 8192 : file_size;
612615
jpeg_data = decoder_malloc(new_read_size);
@@ -617,6 +620,9 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_d
617620
if (rn2 == new_read_size) {
618621
jpeg_size = new_read_size;
619622
res = jpeg_decode_header(&width, &height, jpeg_data, jpeg_size, out_fmt, NULL, NULL, NULL);
623+
if (res == LV_RES_OK) {
624+
s_jpeg_header_read_size = 8192;
625+
}
620626
} else {
621627
free(jpeg_data);
622628
jpeg_data = NULL;
@@ -1327,25 +1333,24 @@ static lv_draw_buf_t * jpeg_decode_jpg(lv_image_decoder_dsc_t * dsc)
13271333

13281334
lv_color_format_t tgt = get_target_rgb_format();
13291335
jpeg_pixel_format_t out_fmt = (tgt == LV_COLOR_FORMAT_RGB565) ? JPEG_PIXEL_FORMAT_RGB565_LE : JPEG_PIXEL_FORMAT_RGB888;
1330-
ESP_GOTO_ON_ERROR((jpeg_decode_header(&width, &height, src_data, src_data_size, out_fmt, &jpeg_dec, &jpeg_io, &header_info) == LV_RESULT_OK) ? ESP_OK : ESP_FAIL,
1331-
cleanup, TAG, "decode JPEG header '%s' failed", (const char*)dsc->src);
13321336

1333-
/* Decide whether we will use HW JPEG path before allocating output buffer */
13341337
#if ESP_LV_ENABLE_HW_JPEG
1335-
bool use_hw = ((width % 16 == 0) && (height % 16 == 0) && (width >= 64) && (height >= 64));
1336-
#else
13371338
bool use_hw = false;
1338-
#endif
1339-
s_hw_output_allocation = use_hw;
1340-
decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, width, height,
1341-
(tgt == LV_COLOR_FORMAT_RGB565) ? LV_COLOR_FORMAT_RGB565 : LV_COLOR_FORMAT_RGB888,
1342-
LV_STRIDE_AUTO);
1343-
s_hw_output_allocation = false;
1344-
ESP_GOTO_ON_ERROR(decoded ? ESP_OK : ESP_ERR_NO_MEM, cleanup, TAG, "alloc image buffer '%s' failed", (const char*)dsc->src);
1339+
jpeg_decode_picture_info_t pic_info = {0};
1340+
if (jpeg_decoder_get_info(src_data, src_data_size, &pic_info) == ESP_OK) {
1341+
width = pic_info.width;
1342+
height = pic_info.height;
1343+
use_hw = ((width % 16 == 0) && (height % 16 == 0) && (width >= 64) && (height >= 64));
1344+
}
13451345

1346-
#if ESP_LV_ENABLE_HW_JPEG
1347-
/* Use HW JPEG only for sizes >= 64x64 and 16-pixel aligned. Smaller images fall back to SW */
13481346
if (use_hw) {
1347+
s_hw_output_allocation = true;
1348+
decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, width, height,
1349+
(tgt == LV_COLOR_FORMAT_RGB565) ? LV_COLOR_FORMAT_RGB565 : LV_COLOR_FORMAT_RGB888,
1350+
LV_STRIDE_AUTO);
1351+
s_hw_output_allocation = false;
1352+
ESP_GOTO_ON_ERROR(decoded ? ESP_OK : ESP_ERR_NO_MEM, cleanup, TAG, "alloc image buffer '%s' failed", (const char*)dsc->src);
1353+
13491354
uint32_t out_size = 0;
13501355
const jpeg_decode_cfg_t *cfg = (tgt == LV_COLOR_FORMAT_RGB565) ? &decode_cfg_rgb565 : &decode_cfg_rgb888;
13511356
esp_err_t hw_ret = jpeg_decoder_process(jpgd_handle, cfg, src_data, src_data_size, decoded->data, decoded->data_size, &out_size);
@@ -1357,6 +1362,14 @@ static lv_draw_buf_t * jpeg_decode_jpg(lv_image_decoder_dsc_t * dsc)
13571362
} else
13581363
#endif
13591364
{
1365+
ESP_GOTO_ON_ERROR((jpeg_decode_header(&width, &height, src_data, src_data_size, out_fmt, &jpeg_dec, &jpeg_io, &header_info) == LV_RESULT_OK) ? ESP_OK : ESP_FAIL,
1366+
cleanup, TAG, "decode JPEG header '%s' failed", (const char*)dsc->src);
1367+
1368+
decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, width, height,
1369+
(tgt == LV_COLOR_FORMAT_RGB565) ? LV_COLOR_FORMAT_RGB565 : LV_COLOR_FORMAT_RGB888,
1370+
LV_STRIDE_AUTO);
1371+
ESP_GOTO_ON_ERROR(decoded ? ESP_OK : ESP_ERR_NO_MEM, cleanup, TAG, "alloc image buffer '%s' failed", (const char*)dsc->src);
1372+
13601373
jpeg_io->outbuf = decoded->data;
13611374
if (jpeg_dec_process(jpeg_dec, jpeg_io) != JPEG_ERR_OK) {
13621375
lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, decoded);

components/display/tools/esp_lv_decoder/test_apps/lvgl8/main/mmap_generate_pjpg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/

components/display/tools/esp_lv_decoder/test_apps/lvgl8/main/mmap_generate_qoi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/

components/display/tools/esp_lv_decoder/test_apps/lvgl8/main/mmap_generate_sjpg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/

components/display/tools/esp_lv_decoder/test_apps/lvgl8/main/mmap_generate_spng.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/

components/display/tools/esp_lv_decoder/test_apps/lvgl9/main/mmap_generate_pjpg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/

components/display/tools/esp_lv_decoder/test_apps/lvgl9/main/mmap_generate_qoi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/

0 commit comments

Comments
 (0)