2#ifdef USE_RUNTIME_IMAGE_JPEG
12#include "esp_task_wdt.h"
20 if (this->
x_boundaries_.
capacity() <
static_cast<size_t>(width + 1) && !this->x_boundaries_.try_init(width + 1)) {
23 if (this->
y_boundaries_.
capacity() <
static_cast<size_t>(height + 1) && !this->y_boundaries_.try_init(height + 1)) {
46 if (pixels ==
nullptr) {
53 for (
int source_y = 0; source_y <
h; source_y++) {
54 const int absolute_y =
y + source_y;
60 for (
int source_x = 0; source_x < w; source_x++) {
61 const int absolute_x =
x + source_x;
67 const uint8_t *pixel = pixels + (source_y * w + source_x) * 2;
68 for (uint16_t destination_y = y1; destination_y < y2; destination_y++) {
69 uint8_t *destination =
buffer + (destination_y * buffer_width + x1) * 2;
70 for (uint16_t destination_x = x1; destination_x < x2; destination_x++) {
71 destination[0] = pixel[first];
72 destination[1] = pixel[1 - first];
86static int draw_callback(JPEGDRAW *jpeg) {
89 if (decoder ==
nullptr) {
90 ESP_LOGE(TAG,
"Decoder pointer is null!");
97 if (esp_task_wdt_status(
nullptr) == ESP_OK) {
103 if (decoder->uses_direct_rgb565()) {
104 decoder->draw_rgb565(jpeg->x, jpeg->y, jpeg->iWidth, jpeg->iHeight,
105 reinterpret_cast<const uint8_t *
>(jpeg->pPixels));
109 size_t height =
static_cast<size_t>(jpeg->iHeight);
110 size_t width =
static_cast<size_t>(jpeg->iWidth);
111 for (
size_t y = 0;
y < height;
y++) {
112 for (
size_t x = 0;
x < width;
x++) {
115 Color color(rg[1], rg[0], ba[1], ba[0]);
117 decoder->draw(jpeg->x +
x, jpeg->y +
y, 1, 1, color);
127 ESP_LOGV(TAG,
"Download not complete. Size: %zu/%zu",
size, this->expected_size_);
134 if (!this->
jpeg_.openRAM(buffer,
size, draw_callback)) {
135 ESP_LOGE(TAG,
"Could not open image for decoding: %d", this->
jpeg_.getLastError());
138 auto jpeg_type = this->
jpeg_.getJPEGType();
139 if (jpeg_type == JPEG_MODE_INVALID) {
140 ESP_LOGE(TAG,
"Unsupported JPEG image");
142 }
else if (jpeg_type == JPEG_MODE_PROGRESSIVE) {
143 ESP_LOGE(TAG,
"Progressive JPEG images not supported");
146 ESP_LOGD(TAG,
"Image size: %d x %d, bpp: %d", this->
jpeg_.getWidth(), this->jpeg_.getHeight(), this->jpeg_.getBpp());
148 this->
jpeg_.setUserPointer(
this);
153 this->
jpeg_.setPixelType(RGB565_LITTLE_ENDIAN);
155 this->
jpeg_.setPixelType(RGB8888);
157 if (!this->
set_size(this->
jpeg_.getWidth(), this->jpeg_.getHeight())) {
163 if (!this->
jpeg_.decode(0, 0, 0)) {
164 auto error = this->
jpeg_.getLastError();
165 ESP_LOGE(TAG,
"Error while decoding: %d", error);
168 case JPEG_ERROR_MEMORY:
170 case JPEG_UNSUPPORTED_FEATURE:
172 case JPEG_INVALID_FILE:
173 case JPEG_INVALID_PARAMETER:
175 case JPEG_DECODE_ERROR:
void feed_wdt()
Feed the task watchdog.
void push_back(const T &value)
Add element without bounds checking Caller must ensure sufficient capacity was allocated via init() S...
bool has_transparency() const
ImageType get_type() const
uint8_t * image_buffer_() const
The image's pixel buffer, for decoders that write their output straight into it.
bool set_size(int width, int height)
Request the image to be resized once the actual dimensions are known.
bool image_is_big_endian_() const
Image decoder specialization for JPEG images.
FixedVector< uint16_t > y_boundaries_
void draw_rgb565(int x, int y, int w, int h, const uint8_t *pixels)
FixedVector< uint16_t > x_boundaries_
int HOT decode(uint8_t *buffer, size_t size) override
bool prepare_rgb565_scaling_(int width, int height)
int get_buffer_height() const
int get_buffer_width() const
ESPHOME_LOG_TAG(TAG, "image_decoder.jpeg")
@ DECODE_ERROR_INTERNAL_DECODER_ERROR
@ DECODE_ERROR_OUT_OF_MEMORY
@ DECODE_ERROR_UNSUPPORTED_FORMAT
@ DECODE_ERROR_INVALID_TYPE
constexpr std::array< uint8_t, sizeof(T)> decode_value(T val)
Decode a value into its constituent bytes (from most to least significant).
Application App
Global storage of Application pointer - only one Application can exist.