You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.6 KiB

From 9598ddeb3dff4e51a9989067e912baf502410cee Mon Sep 17 00:00:00 2001
From: Heiko Lewin <hlewin@worldiety.de>
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<typename T, typename D>
+std::unique_ptr<T, D> make_guard(T* ptr, D&& deleter) {
+ return std::unique_ptr<T, D>(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<kvz_data_chunk*, decltype(free_data)>(&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;
}