ESPHome 2026.3.0
Loading...
Searching...
No Matches
png_decoder.cpp
Go to the documentation of this file.
1#include "png_decoder.h"
2#ifdef USE_RUNTIME_IMAGE_PNG
3
7#include "esphome/core/log.h"
8
9static const char *const TAG = "image_decoder.png";
10
11namespace esphome::runtime_image {
12
21static void init_callback(pngle_t *pngle, uint32_t w, uint32_t h) {
22 PngDecoder *decoder = (PngDecoder *) pngle_get_user_data(pngle);
23 decoder->set_size(w, h);
24}
25
37static void draw_callback(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, const uint8_t rgba[4]) {
38 PngDecoder *decoder = (PngDecoder *) pngle_get_user_data(pngle);
39 Color color(rgba[0], rgba[1], rgba[2], rgba[3]);
40 decoder->draw(x, y, w, h, color);
41
42 // Feed watchdog periodically to avoid triggering during long decode operations.
43 // Feed every 1024 pixels to balance efficiency and responsiveness.
44 uint32_t pixels = w * h;
45 decoder->increment_pixels_decoded(pixels);
46 if ((decoder->get_pixels_decoded() % 1024) < pixels) {
47 App.feed_wdt();
48 }
49}
50
52 {
53 RAMAllocator<pngle_t> allocator;
54 pngle_t *pngle = allocator.allocate(1, PNGLE_T_SIZE);
55 if (!pngle) {
56 ESP_LOGE(TAG, "Failed to allocate memory for PNGLE engine!");
57 return;
58 }
59 memset(pngle, 0, PNGLE_T_SIZE);
60 pngle_reset(pngle);
61 this->pngle_ = pngle;
62 }
63}
64
66 if (this->pngle_) {
67 pngle_reset(this->pngle_);
68 RAMAllocator<pngle_t> allocator;
69 allocator.deallocate(this->pngle_, PNGLE_T_SIZE);
70 }
71}
72
73int PngDecoder::prepare(size_t expected_size) {
74 ImageDecoder::prepare(expected_size);
75 if (!this->pngle_) {
76 ESP_LOGE(TAG, "PNG decoder engine not initialized!");
78 }
79 pngle_set_user_data(this->pngle_, this);
80 pngle_set_init_callback(this->pngle_, init_callback);
81 pngle_set_draw_callback(this->pngle_, draw_callback);
82 return 0;
83}
84
85int HOT PngDecoder::decode(uint8_t *buffer, size_t size) {
86 if (!this->pngle_) {
87 ESP_LOGE(TAG, "PNG decoder engine not initialized!");
89 }
90 // PNG can be decoded progressively, but wait for a reasonable chunk
92 ESP_LOGD(TAG, "Waiting for more data");
93 return 0;
94 }
95 auto fed = pngle_feed(this->pngle_, buffer, size);
96 if (fed < 0) {
97 ESP_LOGE(TAG, "Error decoding image: %s", pngle_error(this->pngle_));
98 } else {
99 this->decoded_bytes_ += fed;
100 }
101 return fed;
102}
103
104} // namespace esphome::runtime_image
105
106#endif // USE_RUNTIME_IMAGE_PNG
uint8_t h
Definition bl0906.h:2
void feed_wdt(uint32_t time=0)
An STL allocator that uses SPI or internal RAM.
Definition helpers.h:1899
void deallocate(T *p, size_t n)
Definition helpers.h:1954
T * allocate(size_t n)
Definition helpers.h:1916
Class to abstract decoding different image formats.
virtual int prepare(size_t expected_size)
Initialize the decoder.
int HOT decode(uint8_t *buffer, size_t size) override
PngDecoder(RuntimeImage *image)
Construct a new PNG Decoder object.
int prepare(size_t expected_size) override
A dynamic image that can be loaded and decoded at runtime.
size_t size
Definition helpers.h:929
Application App
Global storage of Application pointer - only one Application can exist.
static void uint32_t
uint16_t x
Definition tt21100.cpp:5
uint16_t y
Definition tt21100.cpp:6