Modify memory allocation and deallocation of source buffer for encode & decode 40/124940/5 submit/tizen/20170420.025830
authorJiyong Min <jiyong.min@samsung.com>
Thu, 13 Apr 2017 05:40:38 +0000 (14:40 +0900)
committerJiyong Min <jiyong.min@samsung.com>
Mon, 17 Apr 2017 09:19:13 +0000 (18:19 +0900)
 [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 <jiyong.min@samsung.com>
include/image_util_private.h
src/image_util.c

index eef9732..4d7673e 100755 (executable)
@@ -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;
index 6fec0aa..4c4f208 100755 (executable)
@@ -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);