fix(voice): preview generated png and recover shared spi display/print
This commit is contained in:
@@ -23,11 +23,13 @@ static void lcd_fill_err(char *err, size_t err_len, const char *msg)
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t platform_lcd_decode_demo_png(uint16_t **out_pixels,
|
||||
uint16_t *out_width,
|
||||
uint16_t *out_height,
|
||||
char *err,
|
||||
size_t err_len)
|
||||
esp_err_t platform_lcd_decode_png_rgb565(const uint8_t *png,
|
||||
size_t png_len,
|
||||
uint16_t **out_pixels,
|
||||
uint16_t *out_width,
|
||||
uint16_t *out_height,
|
||||
char *err,
|
||||
size_t err_len)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
@@ -35,22 +37,20 @@ esp_err_t platform_lcd_decode_demo_png(uint16_t **out_pixels,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
TAG,
|
||||
"invalid output args");
|
||||
ESP_RETURN_ON_FALSE(png != NULL && png_len > 0, ESP_ERR_INVALID_ARG, TAG, "invalid png data");
|
||||
*out_pixels = NULL;
|
||||
*out_width = 0;
|
||||
*out_height = 0;
|
||||
|
||||
const size_t png_len = (size_t)(lcd_demo_png_end - lcd_demo_png_start);
|
||||
ESP_RETURN_ON_FALSE(png_len > 0, ESP_ERR_INVALID_SIZE, TAG, "empty png data");
|
||||
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof(image));
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
|
||||
ESP_RETURN_ON_FALSE(png_image_begin_read_from_memory(&image, lcd_demo_png_start, png_len),
|
||||
ESP_FAIL,
|
||||
TAG,
|
||||
"png header decode failed: %s",
|
||||
image.message);
|
||||
if (!png_image_begin_read_from_memory(&image, png, png_len)) {
|
||||
const char *png_err = image.message[0] != '\0' ? image.message : "png header decode failed";
|
||||
lcd_fill_err(err, err_len, png_err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_GOTO_ON_FALSE(image.width > 0 && image.height > 0, ESP_ERR_INVALID_SIZE, fail, TAG, "invalid png size");
|
||||
ESP_GOTO_ON_FALSE(image.width <= UINT16_MAX && image.height <= UINT16_MAX,
|
||||
ESP_ERR_INVALID_SIZE,
|
||||
@@ -59,21 +59,21 @@ esp_err_t platform_lcd_decode_demo_png(uint16_t **out_pixels,
|
||||
"png dimensions too large");
|
||||
ESP_GOTO_ON_FALSE(image.width <= SIZE_MAX / image.height, ESP_ERR_INVALID_SIZE, fail, TAG, "png too large");
|
||||
|
||||
image.format = PNG_FORMAT_RGB;
|
||||
png_alloc_size_t rgb_size = PNG_IMAGE_SIZE(image);
|
||||
ESP_GOTO_ON_FALSE(rgb_size > 0, ESP_ERR_INVALID_SIZE, fail, TAG, "png output size invalid");
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
png_alloc_size_t rgba_size = PNG_IMAGE_SIZE(image);
|
||||
ESP_GOTO_ON_FALSE(rgba_size > 0, ESP_ERR_INVALID_SIZE, fail, TAG, "png output size invalid");
|
||||
|
||||
uint8_t *rgb = (uint8_t *)heap_caps_malloc((size_t)rgb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
if (rgb == NULL) {
|
||||
rgb = (uint8_t *)heap_caps_malloc((size_t)rgb_size, MALLOC_CAP_8BIT);
|
||||
uint8_t *rgba = (uint8_t *)heap_caps_malloc((size_t)rgba_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
if (rgba == NULL) {
|
||||
rgba = (uint8_t *)heap_caps_malloc((size_t)rgba_size, MALLOC_CAP_8BIT);
|
||||
}
|
||||
ESP_GOTO_ON_FALSE(rgb != NULL, ESP_ERR_NO_MEM, fail, TAG, "alloc rgb buffer failed");
|
||||
ESP_GOTO_ON_FALSE(rgba != NULL, ESP_ERR_NO_MEM, fail, TAG, "alloc rgba buffer failed");
|
||||
|
||||
png_alloc_size_t stride = PNG_IMAGE_ROW_STRIDE(image);
|
||||
if (!png_image_finish_read(&image, NULL, rgb, stride, NULL)) {
|
||||
if (!png_image_finish_read(&image, NULL, rgba, stride, NULL)) {
|
||||
const char *png_err = image.message[0] != '\0' ? image.message : "png decode failed";
|
||||
lcd_fill_err(err, err_len, png_err);
|
||||
heap_caps_free(rgb);
|
||||
heap_caps_free(rgba);
|
||||
png_image_free(&image);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -87,16 +87,25 @@ esp_err_t platform_lcd_decode_demo_png(uint16_t **out_pixels,
|
||||
}
|
||||
if (pixels == NULL) {
|
||||
lcd_fill_err(err, err_len, "alloc rgb565 buffer failed");
|
||||
heap_caps_free(rgb);
|
||||
heap_caps_free(rgba);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < pixel_count; ++i) {
|
||||
const size_t base = i * 3u;
|
||||
lv_color_t color = lv_color_make(rgb[base], rgb[base + 1u], rgb[base + 2u]);
|
||||
const size_t base = i * 4u;
|
||||
uint8_t r = rgba[base];
|
||||
uint8_t g = rgba[base + 1u];
|
||||
uint8_t b = rgba[base + 2u];
|
||||
uint8_t a = rgba[base + 3u];
|
||||
if (a < 255u) {
|
||||
r = (uint8_t)((((uint32_t)r * (uint32_t)a) + (255u * (255u - (uint32_t)a)) + 127u) / 255u);
|
||||
g = (uint8_t)((((uint32_t)g * (uint32_t)a) + (255u * (255u - (uint32_t)a)) + 127u) / 255u);
|
||||
b = (uint8_t)((((uint32_t)b * (uint32_t)a) + (255u * (255u - (uint32_t)a)) + 127u) / 255u);
|
||||
}
|
||||
lv_color_t color = lv_color_make(r, g, b);
|
||||
pixels[i] = (uint16_t)color.full;
|
||||
}
|
||||
heap_caps_free(rgb);
|
||||
heap_caps_free(rgba);
|
||||
|
||||
*out_pixels = pixels;
|
||||
*out_width = (uint16_t)image.width;
|
||||
@@ -111,3 +120,20 @@ fail:
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t platform_lcd_decode_demo_png(uint16_t **out_pixels,
|
||||
uint16_t *out_width,
|
||||
uint16_t *out_height,
|
||||
char *err,
|
||||
size_t err_len)
|
||||
{
|
||||
const size_t png_len = (size_t)(lcd_demo_png_end - lcd_demo_png_start);
|
||||
ESP_RETURN_ON_FALSE(png_len > 0, ESP_ERR_INVALID_SIZE, TAG, "empty png data");
|
||||
return platform_lcd_decode_png_rgb565(lcd_demo_png_start,
|
||||
png_len,
|
||||
out_pixels,
|
||||
out_width,
|
||||
out_height,
|
||||
err,
|
||||
err_len);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user