From a0e75077d8c1c845bb90f919eb80888027af362f Mon Sep 17 00:00:00 2001 From: PGNetHun Date: Tue, 2 Jan 2024 07:18:45 +0100 Subject: [PATCH] fix(lodepng): fix LodePNG 8 bit palette image to RGBA data conversion bug (#5108) --- src/libs/lodepng/lodepng.c | 25 +++++++++++------- src/libs/lodepng/lv_lodepng.c | 10 ++++++- tests/ref_imgs/libs/png_1.png | Bin 5607 -> 11880 bytes .../test_img_lvgl_logo_8bit_palette.png | Bin 0 -> 1838 bytes tests/src/test_cases/libs/test_lodepng.c | 17 +++++++++--- 5 files changed, 39 insertions(+), 13 deletions(-) create mode 100755 tests/src/test_assets/test_img_lvgl_logo_8bit_palette.png diff --git a/src/libs/lodepng/lodepng.c b/src/libs/lodepng/lodepng.c index 1663decde..385cf4588 100644 --- a/src/libs/lodepng/lodepng.c +++ b/src/libs/lodepng/lodepng.c @@ -5326,7 +5326,7 @@ unsigned lodepng_decode(unsigned char ** out, unsigned * w, unsigned * h, LodePNGState * state, const unsigned char * in, size_t insize) { - *out = 0; + *out = NULL; decodeGeneric(out, w, h, state, in, insize); if(state->error) return state->error; 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*/ - unsigned char * data = *out; - size_t outsize; + lv_draw_buf_t * old_buf = (lv_draw_buf_t *)*out; /*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"*/ @@ -5349,14 +5348,22 @@ unsigned lodepng_decode(unsigned char ** out, unsigned * w, unsigned * h, return 56; /*unsupported color mode conversion*/ } - outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); - *out = (unsigned char *)lodepng_malloc(outsize); - if(!(*out)) { + lv_draw_buf_t * new_buf = lv_draw_buf_create(*w, *h, LV_COLOR_FORMAT_ARGB8888, 4 * *w); + if(new_buf == NULL) { state->error = 83; /*alloc fail*/ } - else state->error = lodepng_convert(*out, data, &state->info_raw, - &state->info_png.color, *w, *h); - lodepng_free(data); + else { + state->error = lodepng_convert(new_buf->data, old_buf->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; } diff --git a/src/libs/lodepng/lv_lodepng.c b/src/libs/lodepng/lv_lodepng.c index 09ea619ff..93cab2f18 100644 --- a/src/libs/lodepng/lv_lodepng.c +++ b/src/libs/lodepng/lv_lodepng.c @@ -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); + 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*/ if(args && args->stride_align) { 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 */ unsigned error = lodepng_decode32((unsigned char **)&decoded, &png_width, &png_height, png_data, png_data_size); if(error) { - if(img_data != NULL) lv_draw_buf_destroy(decoded); + if(img_data != NULL) lv_draw_buf_destroy(decoded); return NULL; } diff --git a/tests/ref_imgs/libs/png_1.png b/tests/ref_imgs/libs/png_1.png index 9d484fb615b75eb36956a7d802ea3cacd61e38f0..643460cdeeca2f86f22e6e179d4a69f7ea0f1b4d 100644 GIT binary patch literal 11880 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 X6zQrox}AY`3qj9im1Xjz4SfC^aB5NG literal 5607 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 W`