mirror of
https://github.com/esphome/esphome.git
synced 2025-02-20 20:08:20 +00:00
[online_image]Fix reset if buffer not allocated (#8236)
This commit is contained in:
parent
897873496a
commit
1111aa167f
@ -9,10 +9,10 @@ namespace online_image {
|
|||||||
static const char *const TAG = "online_image.decoder";
|
static const char *const TAG = "online_image.decoder";
|
||||||
|
|
||||||
bool ImageDecoder::set_size(int width, int height) {
|
bool ImageDecoder::set_size(int width, int height) {
|
||||||
bool resized = this->image_->resize_(width, height);
|
bool success = this->image_->resize_(width, height) > 0;
|
||||||
this->x_scale_ = static_cast<double>(this->image_->buffer_width_) / width;
|
this->x_scale_ = static_cast<double>(this->image_->buffer_width_) / width;
|
||||||
this->y_scale_ = static_cast<double>(this->image_->buffer_height_) / height;
|
this->y_scale_ = static_cast<double>(this->image_->buffer_height_) / height;
|
||||||
return resized;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageDecoder::draw(int x, int y, int w, int h, const Color &color) {
|
void ImageDecoder::draw(int x, int y, int w, int h, const Color &color) {
|
||||||
@ -51,8 +51,9 @@ size_t DownloadBuffer::read(size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t DownloadBuffer::resize(size_t size) {
|
size_t DownloadBuffer::resize(size_t size) {
|
||||||
if (this->size_ == size) {
|
if (this->size_ >= size) {
|
||||||
return size;
|
// Avoid useless reallocations; if the buffer is big enough, don't reallocate.
|
||||||
|
return this->size_;
|
||||||
}
|
}
|
||||||
this->allocator_.deallocate(this->buffer_, this->size_);
|
this->allocator_.deallocate(this->buffer_, this->size_);
|
||||||
this->buffer_ = this->allocator_.allocate(size);
|
this->buffer_ = this->allocator_.allocate(size);
|
||||||
@ -61,6 +62,8 @@ size_t DownloadBuffer::resize(size_t size) {
|
|||||||
this->size_ = size;
|
this->size_ = size;
|
||||||
return size;
|
return size;
|
||||||
} else {
|
} else {
|
||||||
|
ESP_LOGE(TAG, "allocation of %zu bytes failed. Biggest block in heap: %zu Bytes", size,
|
||||||
|
this->allocator_.get_max_free_block_size());
|
||||||
this->size_ = 0;
|
this->size_ = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ int HOT JpegDecoder::decode(uint8_t *buffer, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this->jpeg_.openRAM(buffer, size, draw_callback)) {
|
if (!this->jpeg_.openRAM(buffer, size, draw_callback)) {
|
||||||
ESP_LOGE(TAG, "Could not open image for decoding.");
|
ESP_LOGE(TAG, "Could not open image for decoding: %d", this->jpeg_.getLastError());
|
||||||
return DECODE_ERROR_INVALID_TYPE;
|
return DECODE_ERROR_INVALID_TYPE;
|
||||||
}
|
}
|
||||||
auto jpeg_type = this->jpeg_.getJPEGType();
|
auto jpeg_type = this->jpeg_.getJPEGType();
|
||||||
@ -73,7 +73,9 @@ int HOT JpegDecoder::decode(uint8_t *buffer, size_t size) {
|
|||||||
|
|
||||||
this->jpeg_.setUserPointer(this);
|
this->jpeg_.setUserPointer(this);
|
||||||
this->jpeg_.setPixelType(RGB8888);
|
this->jpeg_.setPixelType(RGB8888);
|
||||||
this->set_size(this->jpeg_.getWidth(), this->jpeg_.getHeight());
|
if (!this->set_size(this->jpeg_.getWidth(), this->jpeg_.getHeight())) {
|
||||||
|
return DECODE_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
if (!this->jpeg_.decode(0, 0, 0)) {
|
if (!this->jpeg_.decode(0, 0, 0)) {
|
||||||
ESP_LOGE(TAG, "Error while decoding.");
|
ESP_LOGE(TAG, "Error while decoding.");
|
||||||
this->jpeg_.close();
|
this->jpeg_.close();
|
||||||
|
@ -64,33 +64,34 @@ void OnlineImage::release() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OnlineImage::resize_(int width_in, int height_in) {
|
size_t OnlineImage::resize_(int width_in, int height_in) {
|
||||||
int width = this->fixed_width_;
|
int width = this->fixed_width_;
|
||||||
int height = this->fixed_height_;
|
int height = this->fixed_height_;
|
||||||
if (this->auto_resize_()) {
|
if (this->is_auto_resize_()) {
|
||||||
width = width_in;
|
width = width_in;
|
||||||
height = height_in;
|
height = height_in;
|
||||||
if (this->width_ != width && this->height_ != height) {
|
if (this->width_ != width && this->height_ != height) {
|
||||||
this->release();
|
this->release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->buffer_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
size_t new_size = this->get_buffer_size_(width, height);
|
size_t new_size = this->get_buffer_size_(width, height);
|
||||||
|
if (this->buffer_) {
|
||||||
|
// Buffer already allocated => no need to resize
|
||||||
|
return new_size;
|
||||||
|
}
|
||||||
ESP_LOGD(TAG, "Allocating new buffer of %zu bytes", new_size);
|
ESP_LOGD(TAG, "Allocating new buffer of %zu bytes", new_size);
|
||||||
this->buffer_ = this->allocator_.allocate(new_size);
|
this->buffer_ = this->allocator_.allocate(new_size);
|
||||||
if (this->buffer_ == nullptr) {
|
if (this->buffer_ == nullptr) {
|
||||||
ESP_LOGE(TAG, "allocation of %zu bytes failed. Biggest block in heap: %zu Bytes", new_size,
|
ESP_LOGE(TAG, "allocation of %zu bytes failed. Biggest block in heap: %zu Bytes", new_size,
|
||||||
this->allocator_.get_max_free_block_size());
|
this->allocator_.get_max_free_block_size());
|
||||||
this->end_connection_();
|
this->end_connection_();
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
this->buffer_width_ = width;
|
this->buffer_width_ = width;
|
||||||
this->buffer_height_ = height;
|
this->buffer_height_ = height;
|
||||||
this->width_ = width;
|
this->width_ = width;
|
||||||
ESP_LOGV(TAG, "New size: (%d, %d)", width, height);
|
ESP_LOGV(TAG, "New size: (%d, %d)", width, height);
|
||||||
return true;
|
return new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnlineImage::update() {
|
void OnlineImage::update() {
|
||||||
|
@ -99,9 +99,22 @@ class OnlineImage : public PollingComponent,
|
|||||||
|
|
||||||
int get_position_(int x, int y) const { return (x + y * this->buffer_width_) * this->get_bpp() / 8; }
|
int get_position_(int x, int y) const { return (x + y * this->buffer_width_) * this->get_bpp() / 8; }
|
||||||
|
|
||||||
ESPHOME_ALWAYS_INLINE bool auto_resize_() const { return this->fixed_width_ == 0 || this->fixed_height_ == 0; }
|
ESPHOME_ALWAYS_INLINE bool is_auto_resize_() const { return this->fixed_width_ == 0 || this->fixed_height_ == 0; }
|
||||||
|
|
||||||
bool resize_(int width, int height);
|
/**
|
||||||
|
* @brief Resize the image buffer to the requested dimensions.
|
||||||
|
*
|
||||||
|
* The buffer will be allocated if not existing.
|
||||||
|
* If the dimensions have been fixed in the yaml config, the buffer will be created
|
||||||
|
* with those dimensions and not resized, even on request.
|
||||||
|
* Otherwise, the old buffer will be deallocated and a new buffer with the requested
|
||||||
|
* allocated
|
||||||
|
*
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
* @return 0 if no memory could be allocated, the size of the new buffer otherwise.
|
||||||
|
*/
|
||||||
|
size_t resize_(int width, int height);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Draw a pixel into the buffer.
|
* @brief Draw a pixel into the buffer.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user