From 9598ddeb3dff4e51a9989067e912baf502410cee Mon Sep 17 00:00:00 2001 From: Heiko Lewin Date: Sun, 10 Mar 2024 13:32:18 +0100 Subject: [PATCH] encoder_kvazaar.cc: Fix some memory leaks --- libheif/plugins/encoder_kvazaar.cc | 50 +++++++++++++----------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/libheif/plugins/encoder_kvazaar.cc b/libheif/plugins/encoder_kvazaar.cc index eada77f9fe..158f174b04 100644 --- a/libheif/plugins/encoder_kvazaar.cc +++ b/libheif/plugins/encoder_kvazaar.cc @@ -361,6 +361,11 @@ static void copy_plane(kvz_pixel* out_p, } +template +std::unique_ptr make_guard(T* ptr, D&& deleter) { + return std::unique_ptr(ptr, deleter); +} + static struct heif_error kvazaar_encode_image(void* encoder_raw, const struct heif_image* image, heif_image_input_class input_class) { @@ -380,7 +385,8 @@ static struct heif_error kvazaar_encode_ return err; } - kvz_config* config = api->config_alloc(); + auto uconfig = make_guard(api->config_alloc(), [api](kvz_config* cfg) { api->config_destroy(cfg); }); + kvz_config* config = uconfig.get(); api->config_init(config); // param, encoder->preset.c_str(), encoder->tune.c_str()); #if HAVE_KVAZAAR_ENABLE_LOGGING config->enable_logging_output = 0; @@ -541,9 +547,9 @@ static struct heif_error kvazaar_encode_ } */ - kvz_picture* pic = api->picture_alloc_csp(kvzChroma, encoded_width, encoded_height); + auto upic = make_guard(api->picture_alloc_csp(kvzChroma, encoded_width, encoded_height), [api](kvz_picture* pic) { api->picture_free(pic); }); + kvz_picture* pic = upic.get(); if (!pic) { - api->config_destroy(config); return heif_error{ heif_error_Encoder_plugin_error, heif_suberror_Encoder_encoding, @@ -573,11 +579,9 @@ static struct heif_error kvazaar_encode_ encoded_width >> chroma_stride_shift, encoded_height >> chroma_height_shift); } - kvz_encoder* kvzencoder = api->encoder_open(config); + auto uencoder = make_guard(api->encoder_open(config), [api](kvz_encoder* e) { api->encoder_close(e); }); + kvz_encoder* kvzencoder = uencoder.get(); if (!kvzencoder) { - api->picture_free(pic); - api->config_destroy(config); - return heif_error{ heif_error_Encoder_plugin_error, heif_suberror_Encoder_encoding, @@ -586,14 +590,18 @@ static struct heif_error kvazaar_encode_ } kvz_data_chunk* data = nullptr; + auto free_data = [api](kvz_data_chunk** data){ + if(*data) { + api->chunk_free(*data); + *data = nullptr; + } + }; + auto data_deleter = std::unique_ptr(&data, free_data); + uint32_t data_len; int success; success = api->encoder_headers(kvzencoder, &data, &data_len); if (!success) { - api->picture_free(pic); - api->config_destroy(config); - api->encoder_close(kvzencoder); - return heif_error{ heif_error_Encoder_plugin_error, heif_suberror_Encoder_encoding, @@ -602,17 +610,13 @@ static struct heif_error kvazaar_encode_ } append_chunk_data(data, encoder->output_data); + free_data(&data); success = api->encoder_encode(kvzencoder, pic, &data, &data_len, nullptr, nullptr, nullptr); if (!success) { - api->chunk_free(data); - api->picture_free(pic); - api->config_destroy(config); - api->encoder_close(kvzencoder); - return heif_error{ heif_error_Encoder_plugin_error, heif_suberror_Encoder_encoding, @@ -621,6 +625,7 @@ static struct heif_error kvazaar_encode_ } append_chunk_data(data, encoder->output_data); + free_data(&data); for (;;) { success = api->encoder_encode(kvzencoder, @@ -628,11 +633,6 @@ static struct heif_error kvazaar_encode_ &data, &data_len, nullptr, nullptr, nullptr); if (!success) { - api->chunk_free(data); - api->picture_free(pic); - api->config_destroy(config); - api->encoder_close(kvzencoder); - return heif_error{ heif_error_Encoder_plugin_error, heif_suberror_Encoder_encoding, @@ -645,16 +645,10 @@ static struct heif_error kvazaar_encode_ } append_chunk_data(data, encoder->output_data); + free_data(&data); } (void) success; - - api->chunk_free(data); - - api->encoder_close(kvzencoder); - api->picture_free(pic); - api->config_destroy(config); - return heif_error_ok; }