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"; | ||||
|  | ||||
| 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->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) { | ||||
| @@ -51,8 +51,9 @@ size_t DownloadBuffer::read(size_t len) { | ||||
| } | ||||
|  | ||||
| size_t DownloadBuffer::resize(size_t size) { | ||||
|   if (this->size_ == size) { | ||||
|     return size; | ||||
|   if (this->size_ >= size) { | ||||
|     // Avoid useless reallocations; if the buffer is big enough, don't reallocate. | ||||
|     return this->size_; | ||||
|   } | ||||
|   this->allocator_.deallocate(this->buffer_, this->size_); | ||||
|   this->buffer_ = this->allocator_.allocate(size); | ||||
| @@ -61,6 +62,8 @@ size_t DownloadBuffer::resize(size_t size) { | ||||
|     this->size_ = size; | ||||
|     return size; | ||||
|   } 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; | ||||
|     return 0; | ||||
|   } | ||||
|   | ||||
| @@ -58,7 +58,7 @@ int HOT JpegDecoder::decode(uint8_t *buffer, size_t size) { | ||||
|   } | ||||
|  | ||||
|   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; | ||||
|   } | ||||
|   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_.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)) { | ||||
|     ESP_LOGE(TAG, "Error while decoding."); | ||||
|     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 height = this->fixed_height_; | ||||
|   if (this->auto_resize_()) { | ||||
|   if (this->is_auto_resize_()) { | ||||
|     width = width_in; | ||||
|     height = height_in; | ||||
|     if (this->width_ != width && this->height_ != height) { | ||||
|       this->release(); | ||||
|     } | ||||
|   } | ||||
|   if (this->buffer_) { | ||||
|     return false; | ||||
|   } | ||||
|   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); | ||||
|   this->buffer_ = this->allocator_.allocate(new_size); | ||||
|   if (this->buffer_ == nullptr) { | ||||
|     ESP_LOGE(TAG, "allocation of %zu bytes failed. Biggest block in heap: %zu Bytes", new_size, | ||||
|              this->allocator_.get_max_free_block_size()); | ||||
|     this->end_connection_(); | ||||
|     return false; | ||||
|     return 0; | ||||
|   } | ||||
|   this->buffer_width_ = width; | ||||
|   this->buffer_height_ = height; | ||||
|   this->width_ = width; | ||||
|   ESP_LOGV(TAG, "New size: (%d, %d)", width, height); | ||||
|   return true; | ||||
|   return new_size; | ||||
| } | ||||
|  | ||||
| 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; } | ||||
|  | ||||
|   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. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user