fix(lodepng): fix LodePNG 8 bit palette image to RGBA data conversion bug (#5108)

This commit is contained in:
PGNetHun
2024-01-02 07:18:45 +01:00
committed by GitHub
parent 91f336c69e
commit a0e75077d8
5 changed files with 39 additions and 13 deletions

View File

@@ -5326,7 +5326,7 @@ unsigned lodepng_decode(unsigned char ** out, unsigned * w, unsigned * h,
LodePNGState * state, LodePNGState * state,
const unsigned char * in, size_t insize) const unsigned char * in, size_t insize)
{ {
*out = 0; *out = NULL;
decodeGeneric(out, w, h, state, in, insize); decodeGeneric(out, w, h, state, in, insize);
if(state->error) return state->error; if(state->error) return state->error;
if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) { if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) {
@@ -5339,8 +5339,7 @@ unsigned lodepng_decode(unsigned char ** out, unsigned * w, unsigned * h,
} }
} }
else { /*color conversion needed*/ else { /*color conversion needed*/
unsigned char * data = *out; lv_draw_buf_t * old_buf = (lv_draw_buf_t *)*out;
size_t outsize;
/*TODO: check if this works according to the statement in the documentation: "The converter can convert /*TODO: check if this works according to the statement in the documentation: "The converter can convert
from grayscale input color type, to 8-bit grayscale or grayscale with alpha"*/ from grayscale input color type, to 8-bit grayscale or grayscale with alpha"*/
@@ -5349,14 +5348,22 @@ unsigned lodepng_decode(unsigned char ** out, unsigned * w, unsigned * h,
return 56; /*unsupported color mode conversion*/ return 56; /*unsupported color mode conversion*/
} }
outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); lv_draw_buf_t * new_buf = lv_draw_buf_create(*w, *h, LV_COLOR_FORMAT_ARGB8888, 4 * *w);
*out = (unsigned char *)lodepng_malloc(outsize); if(new_buf == NULL) {
if(!(*out)) {
state->error = 83; /*alloc fail*/ state->error = 83; /*alloc fail*/
} }
else state->error = lodepng_convert(*out, data, &state->info_raw, else {
&state->info_png.color, *w, *h); state->error = lodepng_convert(new_buf->data, old_buf->data,
lodepng_free(data); &state->info_raw, &state->info_png.color, *w, *h);
if (state->error) {
lv_draw_buf_destroy(new_buf);
new_buf = NULL;
}
}
*out = (unsigned char*)new_buf;
lv_draw_buf_destroy(old_buf);
} }
return state->error; return state->error;
} }

View File

@@ -182,6 +182,14 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
} }
lv_draw_buf_t * decoded = decode_png_data(png_data, png_data_size); lv_draw_buf_t * decoded = decode_png_data(png_data, png_data_size);
if(!decoded) {
LV_LOG_WARN("Error decoding PNG\n");
if(png_data != NULL) {
lv_free((void *)png_data);
}
return LV_RESULT_INVALID;
}
/*Stride check and adjustment accordingly*/ /*Stride check and adjustment accordingly*/
if(args && args->stride_align) { if(args && args->stride_align) {
uint32_t expected = lv_draw_buf_width_to_stride(decoded->header.w, decoded->header.cf); uint32_t expected = lv_draw_buf_width_to_stride(decoded->header.w, decoded->header.cf);
@@ -248,7 +256,7 @@ static lv_draw_buf_t * decode_png_data(const void * png_data, size_t png_data_si
/*Decode the image in ARGB8888 */ /*Decode the image in ARGB8888 */
unsigned error = lodepng_decode32((unsigned char **)&decoded, &png_width, &png_height, png_data, png_data_size); unsigned error = lodepng_decode32((unsigned char **)&decoded, &png_width, &png_height, png_data, png_data_size);
if(error) { if(error) {
if(img_data != NULL) lv_draw_buf_destroy(decoded); if(img_data != NULL) lv_draw_buf_destroy(decoded);
return NULL; return NULL;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -21,6 +21,7 @@ static void create_images(void)
lv_obj_t * img; lv_obj_t * img;
lv_obj_t * label; lv_obj_t * label;
/* PNG array */
LV_IMG_DECLARE(test_img_lvgl_logo_png); LV_IMG_DECLARE(test_img_lvgl_logo_png);
img = lv_image_create(lv_screen_active()); img = lv_image_create(lv_screen_active());
lv_image_set_src(img, &test_img_lvgl_logo_png); lv_image_set_src(img, &test_img_lvgl_logo_png);
@@ -30,13 +31,23 @@ static void create_images(void)
lv_label_set_text(label, "Array"); lv_label_set_text(label, "Array");
lv_obj_align(label, LV_ALIGN_CENTER, -100, 20); lv_obj_align(label, LV_ALIGN_CENTER, -100, 20);
/* 32 bit PNG file */
img = lv_image_create(lv_screen_active()); img = lv_image_create(lv_screen_active());
lv_image_set_src(img, "A:src/test_assets/test_img_lvgl_logo.png"); lv_image_set_src(img, "A:src/test_assets/test_img_lvgl_logo.png");
lv_obj_align(img, LV_ALIGN_CENTER, 100, -20); lv_obj_align(img, LV_ALIGN_CENTER, 100, -100);
label = lv_label_create(lv_screen_active()); label = lv_label_create(lv_screen_active());
lv_label_set_text(label, "File"); lv_label_set_text(label, "File (32 bit)");
lv_obj_align(label, LV_ALIGN_CENTER, 100, 20); lv_obj_align(label, LV_ALIGN_CENTER, 100, -60);
/* 8 bit palette PNG file */
img = lv_image_create(lv_screen_active());
lv_image_set_src(img, "A:src/test_assets/test_img_lvgl_logo_8bit_palette.png");
lv_obj_align(img, LV_ALIGN_CENTER, 100, 60);
label = lv_label_create(lv_screen_active());
lv_label_set_text(label, "File (8 bit palette)");
lv_obj_align(label, LV_ALIGN_CENTER, 100, 100);
} }
void test_lodepng_1(void) void test_lodepng_1(void)