forked from xiaozhi/xiaozhi-esp32
fix: crash if GIF version is 87a (#1194)
* fix: no tool call reply after self.reboot * fix: 87a gif error * append display info to board info
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#include "system_info.h"
|
#include "system_info.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "display/display.h"
|
#include "display/display.h"
|
||||||
|
#include "display/oled_display.h"
|
||||||
#include "assets/lang_config.h"
|
#include "assets/lang_config.h"
|
||||||
|
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
@@ -154,6 +155,21 @@ std::string Board::GetSystemInfoJson() {
|
|||||||
json += R"("label":")" + std::string(ota_partition->label) + R"(")";
|
json += R"("label":")" + std::string(ota_partition->label) + R"(")";
|
||||||
json += R"(},)";
|
json += R"(},)";
|
||||||
|
|
||||||
|
// Append display info
|
||||||
|
auto display = GetDisplay();
|
||||||
|
if (display) {
|
||||||
|
json += R"("display":{)";
|
||||||
|
if (dynamic_cast<OledDisplay*>(display)) {
|
||||||
|
json += R"("monochrome":)" + std::string("true") + R"(,)";
|
||||||
|
} else {
|
||||||
|
json += R"("monochrome":)" + std::string("false") + R"(,)";
|
||||||
|
}
|
||||||
|
json += R"("width":)" + std::to_string(display->width()) + R"(,)";
|
||||||
|
json += R"("height":)" + std::to_string(display->height()) + R"(,)";
|
||||||
|
json.pop_back(); // Remove the last comma
|
||||||
|
}
|
||||||
|
json += R"(},)";
|
||||||
|
|
||||||
json += R"("board":)" + GetBoardJson();
|
json += R"("board":)" + GetBoardJson();
|
||||||
|
|
||||||
// Close the JSON object
|
// Close the JSON object
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#define TAG "GIF"
|
||||||
|
|
||||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||||
@@ -80,13 +83,13 @@ static gd_GIF * gif_open(gd_GIF * gif_base)
|
|||||||
/* Header */
|
/* Header */
|
||||||
f_gif_read(gif_base, sigver, 3);
|
f_gif_read(gif_base, sigver, 3);
|
||||||
if(memcmp(sigver, "GIF", 3) != 0) {
|
if(memcmp(sigver, "GIF", 3) != 0) {
|
||||||
LV_LOG_WARN("invalid signature");
|
ESP_LOGW(TAG, "invalid signature");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
/* Version */
|
/* Version */
|
||||||
f_gif_read(gif_base, sigver, 3);
|
f_gif_read(gif_base, sigver, 3);
|
||||||
if(memcmp(sigver, "89a", 3) != 0) {
|
if(memcmp(sigver, "89a", 3) != 0 && memcmp(sigver, "87a", 3) != 0) {
|
||||||
LV_LOG_WARN("invalid version");
|
ESP_LOGW(TAG, "invalid version");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
/* Width x Height */
|
/* Width x Height */
|
||||||
@@ -96,7 +99,7 @@ static gd_GIF * gif_open(gd_GIF * gif_base)
|
|||||||
f_gif_read(gif_base, &fdsz, 1);
|
f_gif_read(gif_base, &fdsz, 1);
|
||||||
/* Presence of GCT */
|
/* Presence of GCT */
|
||||||
if(!(fdsz & 0x80)) {
|
if(!(fdsz & 0x80)) {
|
||||||
LV_LOG_WARN("no global color table");
|
ESP_LOGW(TAG, "no global color table");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
/* Color Space's Depth */
|
/* Color Space's Depth */
|
||||||
@@ -110,18 +113,18 @@ static gd_GIF * gif_open(gd_GIF * gif_base)
|
|||||||
f_gif_read(gif_base, &aspect, 1);
|
f_gif_read(gif_base, &aspect, 1);
|
||||||
/* Create gd_GIF Structure. */
|
/* Create gd_GIF Structure. */
|
||||||
if(0 == width || 0 == height){
|
if(0 == width || 0 == height){
|
||||||
LV_LOG_WARN("Zero size image");
|
ESP_LOGW(TAG, "Zero size image");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
#if LV_GIF_CACHE_DECODE_DATA
|
#if LV_GIF_CACHE_DECODE_DATA
|
||||||
if(0 == (INT_MAX - sizeof(gd_GIF) - LZW_CACHE_SIZE) / width / height / 5){
|
if(0 == (INT_MAX - sizeof(gd_GIF) - LZW_CACHE_SIZE) / width / height / 5){
|
||||||
LV_LOG_WARN("Image dimensions are too large");
|
ESP_LOGW(TAG, "Image dimensions are too large");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height + LZW_CACHE_SIZE);
|
gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height + LZW_CACHE_SIZE);
|
||||||
#else
|
#else
|
||||||
if(0 == (INT_MAX - sizeof(gd_GIF)) / width / height / 5){
|
if(0 == (INT_MAX - sizeof(gd_GIF)) / width / height / 5){
|
||||||
LV_LOG_WARN("Image dimensions are too large");
|
ESP_LOGW(TAG, "Image dimensions are too large");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height);
|
gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height);
|
||||||
@@ -292,7 +295,7 @@ read_ext(gd_GIF * gif)
|
|||||||
read_application_ext(gif);
|
read_application_ext(gif);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LV_LOG_WARN("unknown extension: %02X\n", label);
|
ESP_LOGW(TAG, "unknown extension: %02X\n", label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +389,7 @@ read_image_data(gd_GIF *gif, int interlace)
|
|||||||
/* copy data to frame buffer */
|
/* copy data to frame buffer */
|
||||||
while (sp > p_stack) {
|
while (sp > p_stack) {
|
||||||
if(frm_off >= frm_size){
|
if(frm_off >= frm_size){
|
||||||
LV_LOG_WARN("LZW table token overflows the frame buffer");
|
ESP_LOGW(TAG, "LZW table token overflows the frame buffer");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*ptr++ = *(--sp);
|
*ptr++ = *(--sp);
|
||||||
@@ -593,7 +596,7 @@ read_image_data(gd_GIF * gif, int interlace)
|
|||||||
entry = table->entries[key];
|
entry = table->entries[key];
|
||||||
str_len = entry.length;
|
str_len = entry.length;
|
||||||
if(frm_off + str_len > frm_size){
|
if(frm_off + str_len > frm_size){
|
||||||
LV_LOG_WARN("LZW table token overflows the frame buffer");
|
ESP_LOGW(TAG, "LZW table token overflows the frame buffer");
|
||||||
lv_free(table);
|
lv_free(table);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -635,7 +638,7 @@ read_image(gd_GIF * gif)
|
|||||||
gif->fw = read_num(gif);
|
gif->fw = read_num(gif);
|
||||||
gif->fh = read_num(gif);
|
gif->fh = read_num(gif);
|
||||||
if(gif->fx + (uint32_t)gif->fw > gif->width || gif->fy + (uint32_t)gif->fh > gif->height){
|
if(gif->fx + (uint32_t)gif->fw > gif->width || gif->fy + (uint32_t)gif->fh > gif->height){
|
||||||
LV_LOG_WARN("Frame coordinates out of image bounds");
|
ESP_LOGW(TAG, "Frame coordinates out of image bounds");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
f_gif_read(gif, &fisrz, 1);
|
f_gif_read(gif, &fisrz, 1);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ LvglGif::LvglGif(const lv_img_dsc_t* img_dsc)
|
|||||||
gif_ = gd_open_gif_data(img_dsc->data);
|
gif_ = gd_open_gif_data(img_dsc->data);
|
||||||
if (!gif_) {
|
if (!gif_) {
|
||||||
ESP_LOGE(TAG, "Failed to open GIF from image descriptor");
|
ESP_LOGE(TAG, "Failed to open GIF from image descriptor");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup LVGL image descriptor
|
// Setup LVGL image descriptor
|
||||||
|
|||||||
@@ -137,13 +137,11 @@ void McpServer::AddUserOnlyTools() {
|
|||||||
AddUserOnlyTool("self.reboot", "Reboot the system",
|
AddUserOnlyTool("self.reboot", "Reboot the system",
|
||||||
PropertyList(),
|
PropertyList(),
|
||||||
[this](const PropertyList& properties) -> ReturnValue {
|
[this](const PropertyList& properties) -> ReturnValue {
|
||||||
auto& app = Application::GetInstance();
|
std::thread([this]() {
|
||||||
app.Schedule([]() {
|
|
||||||
ESP_LOGW(TAG, "User requested reboot");
|
ESP_LOGW(TAG, "User requested reboot");
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
auto& app = Application::GetInstance();
|
Application::GetInstance().Reboot();
|
||||||
app.Reboot();
|
}).detach();
|
||||||
});
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user