From 80c1fc8676b4761dea58835d955245e79c2634e8 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Mon, 15 Dec 2025 15:42:02 +0800 Subject: [PATCH 1/3] fix(jpeg): Fix check in com marker --- components/esp_driver_jpeg/jpeg_parse_marker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_driver_jpeg/jpeg_parse_marker.c b/components/esp_driver_jpeg/jpeg_parse_marker.c index e26bdf218a1..5dd410fe21b 100644 --- a/components/esp_driver_jpeg/jpeg_parse_marker.c +++ b/components/esp_driver_jpeg/jpeg_parse_marker.c @@ -60,7 +60,7 @@ esp_err_t jpeg_parse_com_marker(jpeg_dec_header_info_t *header_info) uint16_t skip_num = jpeg_get_bytes(header_info, 2); ESP_RETURN_ON_FALSE(skip_num >= 2, ESP_ERR_INVALID_ARG, TAG, "Invalid COM marker length: %"PRIu32, skip_num); uint32_t bytes_to_skip = skip_num - 2; - ESP_RETURN_ON_FALSE(header_info->header_size >= bytes_to_skip, ESP_ERR_INVALID_ARG, TAG, "COM marker data underflow for header_size: %"PRIu32, header_info->header_size); + ESP_RETURN_ON_FALSE(header_info->buffer_left >= bytes_to_skip, ESP_ERR_INVALID_ARG, TAG, "COM marker data underflow for header_size: %"PRIu32, header_info->buffer_left); header_info->buffer_offset += bytes_to_skip; header_info->header_size += bytes_to_skip; header_info->buffer_left -= bytes_to_skip; From 38a0beb65900b3f23079bd7da7fce8857e05277d Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Mon, 15 Dec 2025 17:38:52 +0800 Subject: [PATCH 2/3] feat(jpeg_decoder): Add decode to yuv420 since esp32p4 version3 --- components/esp_driver_jpeg/jpeg_decode.c | 24 ++++++++++++++++++++++- components/esp_driver_jpeg/jpeg_param.c | 10 +++++----- components/esp_driver_jpeg/jpeg_private.h | 1 + 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/components/esp_driver_jpeg/jpeg_decode.c b/components/esp_driver_jpeg/jpeg_decode.c index c0121b1876c..718e5cffd7c 100644 --- a/components/esp_driver_jpeg/jpeg_decode.c +++ b/components/esp_driver_jpeg/jpeg_decode.c @@ -382,6 +382,11 @@ static esp_err_t jpeg_dec_config_dma_descriptor(jpeg_decoder_handle_t decoder_en case JPEG_DECODE_OUT_FORMAT_YUV444: best_hb_idx = JPEG_DEC_YUV444_HB; break; +#if !(CONFIG_ESP_REV_MIN_FULL < 300 && CONFIG_IDF_TARGET_ESP32P4) // Invisible for unsupported chips + case JPEG_DECODE_OUT_FORMAT_YUV420: + best_hb_idx = JPEG_DEC_YUV420_HB; + break; +#endif default: ESP_LOGE(TAG, "wrong, we don't support decode to such format."); return ESP_ERR_NOT_SUPPORTED; @@ -468,7 +473,17 @@ static void jpeg_dec_config_dma_csc(jpeg_decoder_handle_t decoder_engine, dma2d_ } else if (decoder_engine->sample_method == JPEG_DOWN_SAMPLING_YUV420) { rx_csc_option = DMA2D_CSC_RX_YUV420_TO_YUV444; } - } else { + } +#if !(CONFIG_ESP_REV_MIN_FULL < 300 && CONFIG_IDF_TARGET_ESP32P4) // Invisible for unsupported chips + else if (decoder_engine->output_format == JPEG_DECODE_OUT_FORMAT_YUV420) { + if (decoder_engine->sample_method == JPEG_DOWN_SAMPLING_YUV422) { + rx_csc_option = DMA2D_CSC_RX_YUV422_TO_YUV420; + } else if (decoder_engine->sample_method == JPEG_DOWN_SAMPLING_YUV444) { + rx_csc_option = DMA2D_CSC_RX_YUV444_TO_YUV420; + } + } +#endif + else { rx_csc_option = DMA2D_CSC_RX_NONE; } @@ -565,6 +580,7 @@ static bool jpeg_dec_transaction_on_picked(uint32_t channel_num, const dma2d_tra static esp_err_t jpeg_color_space_support_check(jpeg_decoder_handle_t decoder_engine) { +#if !(CONFIG_ESP_REV_MIN_FULL < 300 && CONFIG_IDF_TARGET_ESP32P4) // Invisible for unsupported chips if (decoder_engine->sample_method == JPEG_DOWN_SAMPLING_YUV444) { if (decoder_engine->output_format == JPEG_DECODE_OUT_FORMAT_YUV422 || decoder_engine->output_format == JPEG_DECODE_OUT_FORMAT_YUV420) { ESP_LOGE(TAG, "Detected YUV444 but want to convert to YUV422/YUV420, which is not supported"); @@ -581,6 +597,12 @@ static esp_err_t jpeg_color_space_support_check(jpeg_decoder_handle_t decoder_en return ESP_ERR_INVALID_ARG; } } +#else + if (decoder_engine->sample_method != JPEG_DOWN_SAMPLING_YUV422) { + ESP_LOGE(TAG, "Detected YUV444/YUV420 but want to convert to YUV422, which is not supported"); + return ESP_ERR_INVALID_ARG; + } +#endif return ESP_OK; } diff --git a/components/esp_driver_jpeg/jpeg_param.c b/components/esp_driver_jpeg/jpeg_param.c index 380c2c614e8..9d05a3202fa 100644 --- a/components/esp_driver_jpeg/jpeg_param.c +++ b/components/esp_driver_jpeg/jpeg_param.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,10 +40,10 @@ const uint8_t zigzag_arr[64] = { * data stream during the decoding process. */ const uint32_t dec_hb_tbl[JPEG_DOWN_SAMPLING_NUM][JPEG_DEC_BEST_HB_MAX] = { - {40, 40, 40, 32, 0}, - {64, 32, 32, 64, 0}, - {48, 32, 32, 48, 0}, - {96, 0, 0, 0, 96}, + {40, 40, 40, 32, 0, 32}, + {64, 32, 32, 64, 0, 32}, + {48, 32, 32, 48, 0, 48}, + {96, 0, 0, 0, 96, 0}, }; /** diff --git a/components/esp_driver_jpeg/jpeg_private.h b/components/esp_driver_jpeg/jpeg_private.h index 56345cfd054..def879b8874 100644 --- a/components/esp_driver_jpeg/jpeg_private.h +++ b/components/esp_driver_jpeg/jpeg_private.h @@ -61,6 +61,7 @@ typedef enum { JPEG_DEC_RGB888_HB = 2, /*!< output RGB888 format */ JPEG_DEC_RGB565_HB = 3, /*!< output RGB565 format */ JPEG_DEC_GRAY_HB = 4, /*!< output the gray picture */ + JPEG_DEC_YUV420_HB = 5, /*!< output YUV420 format */ JPEG_DEC_BEST_HB_MAX, /*!< Max value of output formats */ } jpeg_dec_format_hb_t; From 1a3e2da8568e6a75f3214f4e2ff6b2c5e3228e2a Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Wed, 17 Dec 2025 10:45:33 +0800 Subject: [PATCH 3/3] fix(jpeg): Fix jpeg color space check --- components/esp_driver_jpeg/jpeg_decode.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/components/esp_driver_jpeg/jpeg_decode.c b/components/esp_driver_jpeg/jpeg_decode.c index 718e5cffd7c..290d6a06770 100644 --- a/components/esp_driver_jpeg/jpeg_decode.c +++ b/components/esp_driver_jpeg/jpeg_decode.c @@ -580,7 +580,7 @@ static bool jpeg_dec_transaction_on_picked(uint32_t channel_num, const dma2d_tra static esp_err_t jpeg_color_space_support_check(jpeg_decoder_handle_t decoder_engine) { -#if !(CONFIG_ESP_REV_MIN_FULL < 300 && CONFIG_IDF_TARGET_ESP32P4) // Invisible for unsupported chips +#if (CONFIG_ESP_REV_MIN_FULL < 300 && CONFIG_IDF_TARGET_ESP32P4) // For P4 less than 3.0 if (decoder_engine->sample_method == JPEG_DOWN_SAMPLING_YUV444) { if (decoder_engine->output_format == JPEG_DECODE_OUT_FORMAT_YUV422 || decoder_engine->output_format == JPEG_DECODE_OUT_FORMAT_YUV420) { ESP_LOGE(TAG, "Detected YUV444 but want to convert to YUV422/YUV420, which is not supported"); @@ -598,9 +598,11 @@ static esp_err_t jpeg_color_space_support_check(jpeg_decoder_handle_t decoder_en } } #else - if (decoder_engine->sample_method != JPEG_DOWN_SAMPLING_YUV422) { - ESP_LOGE(TAG, "Detected YUV444/YUV420 but want to convert to YUV422, which is not supported"); - return ESP_ERR_INVALID_ARG; + if (decoder_engine->sample_method == JPEG_DOWN_SAMPLING_YUV420 || decoder_engine->sample_method == JPEG_DOWN_SAMPLING_YUV444) { + if (decoder_engine->output_format == JPEG_DECODE_OUT_FORMAT_YUV422) { + ESP_LOGE(TAG, "Detected YUV444/YUV420 but want to convert to YUV422, which is not supported"); + return ESP_ERR_INVALID_ARG; + } } #endif return ESP_OK;