mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[online_image]Fix reset if buffer not allocated (#8236)
This commit is contained in:
		| @@ -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. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user