7#ifdef USE_RUNTIME_IMAGE_BMP
10#ifdef USE_RUNTIME_IMAGE_JPEG
13#ifdef USE_RUNTIME_IMAGE_PNG
19static const char *
const TAG =
"runtime_image";
27 return ((color.
r >> 2) + (color.
g >> 1) + (color.
b >> 2)) & 0x80;
31 image::Image *placeholder,
bool is_big_endian,
int fixed_width,
int fixed_height)
32 : Image(nullptr, 0, 0,
type, transparency),
34 fixed_width_(fixed_width),
35 fixed_height_(fixed_height),
36 placeholder_(placeholder),
37 is_big_endian_(is_big_endian) {}
58 ESP_LOGE(TAG,
"Buffer not allocated!");
62 ESP_LOGE(TAG,
"Tried to paint a pixel (%d,%d) outside the image!",
x,
y);
66 switch (this->
type_) {
68 const uint32_t width_8 = ((this->
buffer_width_ + 7u) / 8u) * 8u;
69 uint32_t
pos =
x +
y * width_8;
70 auto bitno = 0x80 >> (
pos % 8u);
84 auto gray =
static_cast<uint8_t
>(0.2125 * color.
r + 0.7154 * color.
g + 0.0721 * color.
b);
101 Color mapped_color = color;
105 this->
buffer_[pos + 0] =
static_cast<uint8_t
>((rgb565 >> 8) & 0xFF);
106 this->
buffer_[pos + 1] =
static_cast<uint8_t
>(rgb565 & 0xFF);
108 this->
buffer_[pos + 0] =
static_cast<uint8_t
>(rgb565 & 0xFF);
109 this->
buffer_[pos + 1] =
static_cast<uint8_t
>((rgb565 >> 8) & 0xFF);
118 Color mapped_color = color;
120 this->
buffer_[pos + 0] = mapped_color.
r;
121 this->
buffer_[pos + 1] = mapped_color.
g;
122 this->
buffer_[pos + 2] = mapped_color.
b;
133 if (color.
g == 1 && color.
r == 0 && color.
b == 0) {
136 if (color.
w < 0x80) {
147 Image::draw(
x,
y, display, color_on, color_off);
157 ESP_LOGW(TAG,
"Decoding already in progress");
163 ESP_LOGE(TAG,
"Failed to create decoder for format %d", this->
format_);
171 int result = this->
decoder_->prepare(expected_size);
173 ESP_LOGE(TAG,
"Failed to prepare decoder: %d", result);
183 ESP_LOGE(TAG,
"No decoder initialized");
219 return this->
decoder_->is_finished();
256 ESP_LOGD(TAG,
"Allocating buffer: %dx%d, %zu bytes", width, height, new_size);
260 ESP_LOGE(TAG,
"Failed to allocate %zu bytes. Largest free block: %zu", new_size,
266 memset(this->
buffer_, 0, new_size);
275 return (this->
get_bpp() * width + 7u) / 8u * height;
282#ifdef USE_RUNTIME_IMAGE_BMP
284 return make_unique<BmpDecoder>(
this);
286#ifdef USE_RUNTIME_IMAGE_JPEG
288 return make_unique<JpegDecoder>(
this);
290#ifdef USE_RUNTIME_IMAGE_PNG
292 return make_unique<PngDecoder>(
this);
295 ESP_LOGE(TAG,
"Unsupported image format: %d", this->
format_);
void deallocate(T *p, size_t n)
size_t get_max_free_block_size() const
Return the maximum size block this allocator could allocate.
static uint16_t color_to_565(Color color, ColorOrder color_order=ColorOrder::COLOR_ORDER_RGB)
const uint8_t * data_start_
bool has_transparency() const
Transparency transparency_
void draw(int x, int y, display::Display *display, Color color_on, Color color_off) override
size_t get_buffer_size_(int width, int height) const
Get the buffer size in bytes for given dimensions.
RAMAllocator< uint8_t > allocator_
bool is_big_endian_
Whether the image is stored in big-endian format.
void draw(int x, int y, display::Display *display, Color color_on, Color color_off) override
int buffer_width_
Actual width of the current image.
bool end_decode()
Complete the decoding process.
int get_position_(int x, int y) const
Get the position in the buffer for a pixel.
const int fixed_height_
Fixed height requested on configuration, or 0 if not specified.
void release_buffer_()
Release only the image buffer without resetting the decoder.
int resize(int width, int height)
Resize the image buffer to the requested dimensions.
int feed_data(uint8_t *data, size_t len)
Feed data to the decoder.
const int fixed_width_
Fixed width requested on configuration, or 0 if not specified.
bool is_decode_finished() const
Check if the decoder has finished processing all data.
void release()
Release the image buffer and free memory.
image::Image * placeholder_
Placeholder image to show when the runtime image is not available.
RuntimeImage(ImageFormat format, image::ImageType type, image::Transparency transparency, image::Image *placeholder=nullptr, bool is_big_endian=false, int fixed_width=0, int fixed_height=0)
Construct a new RuntimeImage object.
const ImageFormat format_
The image format this RuntimeImage is configured to decode.
size_t resize_buffer_(int width, int height)
Resize the image buffer to the requested dimensions.
std::unique_ptr< ImageDecoder > decoder_
bool progressive_display_
std::unique_ptr< ImageDecoder > create_decoder_()
Create decoder instance for the image's format.
void draw_pixel(int x, int y, const Color &color)
int buffer_height_
Actual height of the current image.
bool begin_decode(size_t expected_size=0)
Begin decoding an image.
void map_chroma_key(Color &color)
@ TRANSPARENCY_ALPHA_CHANNEL
@ TRANSPARENCY_CHROMA_KEY
bool is_color_on(const Color &color)
ImageFormat
Image format types that can be decoded dynamically.