ESPHome 2026.10.0-dev
Loading...
Searching...
No Matches
snapshot_display.cpp
Go to the documentation of this file.
1#ifdef USE_HOST
2#include "snapshot_display.h"
4#include "esphome/core/log.h"
5
6#include <cstring>
7
9
10static const char *const TAG = "snapshot.display";
11
12namespace {
13
17constexpr uint8_t expand_channel(uint16_t value, uint16_t max) { return static_cast<uint8_t>(value * 255 / max); }
18
19constexpr uint16_t RED_MAX = 0x1F;
20constexpr uint16_t GREEN_MAX = 0x3F;
21constexpr uint16_t BLUE_MAX = 0x1F;
22
23} // namespace
24
26 this->init_internal_(static_cast<uint32_t>(this->width_) * this->height_ * 2);
27 if (this->buffer_ == nullptr) {
28 this->mark_failed(LOG_STR("Could not allocate display buffer"));
29 }
30}
31
32void SnapshotDisplay::dump_config() { LOG_DISPLAY("", "Snapshot", this); }
33
35 if (this->buffer_ == nullptr || x < 0 || x >= this->width_ || y < 0 || y >= this->height_)
36 return;
38}
39
40void SnapshotDisplay::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr,
41 display::ColorOrder order, display::ColorBitness bitness, bool big_endian,
42 int x_offset, int y_offset, int x_pad) {
43 if (this->buffer_ == nullptr)
44 return;
45 // Anything that is not already laid out the way the buffer is, or that would reach outside it,
46 // goes through the base class, which turns it into one call per pixel with the bounds checked.
47 const bool copyable = this->rotation_ == display::DISPLAY_ROTATION_0_DEGREES &&
48 bitness == display::COLOR_BITNESS_565 && !big_endian && x_start >= 0 && y_start >= 0 &&
49 x_start + w <= this->width_ && y_start + h <= this->height_;
50 if (!copyable) {
51 DisplayBuffer::draw_pixels_at(x_start, y_start, w, h, ptr, order, bitness, big_endian, x_offset, y_offset, x_pad);
52 return;
53 }
54 const size_t stride = static_cast<size_t>(x_offset) + w + x_pad;
55 const uint8_t *src = ptr + (stride * y_offset + x_offset) * 2;
56 for (int y = 0; y != h; y++) {
57 memcpy(&this->pixels_()[(y_start + y) * this->width_ + x_start], src + y * stride * 2, w * 2);
58 }
59}
60
61bool SnapshotDisplay::capture_bgr(uint8_t *dest, size_t row_stride) {
62 if (this->buffer_ == nullptr) {
63 ESP_LOGE(TAG, "Snapshot requested but there is no buffer to read");
64 return false;
65 }
66 const uint16_t *src = this->pixels_();
67 for (int y = 0; y != this->height_; y++) {
68 uint8_t *out = dest + y * row_stride;
69 for (int x = 0; x != this->width_; x++) {
70 const uint16_t pixel = *src++;
71 *out++ = expand_channel(pixel & BLUE_MAX, BLUE_MAX);
72 *out++ = expand_channel((pixel >> 5) & GREEN_MAX, GREEN_MAX);
73 *out++ = expand_channel(pixel >> 11, RED_MAX);
74 }
75 }
76 return true;
77}
78
79} // namespace esphome::snapshot
80#endif
uint8_t h
Definition bl0906.h:2
void mark_failed()
Mark this component as failed.
static uint16_t color_to_565(Color color, ColorOrder color_order=ColorOrder::COLOR_ORDER_RGB)
void init_internal_(uint32_t buffer_length)
DisplayRotation rotation_
Definition display.h:789
bool capture_bgr(uint8_t *dest, size_t row_stride) override
void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order, display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override
uint16_t * pixels_()
The picture, one 16 bit RGB565 value per pixel, topmost row first.
void draw_absolute_pixel_internal(int x, int y, Color color) override
@ DISPLAY_ROTATION_0_DEGREES
Definition display.h:134
const void * src
Definition hal.h:64
static void uint32_t
uint16_t x
Definition tt21100.cpp:5
uint16_t y
Definition tt21100.cpp:6