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,
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;
}

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);
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;
}

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 * 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)