Merge branch 'feat/add_jpeg_pixel_reverse_enc' into 'master'

feat(jpeg): Add config for reversing input pixel format in jpeg encoder

Closes IDFGH-17272

See merge request espressif/esp-idf!46075
This commit is contained in:
C.S.M
2026-02-27 18:31:56 +08:00
5 changed files with 48 additions and 4 deletions
@@ -24,6 +24,7 @@ typedef struct {
jpeg_enc_input_format_t src_type; /*!< Source type of raw image to be encoded, see `jpeg_enc_src_type_t` */
jpeg_down_sampling_type_t sub_sample; /*!< JPEG subsampling method */
uint32_t image_quality; /*!< JPEG compressing quality, value from 1-100, higher value means higher quality */
bool pixel_reverse; /*!< Whether to reverse the input pixel order, for detailed pixel order please refer to TRM */
} jpeg_encode_cfg_t;
/**
+11
View File
@@ -635,6 +635,17 @@ static esp_err_t jpeg_color_space_support_check(jpeg_decoder_handle_t decoder_en
}
}
#endif
if (decoder_engine->sample_method == JPEG_DOWN_SAMPLING_GRAY) {
if (decoder_engine->output_format != JPEG_DECODE_OUT_FORMAT_GRAY) {
ESP_LOGE(TAG, "Detected GRAY but want to convert to other format, which is not supported");
return ESP_ERR_INVALID_ARG;
}
} else {
if (decoder_engine->output_format == JPEG_DECODE_OUT_FORMAT_GRAY) {
ESP_LOGE(TAG, "Detected not GRAY but want to convert to GRAY, which is not supported");
return ESP_ERR_INVALID_ARG;
}
}
return ESP_OK;
}
+30 -4
View File
@@ -40,6 +40,7 @@ static void s_cfg_desc(jpeg_encoder_handle_t encoder_engine, dma2d_descriptor_t
static void s_jpeg_enc_config_picture_color_space(jpeg_encoder_handle_t encoder_engine);
static void s_jpeg_enc_select_sample_mode(jpeg_encoder_handle_t encoder_engine);
static void s_encoder_error_log_print(uint32_t status);
static esp_err_t jpeg_enc_validate_sub_sample(jpeg_enc_src_type_t color_space, jpeg_down_sampling_type_t sub_sample);
static void jpeg_encoder_isr_handle_default(void *arg)
{
@@ -73,6 +74,31 @@ static esp_err_t s_jpeg_set_header_info(jpeg_encoder_handle_t encoder_engine)
return ESP_OK;
}
static esp_err_t jpeg_enc_validate_sub_sample(jpeg_enc_src_type_t color_space, jpeg_down_sampling_type_t sub_sample)
{
if (color_space == JPEG_ENC_SRC_GRAY) {
if (sub_sample != JPEG_DOWN_SAMPLING_GRAY) {
ESP_LOGE(TAG, "Detected GRAY but want to convert to other format, which is not supported");
return ESP_ERR_INVALID_ARG;
}
} else if (sub_sample == JPEG_DOWN_SAMPLING_GRAY) {
ESP_LOGE(TAG, "Detected not GRAY but want to convert to GRAY, which is not supported");
return ESP_ERR_INVALID_ARG;
}
if (color_space == JPEG_ENC_SRC_YUV422) {
if (sub_sample == JPEG_DOWN_SAMPLING_YUV444) {
ESP_LOGE(TAG, "Detected YUV422 but want to convert to YUV444, which is not supported");
return ESP_ERR_INVALID_ARG;
}
} else if (color_space == JPEG_ENC_SRC_YUV420 && sub_sample != JPEG_DOWN_SAMPLING_YUV420) {
ESP_LOGE(TAG, "Detected YUV420 but want to convert to YUV422/YUV444, which is not supported");
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
esp_err_t jpeg_new_encoder_engine(const jpeg_encode_engine_cfg_t *enc_eng_cfg, jpeg_encoder_handle_t *ret_encoder)
{
#if CONFIG_JPEG_ENABLE_DEBUG_LOG
@@ -148,9 +174,6 @@ esp_err_t jpeg_encoder_process(jpeg_encoder_handle_t encoder_engine, const jpeg_
ESP_RETURN_ON_FALSE(encode_inbuf, ESP_ERR_INVALID_ARG, TAG, "jpeg encode picture buffer is null");
ESP_RETURN_ON_FALSE(out_size, ESP_ERR_INVALID_ARG, TAG, "jpeg encode picture out_size is null");
ESP_RETURN_ON_FALSE(((uintptr_t)bit_stream % cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA)) == 0, ESP_ERR_INVALID_ARG, TAG, "jpeg encode bit stream is not aligned, please use jpeg_alloc_encoder_mem to malloc your buffer");
if (encode_cfg->src_type == JPEG_ENCODE_IN_FORMAT_YUV422) {
ESP_RETURN_ON_FALSE(encode_cfg->sub_sample == JPEG_DOWN_SAMPLING_YUV422, ESP_ERR_INVALID_ARG, TAG, "Sub sampling is not supported under this source type");
}
esp_err_t ret = ESP_OK;
@@ -204,6 +227,9 @@ esp_err_t jpeg_encoder_process(jpeg_encoder_handle_t encoder_engine, const jpeg_
ret = ESP_ERR_NOT_SUPPORTED;
goto err2;
}
ESP_GOTO_ON_ERROR(jpeg_enc_validate_sub_sample(encoder_engine->color_space, encode_cfg->sub_sample), err2, TAG, "format and subsampling check failed");
encoder_engine->header_info->sub_sample = encode_cfg->sub_sample;
encoder_engine->header_info->quality = encode_cfg->image_quality;
encoder_engine->header_info->origin_h = encode_cfg->width;
@@ -214,7 +240,7 @@ esp_err_t jpeg_encoder_process(jpeg_encoder_handle_t encoder_engine, const jpeg_
s_jpeg_enc_select_sample_mode(encoder_engine);
jpeg_ll_set_picture_height(hal->dev, encoder_engine->header_info->origin_v);
jpeg_ll_set_picture_width(hal->dev, encoder_engine->header_info->origin_h);
jpeg_ll_pixel_reverse(hal->dev, false);
jpeg_ll_pixel_reverse(hal->dev, encode_cfg->pixel_reverse);
jpeg_ll_add_tail(hal->dev, true);
jpeg_ll_enable_ff_check(hal->dev, true);
jpeg_ll_set_qnr_presition(hal->dev, 0);
@@ -10,6 +10,8 @@ JPEG is a commonly used method of lossy compression for digital images, particul
JPEG codec on {IDF_TARGET_NAME} is an image codec, which is based on the JPEG baseline standard, for compressing and decompressing images to reduce the bandwidth required to transmit images or the space required to store images, making it possible to process large-resolution images. But please note, at one time, the codec engine can only work as either encoder or decoder.
For more hardware features of JPEG codec, please refer to the `JPEG codec <{IDF_TARGET_TRM_EN_URL}#jpegcodec>`__ section in {IDF_TARGET_NAME} Technical Reference Manual, for more details.
Functional Overview
-------------------
@@ -187,6 +189,7 @@ Below is the example of code that encodes a 1080*1920 picture:
.image_quality = 80,
.width = 1920,
.height = 1080,
.pixel_reverse = false, // Whether to reverse the pixel order of the input image, or pixel order detail please refer to technical reference manual
};
uint8_t *raw_buf_1080p = (uint8_t*)jpeg_alloc_encoder_mem(raw_size_1080p);
@@ -10,6 +10,8 @@ JPEG 常用于数字图像,尤其是数码摄影图像的有损压缩。压缩
{IDF_TARGET_NAME} 的 JPEG 编解码器是一种基于 JPEG 基线标准的图像编解码器,可以压缩和解压缩图像,从而降低传输图像所需的带宽或存储图像所需的空间,可以处理高分辨率的图像。但请注意,编解码器引擎不能同时作为编码器和解码器工作。
关于更多 JPEG 编解码器的硬件特性,请参考 {IDF_TARGET_NAME} 技术参考手册中的 `JPEG 编解码器 <{IDF_TARGET_TRM_EN_URL}#jpegcodec>`__ 章节,了解更多详情。
功能概述
--------
@@ -187,6 +189,7 @@ JPEG 编码器引擎
.image_quality = 80,
.width = 1920,
.height = 1080,
.pixel_reverse = false, // 是否反转输入图像的像素顺序,或像素顺序细节请参考技术参考手册
};
uint8_t *raw_buf_1080p = (uint8_t*)jpeg_alloc_encoder_mem(raw_size_1080p);