From 0a12e654795db2fc1871b3b9e1fc9034be29e2e3 Mon Sep 17 00:00:00 2001 From: Xu Xingliang Date: Wed, 6 Dec 2023 23:36:02 +0800 Subject: [PATCH] fix(draw): use image area to check if decoded image usable Fix #4838 Signed-off-by: Xu Xingliang --- src/draw/sw/lv_draw_sw_img.c | 48 +++++++++++++++++++++------ src/libs/bin_decoder/lv_bin_decoder.c | 4 +-- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/draw/sw/lv_draw_sw_img.c b/src/draw/sw/lv_draw_sw_img.c index bfd762becfae..8e85f1cb5028 100644 --- a/src/draw/sw/lv_draw_sw_img.c +++ b/src/draw/sw/lv_draw_sw_img.c @@ -252,15 +252,42 @@ static void img_decode_and_draw(lv_draw_unit_t * draw_unit, const lv_draw_image_ sup.palette = decoder_dsc->palette; sup.palette_size = decoder_dsc->palette_size; - /*The whole image is available, just draw it*/ - if(decoder_dsc->decoded || decoder_dsc->img_data) { + const lv_draw_buf_t * decoded = decoder_dsc->decoded; + + /*For backward compatibility, will be removed*/ + if(decoder_dsc->img_data) { img_draw_core(draw_unit, draw_dsc, decoder_dsc, &sup, img_area, clipped_img_area); + return; } - /*Draw in smaller pieces*/ - else { - lv_area_t relative_full_area_to_decode = *clipped_img_area; - lv_area_move(&relative_full_area_to_decode, -img_area->x1, -img_area->y1); + lv_area_t relative_full_area_to_decode = *clipped_img_area; + lv_area_move(&relative_full_area_to_decode, -img_area->x1, -img_area->y1); + + if(decoded) { + lv_area_t decoded_area = { + .x1 = 0, + .y1 = 0, + .x2 = decoder_dsc->header.w - 1, + .y2 = decoder_dsc->header.h - 1, + }; + + _lv_area_intersect(&relative_full_area_to_decode, &relative_full_area_to_decode, &decoded_area); + + decoded_area.x2 = decoded->header.w - 1; + decoded_area.y2 = decoded->header.h - 1; + + /*Decoded image can be used.*/ + if(_lv_area_is_in(&relative_full_area_to_decode, &decoded_area, 0)) { + img_draw_core(draw_unit, draw_dsc, decoder_dsc, &sup, img_area, clipped_img_area); + return; + } + else { + LV_LOG_USER("area not ready"); + } + } + + /*Draw in smaller pieces*/ + { lv_area_t relative_decoded_area; relative_decoded_area.x1 = LV_COORD_MIN; relative_decoded_area.y1 = LV_COORD_MIN; @@ -300,10 +327,11 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t cf = LV_COLOR_FORMAT_IS_INDEXED(cf) ? LV_COLOR_FORMAT_ARGB8888 : cf; - if(decoder_dsc->decoded) { - src_buf = decoder_dsc->decoded->data; - img_stride = decoder_dsc->decoded->header.stride; - cf = decoder_dsc->decoded->header.cf; + const lv_draw_buf_t * decoded = decoder_dsc->decoded; + if(decoded) { + src_buf = decoded->data; + img_stride = decoded->header.stride; + cf = decoded->header.cf; } lv_memzero(&blend_dsc, sizeof(lv_draw_sw_blend_dsc_t)); diff --git a/src/libs/bin_decoder/lv_bin_decoder.c b/src/libs/bin_decoder/lv_bin_decoder.c index b265144af243..3a2ffcb1e646 100644 --- a/src/libs/bin_decoder/lv_bin_decoder.c +++ b/src/libs/bin_decoder/lv_bin_decoder.c @@ -388,7 +388,7 @@ lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod int32_t w_px = lv_area_get_width(full_area); uint8_t * img_data = NULL; lv_draw_buf_t * decoded = NULL; - uint32_t offset = 0; + uint32_t offset = sizeof(lv_image_header_t); /*All image starts with image header*/ /*We only support read line by line for now*/ if(decoded_area->y1 == LV_COORD_MIN) { @@ -432,7 +432,6 @@ lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod offset += decoded_area->y1 * dsc->header.stride; offset += decoded_area->x1 * bpp / 8; /*Move to x1*/ if(dsc->src_type == LV_IMAGE_SRC_FILE) { - offset += sizeof(lv_image_header_t); /*File image starts with image header*/ buf = lv_malloc(len); LV_ASSERT_NULL(buf); if(buf == NULL) @@ -445,6 +444,7 @@ lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod } } else { + offset -= sizeof(lv_image_header_t); const lv_image_dsc_t * image = dsc->src; buf = (void *)(image->data + offset); }