diff --git a/conversions/include/img_converters.h b/conversions/include/img_converters.h index 6e71ce93fd..015d7e8c6c 100644 --- a/conversions/include/img_converters.h +++ b/conversions/include/img_converters.h @@ -129,6 +129,17 @@ bool fmt2rgb888(const uint8_t *src_buf, size_t src_len, pixformat_t format, uint #define JPG_SCALE_MAX JPEG_IMAGE_SCALE_1_8 bool jpg2rgb565(const uint8_t *src, size_t src_len, uint8_t * out, esp_jpeg_image_scale_t scale); +/** + * @brief Configure RGB565 input byte order for JPEG encoding. + * + * Controls how RGB565 source pixel data is interpreted before JPEG conversion. + * By default, the encoder assumes big-endian byte order (MSB first), which + * matches most ESP32 camera and frame buffer outputs. + * + * @param enable True to use big-endian RGB565 (default), false for little-endian. + */ +void jpgSetRgb565BE(bool enable); + #ifdef __cplusplus } #endif diff --git a/conversions/to_jpg.cpp b/conversions/to_jpg.cpp index a4ac804d1d..6ec422b77c 100644 --- a/conversions/to_jpg.cpp +++ b/conversions/to_jpg.cpp @@ -29,6 +29,8 @@ static const char* TAG = "to_jpg"; #endif +static bool rgb565_big_endian = true; + static void *_malloc(size_t size) { void * res = malloc(size); @@ -60,9 +62,15 @@ static IRAM_ATTR void convert_line_format(uint8_t * src, pixformat_t format, uin l = width * 2; src += l * line; for(i=0; i> 3; - dst[o++] = (src[i+1] & 0x1F) << 3; + if (rgb565_big_endian) { + dst[o++] = src[i] & 0xF8; + dst[o++] = (src[i] & 0x07) << 5 | (src[i+1] & 0xE0) >> 3; + dst[o++] = (src[i+1] & 0x1F) << 3; + } else { + dst[o++] = src[i+1] & 0xF8; + dst[o++] = (src[i+1] & 0x07) << 5 | (src[i] & 0xE0) >> 3; + dst[o++] = (src[i] & 0x1F) << 3; + } } } else if(format == PIXFORMAT_YUV422) { uint8_t y0, y1, u, v; @@ -233,3 +241,8 @@ bool frame2jpg(camera_fb_t * fb, uint8_t quality, uint8_t ** out, size_t * out_l { return fmt2jpg(fb->buf, fb->len, fb->width, fb->height, fb->format, quality, out, out_len); } + +void jpgSetRgb565BE(bool enable) +{ + rgb565_big_endian = enable; +}