diff --git a/components/esp_driver_jpeg/jpeg_decode.c b/components/esp_driver_jpeg/jpeg_decode.c index c49be6c6d5..d940acc339 100644 --- a/components/esp_driver_jpeg/jpeg_decode.c +++ b/components/esp_driver_jpeg/jpeg_decode.c @@ -716,6 +716,9 @@ static esp_err_t jpeg_parse_marker(jpeg_decoder_handle_t decoder_engine, const u case JPEG_M_SOS: ESP_RETURN_ON_ERROR(jpeg_parse_sos_marker(header_info), TAG, "deal sos marker failed"); break; + case JPEG_M_INV: + ESP_RETURN_ON_ERROR(jpeg_parse_inv_marker(header_info), TAG, "deal invalid marker failed"); + break; } if (marker == JPEG_M_SOS) { break; diff --git a/components/esp_driver_jpeg/jpeg_parse_marker.c b/components/esp_driver_jpeg/jpeg_parse_marker.c index db762ddd52..9ba19048cf 100644 --- a/components/esp_driver_jpeg/jpeg_parse_marker.c +++ b/components/esp_driver_jpeg/jpeg_parse_marker.c @@ -186,3 +186,13 @@ esp_err_t jpeg_parse_sos_marker(jpeg_dec_header_info_t *header_info) header_info->buffer_left += 2; return ESP_OK; } + +esp_err_t jpeg_parse_inv_marker(jpeg_dec_header_info_t *header_info) +{ + // Got invalid 0xFFFF, (followed by a valid marker type) + // Go one byte back, to skip the first 0xFF + header_info->buffer_offset--; + header_info->header_size--; + header_info->buffer_left++; + return ESP_OK; +} diff --git a/components/esp_driver_jpeg/private/jpeg_parse_marker.h b/components/esp_driver_jpeg/private/jpeg_parse_marker.h index 6ba5e2b221..dc8dc059c1 100644 --- a/components/esp_driver_jpeg/private/jpeg_parse_marker.h +++ b/components/esp_driver_jpeg/private/jpeg_parse_marker.h @@ -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 */ @@ -118,6 +118,26 @@ esp_err_t jpeg_parse_sos_marker(jpeg_dec_header_info_t *header_info); */ esp_err_t jpeg_parse_dri_marker(jpeg_dec_header_info_t *header_info); +/** + * @brief Parses with an invalid marker in a JPEG file. + * + * This function is called when the decoder encounters an invalid (0xFFFF) marker. + * In the baseline JPEG specification, 0xFF is always used as the "marker prefix," and the byte that follows determines + * the marker type (e.g., 0xD8 for SOI, 0xD9 for EOI, 0xDA for SOS, etc.). + * A 0xFFFF sequence, however, does not correspond to any valid, standard JPEG marker. + * In JPEG-compressed data, any single 0xFF in the entropy-coded segment is supposed to be followed by 0x00 if it is not a marker. + * Sometimes, encoders or hardware incorrectly insert repeated 0xFF bytes without the 0x00 "stuffing" byte. + * This confuses decoders that strictly follow the JPEG standard. + * + * The function handles the invalid data contained within the marker and performs + * any necessary processing or actions based on the restart interval information. + * + * @param[in] header_info Pointer to the JPEG picture information. + * + * @return ESP_OK on success, or an appropriate error code if an error occurred. + */ +esp_err_t jpeg_parse_inv_marker(jpeg_dec_header_info_t *header_info); + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/jpeg_defs.h b/components/hal/include/hal/jpeg_defs.h index 742911e27f..1518edceb4 100644 --- a/components/hal/include/hal/jpeg_defs.h +++ b/components/hal/include/hal/jpeg_defs.h @@ -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 */ @@ -70,6 +70,7 @@ typedef enum { JPEG_M_JPG13 = 0xFFFD, ///< Reserved for JPEG extension JPEG_M_COM = 0xFFFE, ///< Comment JPEG_M_TEM = 0xFF01, ///< Temporary use in arithmetic coding + JPEG_M_INV = 0xFFFF, ///< Invalid marker } __attribute__((packed)) jpeg_marker_code_t;