ESPHome 2025.10.3
Loading...
Searching...
No Matches
jpeg_image.cpp
Go to the documentation of this file.
1#include "jpeg_image.h"
2#ifdef USE_ONLINE_IMAGE_JPEG_SUPPORT
3
7#include "esphome/core/log.h"
8
9#include "online_image.h"
10static const char *const TAG = "online_image.jpeg";
11
12namespace esphome {
13namespace online_image {
14
21static int draw_callback(JPEGDRAW *jpeg) {
22 ImageDecoder *decoder = (ImageDecoder *) jpeg->pUser;
23
24 // Some very big images take too long to decode, so feed the watchdog on each callback
25 // to avoid crashing.
26 App.feed_wdt();
27 size_t position = 0;
28 size_t height = static_cast<size_t>(jpeg->iHeight);
29 size_t width = static_cast<size_t>(jpeg->iWidth);
30 for (size_t y = 0; y < height; y++) {
31 for (size_t x = 0; x < width; x++) {
32 auto rg = decode_value(jpeg->pPixels[position++]);
33 auto ba = decode_value(jpeg->pPixels[position++]);
34 Color color(rg[1], rg[0], ba[1], ba[0]);
35
36 if (!decoder) {
37 ESP_LOGE(TAG, "Decoder pointer is null!");
38 return 0;
39 }
40 decoder->draw(jpeg->x + x, jpeg->y + y, 1, 1, color);
41 }
42 }
43 return 1;
44}
45
46int JpegDecoder::prepare(size_t download_size) {
47 ImageDecoder::prepare(download_size);
48 auto size = this->image_->resize_download_buffer(download_size);
49 if (size < download_size) {
50 ESP_LOGE(TAG, "Download buffer resize failed!");
52 }
53 return 0;
54}
55
56int HOT JpegDecoder::decode(uint8_t *buffer, size_t size) {
57 if (size < this->download_size_) {
58 ESP_LOGV(TAG, "Download not complete. Size: %d/%d", size, this->download_size_);
59 return 0;
60 }
61
62 if (!this->jpeg_.openRAM(buffer, size, draw_callback)) {
63 ESP_LOGE(TAG, "Could not open image for decoding: %d", this->jpeg_.getLastError());
65 }
66 auto jpeg_type = this->jpeg_.getJPEGType();
67 if (jpeg_type == JPEG_MODE_INVALID) {
68 ESP_LOGE(TAG, "Unsupported JPEG image");
70 } else if (jpeg_type == JPEG_MODE_PROGRESSIVE) {
71 ESP_LOGE(TAG, "Progressive JPEG images not supported");
73 }
74 ESP_LOGD(TAG, "Image size: %d x %d, bpp: %d", this->jpeg_.getWidth(), this->jpeg_.getHeight(), this->jpeg_.getBpp());
75
76 this->jpeg_.setUserPointer(this);
77 this->jpeg_.setPixelType(RGB8888);
78 if (!this->set_size(this->jpeg_.getWidth(), this->jpeg_.getHeight())) {
80 }
81 if (!this->jpeg_.decode(0, 0, 0)) {
82 ESP_LOGE(TAG, "Error while decoding.");
83 this->jpeg_.close();
85 }
86 this->decoded_bytes_ = size;
87 this->jpeg_.close();
88 return size;
89}
90
91} // namespace online_image
92} // namespace esphome
93
94#endif // USE_ONLINE_IMAGE_JPEG_SUPPORT
void feed_wdt(uint32_t time=0)
virtual int prepare(size_t download_size)
Initialize the decoder.
bool set_size(int width, int height)
Request the image to be resized once the actual dimensions are known.
int prepare(size_t download_size) override
int HOT decode(uint8_t *buffer, size_t size) override
size_t resize_download_buffer(size_t size)
Resize the download buffer.
float position
Definition cover.h:0
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
constexpr std::array< uint8_t, sizeof(T)> decode_value(T val)
Decode a value into its constituent bytes (from most to least significant).
Definition helpers.h:227
Application App
Global storage of Application pointer - only one Application can exist.
uint16_t x
Definition tt21100.cpp:5
uint16_t y
Definition tt21100.cpp:6