ESPHome  2025.2.0
bmp_image.cpp
Go to the documentation of this file.
1 #include "bmp_image.h"
2 
3 #ifdef USE_ONLINE_IMAGE_BMP_SUPPORT
4 
6 #include "esphome/core/helpers.h"
7 #include "esphome/core/log.h"
8 
9 namespace esphome {
10 namespace online_image {
11 
12 static const char *const TAG = "online_image.bmp";
13 
14 int HOT BmpDecoder::decode(uint8_t *buffer, size_t size) {
15  size_t index = 0;
16  if (this->current_index_ == 0 && index == 0 && size > 14) {
27  // Check if the file is a BMP image
28  if (buffer[0] != 'B' || buffer[1] != 'M') {
29  ESP_LOGE(TAG, "Not a BMP file");
31  }
32 
33  this->download_size_ = encode_uint32(buffer[5], buffer[4], buffer[3], buffer[2]);
34  this->data_offset_ = encode_uint32(buffer[13], buffer[12], buffer[11], buffer[10]);
35 
36  this->current_index_ = 14;
37  index = 14;
38  }
39  if (this->current_index_ == 14 && index == 14 && size > this->data_offset_) {
54  this->width_ = encode_uint32(buffer[21], buffer[20], buffer[19], buffer[18]);
55  this->height_ = encode_uint32(buffer[25], buffer[24], buffer[23], buffer[22]);
56  this->bits_per_pixel_ = encode_uint16(buffer[29], buffer[28]);
57  this->compression_method_ = encode_uint32(buffer[33], buffer[32], buffer[31], buffer[30]);
58  this->image_data_size_ = encode_uint32(buffer[37], buffer[36], buffer[35], buffer[34]);
59  this->color_table_entries_ = encode_uint32(buffer[49], buffer[48], buffer[47], buffer[46]);
60 
61  switch (this->bits_per_pixel_) {
62  case 1:
63  this->width_bytes_ = (this->width_ % 8 == 0) ? (this->width_ / 8) : (this->width_ / 8 + 1);
64  break;
65  default:
66  ESP_LOGE(TAG, "Unsupported bits per pixel: %d", this->bits_per_pixel_);
68  }
69 
70  if (this->compression_method_ != 0) {
71  ESP_LOGE(TAG, "Unsupported compression method: %d", this->compression_method_);
73  }
74 
75  if (!this->set_size(this->width_, this->height_)) {
77  }
78  this->current_index_ = this->data_offset_;
79  index = this->data_offset_;
80  }
81  while (index < size) {
82  size_t paint_index = this->current_index_ - this->data_offset_;
83 
84  uint8_t current_byte = buffer[index];
85  for (uint8_t i = 0; i < 8; i++) {
86  size_t x = (paint_index * 8) % this->width_ + i;
87  size_t y = (this->height_ - 1) - (paint_index / this->width_bytes_);
88  Color c = (current_byte & (1 << (7 - i))) ? display::COLOR_ON : display::COLOR_OFF;
89  this->draw(x, y, 1, 1, c);
90  }
91  this->current_index_++;
92  index++;
93  }
94  this->decoded_bytes_ += size;
95  return size;
96 };
97 
98 } // namespace online_image
99 } // namespace esphome
100 
101 #endif // USE_ONLINE_IMAGE_BMP_SUPPORT
int HOT decode(uint8_t *buffer, size_t size) override
Definition: bmp_image.cpp:14
uint16_t x
Definition: tt21100.cpp:17
const Color COLOR_OFF(0, 0, 0, 0)
Turn the pixel OFF.
Definition: display.h:191
constexpr uint32_t encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4)
Encode a 32-bit value given four bytes in most to least significant byte order.
Definition: helpers.h:195
uint16_t y
Definition: tt21100.cpp:18
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
Definition: helpers.h:191
void draw(int x, int y, int w, int h, const Color &color)
Fill a rectangle on the display_buffer using the defined color.
bool set_size(int width, int height)
Request the image to be resized once the actual dimensions are known.
const Color COLOR_ON(255, 255, 255, 255)
Turn the pixel ON.
Definition: display.h:193
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7