mirror of
https://github.com/lvgl/lvgl.git
synced 2026-08-18 02:38:01 +08:00
fix(bin_decoder): fix memory leak (#5990)
This commit is contained in:
+11
-11
@@ -82,15 +82,14 @@ typedef lv_result_t (*lv_image_decoder_info_f_t)(lv_image_decoder_t * decoder, c
|
||||
typedef lv_result_t (*lv_image_decoder_open_f_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
|
||||
* Decode `full_area` pixels incrementally by calling in a loop. Set `decoded_area` values to `LV_COORD_MIN` on first call.
|
||||
* Required only if the "open" function can't return with the whole decoded pixel array.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param x start x coordinate
|
||||
* @param y start y coordinate
|
||||
* @param len number of pixels to decode
|
||||
* @param buf a buffer to store the decoded pixels
|
||||
* @return LV_RESULT_OK: ok; LV_RESULT_INVALID: failed
|
||||
* @param full_area input parameter. the full area to decode after enough subsequent calls
|
||||
* @param decoded_area input+output parameter. set the values to `LV_COORD_MIN` for the first call and to reset decoding.
|
||||
* the decoded area is stored here after each call.
|
||||
* @return LV_RESULT_OK: ok; LV_RESULT_INVALID: failed or there is nothing left to decode
|
||||
*/
|
||||
typedef lv_result_t (*lv_image_decoder_get_area_cb_t)(lv_image_decoder_t * decoder,
|
||||
lv_image_decoder_dsc_t * dsc,
|
||||
@@ -217,12 +216,13 @@ lv_result_t lv_image_decoder_get_info(const void * src, lv_image_header_t * head
|
||||
*/
|
||||
lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src, const lv_image_decoder_args_t * args);
|
||||
|
||||
/**
|
||||
* Decode an area of the opened image
|
||||
/***
|
||||
* Decode `full_area` pixels incrementally by calling in a loop. Set `decoded_area` to `LV_COORD_MIN` on first call.
|
||||
* @param dsc image decoder descriptor
|
||||
* @param full_area start X coordinate (from left)
|
||||
* @param decoded_area start Y coordinate (from top)
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: an error occurred
|
||||
* @param full_area input parameter. the full area to decode after enough subsequent calls
|
||||
* @param decoded_area input+output parameter. set the values to `LV_COORD_MIN` for the first call and to reset decoding.
|
||||
* the decoded area is stored here after each call.
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: an error occurred or there is nothing left to decode
|
||||
*/
|
||||
lv_result_t lv_image_decoder_get_area(lv_image_decoder_dsc_t * dsc, const lv_area_t * full_area,
|
||||
lv_area_t * decoded_area);
|
||||
|
||||
@@ -363,7 +363,7 @@ void lv_bin_decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t *
|
||||
|
||||
free_decoder_data(dsc);
|
||||
|
||||
if(dsc->cache_entry) {
|
||||
if(dsc->cache && dsc->cache_entry) {
|
||||
/*Decoded data is in cache, release it from cache's callback*/
|
||||
lv_cache_release(dsc->cache, dsc->cache_entry, NULL);
|
||||
}
|
||||
@@ -407,23 +407,20 @@ lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod
|
||||
/*We only support read line by line for now*/
|
||||
if(decoded_area->y1 == LV_COORD_MIN) {
|
||||
/*Indexed image is converted to ARGB888*/
|
||||
uint32_t len = LV_COLOR_FORMAT_IS_INDEXED(cf) ? sizeof(lv_color32_t) * 8 : bpp;
|
||||
lv_color_format_t cf_decoded = LV_COLOR_FORMAT_IS_INDEXED(cf) ? LV_COLOR_FORMAT_ARGB8888 : cf;
|
||||
|
||||
len = (len * w_px) / 8;
|
||||
decoded = decoder_data->decoded_partial;
|
||||
if(decoded && decoded->header.w == w_px) {
|
||||
/*Use existing one directly*/
|
||||
}
|
||||
else {
|
||||
decoded = lv_draw_buf_reshape(decoder_data->decoded_partial, cf_decoded, w_px, 1, LV_STRIDE_AUTO);
|
||||
if(decoded == NULL) {
|
||||
if(decoder_data->decoded_partial != NULL) {
|
||||
lv_draw_buf_destroy(decoder_data->decoded_partial);
|
||||
decoder_data->decoded_partial = NULL;
|
||||
}
|
||||
decoded = lv_draw_buf_create(w_px, 1, cf_decoded, LV_STRIDE_AUTO);
|
||||
if(decoded == NULL)
|
||||
return LV_RESULT_INVALID;
|
||||
if(decoded == NULL) return LV_RESULT_INVALID;
|
||||
decoder_data->decoded_partial = decoded; /*Free on decoder close*/
|
||||
}
|
||||
|
||||
*decoded_area = *full_area;
|
||||
decoded_area->y2 = decoded_area->y1;
|
||||
decoder_data->decoded_partial = decoded; /*Free on decoder close*/
|
||||
}
|
||||
else {
|
||||
decoded_area->y1++;
|
||||
|
||||
+14
-1
@@ -200,7 +200,20 @@ static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod
|
||||
if(decoded_area->y1 == LV_COORD_MIN) {
|
||||
*decoded_area = *full_area;
|
||||
decoded_area->y2 = decoded_area->y1;
|
||||
if(decoded == NULL) decoded = lv_draw_buf_create(lv_area_get_width(full_area), 1, dsc->header.cf, LV_STRIDE_AUTO);
|
||||
int32_t w_px = lv_area_get_width(full_area);
|
||||
lv_draw_buf_t * reshaped = lv_draw_buf_reshape(decoded, dsc->header.cf, w_px, 1, LV_STRIDE_AUTO);
|
||||
if(reshaped == NULL) {
|
||||
if(decoded != NULL) {
|
||||
lv_draw_buf_destroy(decoded);
|
||||
decoded = NULL;
|
||||
dsc->decoded = NULL;
|
||||
}
|
||||
decoded = lv_draw_buf_create(w_px, 1, dsc->header.cf, LV_STRIDE_AUTO);
|
||||
if(decoded == NULL) return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
decoded = reshaped;
|
||||
}
|
||||
dsc->decoded = decoded;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -216,8 +216,6 @@ static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod
|
||||
|
||||
JDEC * jd = dsc->user_data;
|
||||
lv_draw_buf_t * decoded = (void *)dsc->decoded;
|
||||
if(decoded == NULL) decoded = lv_malloc_zeroed(sizeof(lv_draw_buf_t));
|
||||
dsc->decoded = decoded;
|
||||
|
||||
uint32_t mx, my;
|
||||
mx = jd->msx * 8;
|
||||
@@ -231,6 +229,15 @@ static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod
|
||||
jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; /* Initialize DC values */
|
||||
jd->rst = 0;
|
||||
jd->rsc = 0;
|
||||
if(decoded == NULL) {
|
||||
decoded = lv_malloc_zeroed(sizeof(lv_draw_buf_t));
|
||||
dsc->decoded = decoded;
|
||||
}
|
||||
else {
|
||||
lv_fs_seek(jd->device, 0, LV_FS_SEEK_SET);
|
||||
JRESULT rc = jd_prepare(jd, input_func, jd->pool_original, (size_t)TJPGD_WORKBUFF_SIZE, jd->device);
|
||||
if(rc) return rc;
|
||||
}
|
||||
decoded->data = jd->workbuf;
|
||||
decoded->header = dsc->header;
|
||||
decoded->header.stride = mx * 3;
|
||||
|
||||
Reference in New Issue
Block a user