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 9d484fb61..643460cde 100644 Binary files a/tests/ref_imgs/libs/png_1.png and b/tests/ref_imgs/libs/png_1.png differ diff --git a/tests/src/test_assets/test_img_lvgl_logo_8bit_palette.png b/tests/src/test_assets/test_img_lvgl_logo_8bit_palette.png new file mode 100755 index 000000000..555614b4e Binary files /dev/null and b/tests/src/test_assets/test_img_lvgl_logo_8bit_palette.png differ diff --git a/tests/src/test_cases/libs/test_lodepng.c b/tests/src/test_cases/libs/test_lodepng.c index dae39b78b..ce68cec0e 100644 --- a/tests/src/test_cases/libs/test_lodepng.c +++ b/tests/src/test_cases/libs/test_lodepng.c @@ -21,6 +21,7 @@ static void create_images(void) lv_obj_t * img; lv_obj_t * label; + /* PNG array */ LV_IMG_DECLARE(test_img_lvgl_logo_png); img = lv_image_create(lv_screen_active()); 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_obj_align(label, LV_ALIGN_CENTER, -100, 20); + /* 32 bit PNG file */ img = lv_image_create(lv_screen_active()); 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()); - lv_label_set_text(label, "File"); - lv_obj_align(label, LV_ALIGN_CENTER, 100, 20); + lv_label_set_text(label, "File (32 bit)"); + 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)