From 7b993beb44392ed3384394ec5bdb8c00e705b131 Mon Sep 17 00:00:00 2001 From: Jiyong Min Date: Thu, 13 Apr 2017 14:40:38 +0900 Subject: [PATCH] Modify memory allocation and deallocation of source buffer for encode & decode [Problem] C#, the instance of encode & decode need to run without memory consideration But the source buffer can not reuse on image-util framework(native). [Solution] It is added to add & destroy source buffer. Change-Id: I10848a2099d5a533e406ecda605db45380c9dfd4 Signed-off-by: Jiyong Min --- include/image_util_private.h | 3 +- src/image_util.c | 250 ++++++++++++++++++++----------------------- 2 files changed, 120 insertions(+), 133 deletions(-) diff --git a/include/image_util_private.h b/include/image_util_private.h index eef9732..4d7673e 100755 --- a/include/image_util_private.h +++ b/include/image_util_private.h @@ -114,11 +114,12 @@ typedef struct { unsigned long long src_size; void **dst_buffer; unsigned long long dst_size; - const char *path; + char *path; mm_util_imgp_h image_h; unsigned long width; unsigned long height; bool is_decode; + bool is_encoded; int quality; unsigned int image_count; unsigned int current_buffer_count; diff --git a/src/image_util.c b/src/image_util.c index 6fec0aa..4c4f208 100755 --- a/src/image_util.c +++ b/src/image_util.c @@ -900,12 +900,24 @@ int image_util_foreach_supported_colorspace(image_util_type_e image_type, image_ return IMAGE_UTIL_ERROR_NONE; } +static void _image_util_decode_destroy_image_handle(decode_encode_s * handle) +{ + image_util_retm_if((handle == NULL), "Invalid Handle"); + void *image_handle = (void *)(handle->image_h); + image_util_retm_if((image_handle == NULL), "Invalid image handle"); + + IMAGE_UTIL_SAFE_FREE(image_handle); +} + static int _image_util_decode_create_jpeg_handle(decode_encode_s * handle) { int err = MM_UTIL_ERROR_NONE; image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + /* It is needed to reuse decode handle for C#, so it shoud be reallocated */ + _image_util_decode_destroy_image_handle(handle); + mm_util_jpeg_yuv_data *_handle = (mm_util_jpeg_yuv_data *) calloc(1, sizeof(mm_util_jpeg_yuv_data)); image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY); @@ -922,6 +934,9 @@ static int _image_util_decode_create_png_handle(decode_encode_s * handle) image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + /* It is needed to reuse decode handle for C#, so it shoud be reallocated */ + _image_util_decode_destroy_image_handle(handle); + mm_util_png_data *_handle = (mm_util_png_data *) calloc(1, sizeof(mm_util_png_data)); image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY); @@ -938,6 +953,9 @@ static int _image_util_decode_create_gif_handle(decode_encode_s * handle) image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + /* It is needed to reuse decode handle for C#, so it shoud be reallocated */ + _image_util_decode_destroy_image_handle(handle); + mm_util_gif_data *_handle = (mm_util_gif_data *) calloc(1, sizeof(mm_util_gif_data)); image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY); @@ -952,6 +970,9 @@ static int _image_util_decode_create_bmp_handle(decode_encode_s * handle) image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle"); + /* It is needed to reuse decode handle for C#, so it shoud be reallocated */ + _image_util_decode_destroy_image_handle(handle); + mm_util_bmp_data *_handle = (mm_util_bmp_data *) calloc(1, sizeof(mm_util_bmp_data)); image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY); @@ -1097,7 +1118,7 @@ int image_util_decode_set_input_path(image_util_decode_h handle, const char *pat fp = NULL; free(src_buffer); - _handle->path = path; + _handle->path = g_strndup(path, strlen(path)); return err; } @@ -1116,8 +1137,7 @@ int image_util_decode_set_input_buffer(image_util_decode_h handle, const unsigne return IMAGE_UTIL_ERROR_INVALID_PARAMETER; } - if (_handle->path) - _handle->path = NULL; + IMAGE_UTIL_SAFE_FREE(_handle->path); err = _image_util_decode_create_image_handle(_handle, src_buffer); if (err != IMAGE_UTIL_ERROR_NONE) { @@ -1125,8 +1145,15 @@ int image_util_decode_set_input_buffer(image_util_decode_h handle, const unsigne return err; } - if (!_handle->src_buffer) - _handle->src_buffer = (void *)calloc(1, sizeof(void *)); + IMAGE_UTIL_SAFE_FREE(_handle->src_buffer); + + _handle->src_buffer = (void *)calloc(1, sizeof(void *)); + if (_handle->src_buffer == NULL) { + image_util_error("The memory of input buffer was not allocated"); + _image_util_decode_destroy_image_handle(_handle); + return IMAGE_UTIL_ERROR_OUT_OF_MEMORY; + } + _handle->src_buffer[0] = (void *)src_buffer; _handle->src_size = src_size; @@ -1440,58 +1467,7 @@ int image_util_decode_destroy(image_util_decode_h handle) return IMAGE_UTIL_ERROR_INVALID_PARAMETER; } - switch (_handle->image_type) { - case IMAGE_UTIL_JPEG: - { - mm_util_jpeg_yuv_data *jpeg_data; - - jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h; - if (jpeg_data == NULL) { - image_util_error("Invalid jpeg data"); - return IMAGE_UTIL_ERROR_INVALID_PARAMETER; - } - IMAGE_UTIL_SAFE_FREE(jpeg_data); - } - break; - case IMAGE_UTIL_PNG: - { - mm_util_png_data *png_data; - - png_data = (mm_util_png_data *) _handle->image_h; - if (png_data == NULL) { - image_util_error("Invalid png data"); - return IMAGE_UTIL_ERROR_INVALID_PARAMETER; - } - IMAGE_UTIL_SAFE_FREE(png_data); - } - break; - case IMAGE_UTIL_GIF: - { - mm_util_gif_data *gif_data; - - gif_data = (mm_util_gif_data *) _handle->image_h; - if (gif_data == NULL) { - image_util_error("Invalid gif data"); - return IMAGE_UTIL_ERROR_INVALID_PARAMETER; - } - IMAGE_UTIL_SAFE_FREE(gif_data); - } - break; - case IMAGE_UTIL_BMP: - { - mm_util_bmp_data *bmp_data; - - bmp_data = (mm_util_bmp_data *) _handle->image_h; - if (bmp_data == NULL) { - image_util_error("Invalid bmp data"); - return IMAGE_UTIL_ERROR_INVALID_PARAMETER; - } - IMAGE_UTIL_SAFE_FREE(bmp_data); - } - break; - default: - break; - } + _image_util_decode_destroy_image_handle(_handle); /* g_thread_exit(handle->thread); */ if (_handle->thread) { @@ -1504,6 +1480,54 @@ int image_util_decode_destroy(image_util_decode_h handle) return err; } +static int _image_util_encode_create_gif_buffer(void *data) +{ + mm_util_gif_data *gif_data = (mm_util_gif_data *) data; + image_util_retvm_if((gif_data == NULL), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Invalid Operation"); + + gif_data->frames = (mm_util_gif_frame_data **) calloc(1, sizeof(mm_util_gif_frame_data *)); + if (gif_data->frames == NULL) { + image_util_error("Error - OUT_OF_MEMORY"); + IMAGE_UTIL_SAFE_FREE(gif_data); + return IMAGE_UTIL_ERROR_OUT_OF_MEMORY; + } + gif_data->frames[0] = (mm_util_gif_frame_data *) calloc(1, sizeof(mm_util_gif_frame_data)); + if (gif_data->frames[0] == NULL) { + image_util_error("Error - OUT_OF_MEMORY"); + IMAGE_UTIL_SAFE_FREE(gif_data->frames); + IMAGE_UTIL_SAFE_FREE(gif_data); + return IMAGE_UTIL_ERROR_OUT_OF_MEMORY; + } + + return IMAGE_UTIL_ERROR_NONE; +} + +static void _image_util_encode_destroy_gif_buffer(void *data) +{ + mm_util_gif_data gif_data = (mm_util_gif_data *)data; + unsigned int i = 0; + image_util_retm_if((gif_data == NULL), "Invalid GIF data"); + + for (i = 1; i < gif_data->image_count; i++) + IMAGE_UTIL_SAFE_FREE(gif_data->frames[i]); + IMAGE_UTIL_SAFE_FREE(gif_data->frames[0]); + IMAGE_UTIL_SAFE_FREE(gif_data->frames); +} + +static void _image_util_encode_destroy_image_handle(decode_encode_s * handle) +{ + image_util_retm_if((handle == NULL), "Invalid Handle"); + void *image_handle = (void *)(handle->image_h); + image_util_retm_if((image_handle == NULL), "Invalid image handle"); + + if (handle->image_type == IMAGE_UTIL_GIF) + { + mm_util_encode_close_gif( (mm_util_gif_data *) image_handle); + _image_util_encode_destroy_gif_buffer(image_handle); + } + IMAGE_UTIL_SAFE_FREE(image_handle); +} + static int _image_util_encode_create_jpeg_handle(decode_encode_s * handle) { int err = MM_UTIL_ERROR_NONE; @@ -1545,18 +1569,11 @@ static int _image_util_encode_create_gif_handle(decode_encode_s * handle) mm_util_gif_data *_handle = (mm_util_gif_data *) calloc(1, sizeof(mm_util_gif_data)); image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY); - _handle->frames = (mm_util_gif_frame_data **) calloc(1, sizeof(mm_util_gif_frame_data *)); - if (_handle->frames == NULL) { - image_util_error("Error - OUT_OF_MEMORY"); - IMAGE_UTIL_SAFE_FREE(_handle); - return MM_UTIL_ERROR_OUT_OF_MEMORY; - } - _handle->frames[0] = (mm_util_gif_frame_data *) calloc(1, sizeof(mm_util_gif_frame_data)); - if (_handle->frames[0] == NULL) { - image_util_error("Error - OUT_OF_MEMORY"); - IMAGE_UTIL_SAFE_FREE(_handle->frames); + err = _image_util_encode_create_gif_buffer(_handle); + if (err != IMAGE_UTIL_ERROR_NONE) { + image_util_error("Error - _image_util_encode_init_gif_buffer is failed (%d)", err); IMAGE_UTIL_SAFE_FREE(_handle); - return MM_UTIL_ERROR_OUT_OF_MEMORY; + return err; } handle->image_h = (mm_util_imgp_h) _handle; @@ -1595,6 +1612,7 @@ int image_util_encode_create(image_util_type_e image_type, image_util_encode_h * _handle->path = NULL; _handle->image_h = 0; _handle->is_decode = FALSE; + _handle->is_encoded = FALSE; _handle->image_count = 1; _handle->current_buffer_count = 0; _handle->current_resolution_count = 0; @@ -1875,9 +1893,30 @@ int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigne return IMAGE_UTIL_ERROR_INVALID_PARAMETER; } - _handle->src_buffer = (void *)realloc(_handle->src_buffer, (_handle->current_buffer_count + 1) * sizeof(void *)); - _handle->src_buffer[_handle->current_buffer_count] = (void *)src_buffer; + /* initialize buffer and value for source buffer */ + if (_handle->image_type == IMAGE_UTIL_GIF) { + if (_handle->is_encoded) { + _image_util_encode_destroy_gif_buffer(_handle->image_h); + err = _image_util_encode_create_gif_buffer(_handle->image_h); + if (err != IMAGE_UTIL_ERROR_NONE) { + image_util_error("Error - _image_util_encode_init_gif_buffer is failed (%d)", err); + return err; + } + _handle->is_encoded = FALSE; + _handle->image_count = 1; + _handle->current_buffer_count = 0; + _handle->current_resolution_count = 0; + _handle->current_delay_count = 0; + } + _handle->src_buffer = (void *)realloc(_handle->src_buffer, (_handle->current_buffer_count + 1) * sizeof(void *)); + _handle->src_buffer[_handle->current_buffer_count] = (void *)src_buffer; + } else { + if (_handle->src_buffer == NULL) + _handle->src_buffer = (void *)calloc(1, sizeof(void *)); + _handle->src_buffer[_handle->current_buffer_count] = (void *)src_buffer; + } + /* put the source buffer for animated-gif into array */ if (_handle->image_type == IMAGE_UTIL_GIF) { mm_util_gif_data *gif_data; @@ -1924,7 +1963,10 @@ int image_util_encode_set_output_path(image_util_encode_h handle, const char *pa if (_handle->dst_buffer) _handle->dst_buffer = NULL; - _handle->path = path; + IMAGE_UTIL_SAFE_FREE(_handle->path); + + _handle->path = g_strndup(path, strlen(path)); + if (_handle->image_type == IMAGE_UTIL_GIF) { mm_util_gif_data *gif_data; @@ -1958,8 +2000,7 @@ int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned cha return IMAGE_UTIL_ERROR_INVALID_PARAMETER; } - if (_handle->path) - _handle->path = NULL; + IMAGE_UTIL_SAFE_FREE(_handle->path); _handle->dst_buffer = (void **)dst_buffer; if (_handle->image_type == IMAGE_UTIL_GIF) { @@ -2089,6 +2130,7 @@ int image_util_encode_run(image_util_encode_h handle, unsigned long long *size) image_util_retvm_if((_image_util_check_resolution(_handle->width, _handle->height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution"); err = _image_util_encode_internal(_handle); + _handle->is_encoded = TRUE; if (err != MM_UTIL_ERROR_NONE) { image_util_error("Error - encode run"); @@ -2124,6 +2166,7 @@ gpointer _image_util_encode_thread(gpointer data) IMAGE_UTIL_SAFE_FREE(_handle->_encode_cb); _handle->thread = NULL; + _handle->is_encoded = TRUE; image_util_debug("exit thread"); return NULL; @@ -2195,65 +2238,7 @@ int image_util_encode_destroy(image_util_encode_h handle) return IMAGE_UTIL_ERROR_INVALID_PARAMETER; } - switch (_handle->image_type) { - case IMAGE_UTIL_JPEG: - { - mm_util_jpeg_yuv_data *jpeg_data; - - jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h; - if (jpeg_data == NULL) { - image_util_error("Invalid jpeg data"); - return IMAGE_UTIL_ERROR_INVALID_PARAMETER; - } - IMAGE_UTIL_SAFE_FREE(jpeg_data); - } - break; - case IMAGE_UTIL_PNG: - { - mm_util_png_data *png_data; - - png_data = (mm_util_png_data *) _handle->image_h; - if (png_data == NULL) { - image_util_error("Invalid png data"); - return IMAGE_UTIL_ERROR_INVALID_PARAMETER; - } - IMAGE_UTIL_SAFE_FREE(png_data); - } - break; - case IMAGE_UTIL_GIF: - { - mm_util_gif_data *gif_data; - unsigned int i = 0; - - gif_data = (mm_util_gif_data *) _handle->image_h; - if (gif_data == NULL) { - image_util_error("Invalid gif data"); - return IMAGE_UTIL_ERROR_INVALID_PARAMETER; - } - mm_util_encode_close_gif(gif_data); - for (i = 1; i < _handle->image_count; i++) - IMAGE_UTIL_SAFE_FREE(gif_data->frames[i]); - IMAGE_UTIL_SAFE_FREE(gif_data->frames[0]); - IMAGE_UTIL_SAFE_FREE(gif_data->frames); - IMAGE_UTIL_SAFE_FREE(gif_data); - } - break; - case IMAGE_UTIL_BMP: - { - mm_util_bmp_data *bmp_data; - - bmp_data = (mm_util_bmp_data *) _handle->image_h; - if (bmp_data == NULL) { - image_util_error("Invalid bmp data"); - return IMAGE_UTIL_ERROR_INVALID_PARAMETER; - } - IMAGE_UTIL_SAFE_FREE(bmp_data); - } - break; - default: - err = IMAGE_UTIL_ERROR_INVALID_PARAMETER; - break; - } + _image_util_encode_destroy_image_handle(_handle); /* g_thread_exit(handle->thread); */ if (_handle->thread) { @@ -2261,6 +2246,7 @@ int image_util_encode_destroy(image_util_encode_h handle) IMAGE_UTIL_SAFE_FREE(_handle->_encode_cb); } + IMAGE_UTIL_SAFE_FREE(_handle->path); IMAGE_UTIL_SAFE_FREE(_handle->src_buffer); IMAGE_UTIL_SAFE_FREE(_handle); -- 2.7.4