1
0
mirror of https://github.com/esphome/esphome.git synced 2025-02-13 08:28:19 +00:00

[online_image] Improve error handling (#8212)

This commit is contained in:
guillempages 2025-02-11 12:12:13 +01:00 committed by GitHub
parent 8b7aa4c110
commit c9e7562aff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 35 additions and 13 deletions

View File

@ -25,6 +25,15 @@ void ImageDecoder::draw(int x, int y, int w, int h, const Color &color) {
} }
} }
DownloadBuffer::DownloadBuffer(size_t size) : size_(size) {
this->buffer_ = this->allocator_.allocate(size);
this->reset();
if (!this->buffer_) {
ESP_LOGE(TAG, "Initial allocation of download buffer failed!");
this->size_ = 0;
}
}
uint8_t *DownloadBuffer::data(size_t offset) { uint8_t *DownloadBuffer::data(size_t offset) {
if (offset > this->size_) { if (offset > this->size_) {
ESP_LOGE(TAG, "Tried to access beyond download buffer bounds!!!"); ESP_LOGE(TAG, "Tried to access beyond download buffer bounds!!!");
@ -46,12 +55,13 @@ size_t DownloadBuffer::resize(size_t size) {
return size; return size;
} }
this->allocator_.deallocate(this->buffer_, this->size_); this->allocator_.deallocate(this->buffer_, this->size_);
this->size_ = size;
this->buffer_ = this->allocator_.allocate(size); this->buffer_ = this->allocator_.allocate(size);
this->reset(); this->reset();
if (this->buffer_) { if (this->buffer_) {
this->size_ = size;
return size; return size;
} else { } else {
this->size_ = 0;
return 0; return 0;
} }
} }

View File

@ -29,8 +29,12 @@ class ImageDecoder {
* @brief Initialize the decoder. * @brief Initialize the decoder.
* *
* @param download_size The total number of bytes that need to be downloaded for the image. * @param download_size The total number of bytes that need to be downloaded for the image.
* @return int Returns 0 on success, a {@see DecodeError} value in case of an error.
*/ */
virtual void prepare(size_t download_size) { this->download_size_ = download_size; } virtual int prepare(size_t download_size) {
this->download_size_ = download_size;
return 0;
}
/** /**
* @brief Decode a part of the image. It will try reading from the buffer. * @brief Decode a part of the image. It will try reading from the buffer.
@ -83,10 +87,7 @@ class ImageDecoder {
class DownloadBuffer { class DownloadBuffer {
public: public:
DownloadBuffer(size_t size) : size_(size) { DownloadBuffer(size_t size);
this->buffer_ = this->allocator_.allocate(size);
this->reset();
}
virtual ~DownloadBuffer() { this->allocator_.deallocate(this->buffer_, this->size_); } virtual ~DownloadBuffer() { this->allocator_.deallocate(this->buffer_, this->size_); }

View File

@ -41,13 +41,14 @@ static int draw_callback(JPEGDRAW *jpeg) {
return 1; return 1;
} }
void JpegDecoder::prepare(size_t download_size) { int JpegDecoder::prepare(size_t download_size) {
ImageDecoder::prepare(download_size); ImageDecoder::prepare(download_size);
auto size = this->image_->resize_download_buffer(download_size); auto size = this->image_->resize_download_buffer(download_size);
if (size < download_size) { if (size < download_size) {
ESP_LOGE(TAG, "Resize failed!"); ESP_LOGE(TAG, "Download buffer resize failed!");
// TODO: return an error code; return DECODE_ERROR_OUT_OF_MEMORY;
} }
return 0;
} }
int HOT JpegDecoder::decode(uint8_t *buffer, size_t size) { int HOT JpegDecoder::decode(uint8_t *buffer, size_t size) {

View File

@ -21,7 +21,7 @@ class JpegDecoder : public ImageDecoder {
JpegDecoder(OnlineImage *image) : ImageDecoder(image) {} JpegDecoder(OnlineImage *image) : ImageDecoder(image) {}
~JpegDecoder() override {} ~JpegDecoder() override {}
void prepare(size_t download_size) override; int prepare(size_t download_size) override;
int HOT decode(uint8_t *buffer, size_t size) override; int HOT decode(uint8_t *buffer, size_t size) override;
protected: protected:

View File

@ -178,7 +178,12 @@ void OnlineImage::update() {
this->download_error_callback_.call(); this->download_error_callback_.call();
return; return;
} }
this->decoder_->prepare(total_size); auto prepare_result = this->decoder_->prepare(total_size);
if (prepare_result < 0) {
this->end_connection_();
this->download_error_callback_.call();
return;
}
ESP_LOGI(TAG, "Downloading image (Size: %d)", total_size); ESP_LOGI(TAG, "Downloading image (Size: %d)", total_size);
this->start_time_ = ::time(nullptr); this->start_time_ = ::time(nullptr);
} }

View File

@ -40,11 +40,16 @@ static void draw_callback(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, ui
decoder->draw(x, y, w, h, color); decoder->draw(x, y, w, h, color);
} }
void PngDecoder::prepare(size_t download_size) { int PngDecoder::prepare(size_t download_size) {
ImageDecoder::prepare(download_size); ImageDecoder::prepare(download_size);
if (!this->pngle_) {
ESP_LOGE(TAG, "PNG decoder engine not initialized!");
return DECODE_ERROR_OUT_OF_MEMORY;
}
pngle_set_user_data(this->pngle_, this); pngle_set_user_data(this->pngle_, this);
pngle_set_init_callback(this->pngle_, init_callback); pngle_set_init_callback(this->pngle_, init_callback);
pngle_set_draw_callback(this->pngle_, draw_callback); pngle_set_draw_callback(this->pngle_, draw_callback);
return 0;
} }
int HOT PngDecoder::decode(uint8_t *buffer, size_t size) { int HOT PngDecoder::decode(uint8_t *buffer, size_t size) {

View File

@ -21,7 +21,7 @@ class PngDecoder : public ImageDecoder {
PngDecoder(OnlineImage *image) : ImageDecoder(image), pngle_(pngle_new()) {} PngDecoder(OnlineImage *image) : ImageDecoder(image), pngle_(pngle_new()) {}
~PngDecoder() override { pngle_destroy(this->pngle_); } ~PngDecoder() override { pngle_destroy(this->pngle_); }
void prepare(size_t download_size) override; int prepare(size_t download_size) override;
int HOT decode(uint8_t *buffer, size_t size) override; int HOT decode(uint8_t *buffer, size_t size) override;
protected: protected: