[ACR-512] Add APIs for supporting animated gif encoding utility 86/58686/19
authorVineeth TM <vineeth.tm@samsung.com>
Mon, 1 Feb 2016 07:10:30 +0000 (16:10 +0900)
committerVineeth T M <vineeth.tm@samsung.com>
Fri, 19 Feb 2016 07:20:06 +0000 (23:20 -0800)
Change-Id: I0887c5fc1433f2629579f17a810bb8617d59677d
Signed-off-by: Vineeth TM <vineeth.tm@samsung.com>
decode-test/image_util_decode_encode_testsuite.c
include/image_util.h
include/image_util_private.h
src/image_util.c

index 2d1d808c22d6485149436a94f4574fc511902e3b..26fcede9198f73b2a15ef7ac358a945f4508dea4 100755 (executable)
@@ -166,20 +166,135 @@ int main(int argc, char *argv[])
        image_util_encode_h encoded = NULL;
        void *src = NULL;
        unsigned char *data = NULL;
+       unsigned char **animated_data = NULL;
        unsigned char *dst = NULL;
        unsigned long long src_size = 0;
        int encode_image_type = -1;
 
-       if (argc < 4) {
+       if (argc < 3) {
                fprintf(stderr, "\t[usage]\n");
-               fprintf(stderr, "\t\t1. decode : mm_util_png_testsuite decode filepath encode_image_type\n");
+               fprintf(stderr, "\t\t1. decode/encode : capi-media-image-util-decode-test decode/decode-mem/decode-async filepath encode_image_type\n");
+               fprintf(stderr, "\t\t2. encode gif : capi-media-image-util-decode-test encode-gif/encode-gif-mem 'folderpath containing png images named \
+                                       with number prefix according to the animation order'\n");
                return 0;
        }
 
        if (argv[3])
                encode_image_type = atoi(argv[3]);
 
-       if (!strcmp("decode", argv[1]) || !strcmp("decode-mem", argv[1]) || !strcmp("decode-async", argv[1])) {
+       if (!strcmp("encode-gif", argv[1]) || !strcmp("encode-gif-mem", argv[1])) {
+               struct dirent *dp;
+               DIR *fd;
+               int number_files = 0, i = 0;
+               char gif_filename[BUFFER_SIZE] = { 0, }, temp_filename[BUFFER_SIZE] = {
+               0,}, temp[BUFFER_SIZE] = {0,}, file_format[BUFFER_SIZE] = {0,};
+               unsigned long gif_image_width[1000] = { 0, }, gif_image_height[1000] = {
+               0,};
+               memset(gif_filename, 0, BUFFER_SIZE);
+               {
+                       snprintf(gif_filename, BUFFER_SIZE, "%s%s", DECODE_RESULT_PATH, "gif");
+               }
+
+               if ((fd = opendir(argv[2])) == NULL) {
+                       fprintf(stderr, "listdir: can't open %s\n", argv[2]);
+                       return 0;
+               }
+
+               while ((dp = readdir(fd)) != NULL) {
+                       if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
+                               continue;               /* skip self and parent */
+                       if(!number_files) {
+                               char *temp1 = strstr(dp->d_name, "-");
+                               char *temp2 = strstr(dp->d_name, ".");
+
+                               strncpy(temp_filename, dp->d_name, strlen(dp->d_name) - strlen(temp1));
+                               strncpy(file_format, temp2, strlen(temp2));
+                       }
+                       number_files++;
+               }
+               closedir(fd);
+               if (!number_files) {
+                       fprintf(stderr, "\t\tCannot open directory\n");
+                       return 0;
+               }
+
+               for (i = 0; i < number_files; i++) {
+                       animated_data = (unsigned char **)realloc(animated_data, (i + 1) * sizeof(unsigned char *));
+                       ret = image_util_decode_create(&decoded);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+
+                       snprintf(temp, BUFFER_SIZE, "%s%s-%d%s", argv[2], temp_filename, i, file_format);
+
+                       ret = image_util_decode_set_input_path(decoded, temp);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+
+                       ret = image_util_decode_set_output_buffer(decoded, &animated_data[i]);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+
+                       ret = image_util_decode_run(decoded, &gif_image_width[i], &gif_image_height[i], NULL);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+
+                       ret = image_util_decode_destroy(decoded);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+               }
+
+               ret = image_util_encode_create(IMAGE_UTIL_GIF, &encoded);
+               if (ret != IMAGE_UTIL_ERROR_NONE)
+                       return 0;
+
+               for (i = 0; i < number_files; i++) {
+                       ret = image_util_encode_set_input_buffer(encoded, animated_data[i]);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+               }
+               for (i = 0; i < number_files; i++) {
+                       ret = image_util_encode_set_resolution(encoded, gif_image_width[i], gif_image_height[i]);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+               }
+               for (i = 0; i < number_files; i++) {
+                       ret = image_util_encode_set_gif_frame_delay_time(encoded, 10);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+               }
+               if (!strcmp("encode-gif-mem", argv[1])) {
+                       ret = image_util_encode_set_output_buffer(encoded, &dst);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+               } else {
+                       ret = image_util_encode_set_output_path(encoded, gif_filename);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+               }
+               ret = image_util_encode_run(encoded, &image_size);
+               if (ret != IMAGE_UTIL_ERROR_NONE)
+                       return 0;
+
+               if (!strcmp("encode-gif-mem", argv[1])) {
+                       _write_file(gif_filename, (void *)dst, image_size);
+                       free(dst);
+               }
+
+               ret = image_util_encode_destroy(encoded);
+               if (ret != IMAGE_UTIL_ERROR_NONE)
+                       return 0;
+
+               for (i = 0; i < number_files; i++)
+                       free(animated_data[i]);
+               free(animated_data);
+
+               return 0;
+       } else if (!strcmp("decode", argv[1]) || !strcmp("decode-mem", argv[1]) || !strcmp("decode-async", argv[1])) {
+               if (argc < 4) {
+                       fprintf(stderr, "\t[usage]\n");
+                       fprintf(stderr, "\t\t1. decode/encode : capi-media-image-util-decode-test decode/decode-mem/decode-async filepath encode_image_type\n");
+                       return 0;
+               }
                ret = image_util_decode_create(&decoded);
                if (ret != IMAGE_UTIL_ERROR_NONE)
                        return 0;
@@ -204,7 +319,7 @@ int main(int argc, char *argv[])
                        ret = image_util_decode_run_async(decoded, (image_util_decode_completed_cb) decode_completed_cb, NULL);
                        _wait();
                } else
-                       ret = image_util_decode_run(decoded, &image_width, &image_height, NULL);
+                       ret = image_util_decode_run(decoded, &image_width, &image_height, &image_size);
                if (ret != IMAGE_UTIL_ERROR_NONE)
                        return 0;
 
@@ -224,6 +339,10 @@ int main(int argc, char *argv[])
                0,};
                memset(filename, 0, BUFFER_SIZE);
 
+               snprintf(filename, BUFFER_SIZE, "%s%s", DECODE_RESULT_PATH, "raw");
+               _write_file(filename, (void *)data, image_size);
+               memset(filename, 0, BUFFER_SIZE);
+
                switch (encode_image_type) {
                case IMAGE_UTIL_JPEG:
                        snprintf(type, 4, "%s", "jpg");
index 0511f34c8572f86f220ec70dd16c46f3fe9f4f69..369653b1f8ae770b0c05583b0d4a9917c878d204 100755 (executable)
@@ -846,7 +846,7 @@ int image_util_decode_create(image_util_decode_h *handle);
 *
 * @pre image_util_decode_create()
 *
-* @post image_util_decode_run()/image_util_decode_run_async()
+* @post image_util_decode_run() / image_util_decode_run_async()
 * @post image_util_decode_destroy()
 *
 * @see image_util_decode_create()
@@ -880,7 +880,7 @@ int image_util_decode_set_input_path(image_util_decode_h handle, const char *pat
 *
 * @pre image_util_decode_create()
 *
-* @post image_util_decode_run()/image_util_decode_run_async()
+* @post image_util_decode_run() / image_util_decode_run_async()
 * @post image_util_decode_destroy()
 *
 * @see image_util_decode_create()
@@ -911,7 +911,7 @@ int image_util_decode_set_input_buffer(image_util_decode_h handle, const unsigne
 *
 * @pre image_util_decode_create()
 *
-* @post image_util_decode_run()/image_util_decode_run_async()
+* @post image_util_decode_run() / image_util_decode_run_async()
 * @post image_util_decode_destroy()
 *
 * @see image_util_decode_create()
@@ -943,7 +943,7 @@ int image_util_decode_set_output_buffer(image_util_decode_h handle, unsigned cha
 *
 * @pre image_util_decode_create()
 *
-* @post image_util_decode_run()/image_util_decode_run_async()
+* @post image_util_decode_run() / image_util_decode_run_async()
 * @post image_util_decode_destroy()
 *
 * @see image_util_supported_colorspace_cb()
@@ -976,7 +976,7 @@ int image_util_decode_set_colorspace(image_util_encode_h handle, image_util_colo
 *
 * @pre image_util_decode_create()
 *
-* @post image_util_decode_run()/image_util_decode_run_async()
+* @post image_util_decode_run() / image_util_decode_run_async()
 * @post image_util_decode_destroy()
 *
 * @see image_util_decode_create()
@@ -1010,7 +1010,7 @@ int image_util_decode_set_jpeg_downscale(image_util_encode_h handle, image_util_
 * @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
 *
 * @pre image_util_decode_create()
-* @pre image_util_decode_set_input_buffer()/image_util_decode_set_input_path().
+* @pre image_util_decode_set_input_buffer() / image_util_decode_set_input_path().
 * @pre image_util_decode_set_output_buffer()
 *
 * @post image_util_decode_destroy()
@@ -1043,7 +1043,7 @@ int image_util_decode_run(image_util_decode_h handle, unsigned long *width, unsi
 * @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
 *
 * @pre image_util_decode_create()
-* @pre image_util_decode_set_input_buffer()/image_util_decode_set_input_path().
+* @pre image_util_decode_set_input_buffer() / image_util_decode_set_input_path().
 * @pre image_util_decode_set_output_buffer()
 *
 * @post image_util_decode_destroy()
@@ -1104,7 +1104,8 @@ int image_util_encode_create(image_util_type_e image_type, image_util_encode_h *
 * @brief Sets the resolution of the encoded image.
 * @since_tizen 3.0
 *
-* @remarks This should be called before calling image_util_encode_run().
+* @remarks This should be called before calling image_util_encode_run().\n
+*          While encoding animated gif image, resolution should be set for each frame.
 *
 * @param[in] handle The handle to image util encoding
 * @param[in] width Width of the original image
@@ -1119,7 +1120,7 @@ int image_util_encode_create(image_util_type_e image_type, image_util_encode_h *
 *
 * @pre image_util_encode_create()
 *
-* @post image_util_encode_run()/image_util_encode_run_async()
+* @post image_util_encode_run() / image_util_encode_run_async()
 * @post image_util_encode_destroy()
 *
 * @see image_util_encode_create()
@@ -1152,7 +1153,7 @@ int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long w
 *
 * @pre image_util_encode_create()
 *
-* @post image_util_encode_run()/image_util_encode_run_async()
+* @post image_util_encode_run() / image_util_encode_run_async()
 * @post image_util_encode_destroy()
 *
 * @see image_util_supported_colorspace_cb()
@@ -1187,7 +1188,7 @@ int image_util_encode_set_colorspace(image_util_encode_h handle, image_util_colo
 *
 * @pre image_util_encode_create()
 *
-* @post image_util_encode_run()/image_util_encode_run_async()
+* @post image_util_encode_run() / image_util_encode_run_async()
 * @post image_util_encode_destroy()
 *
 * @see image_util_encode_create()
@@ -1220,7 +1221,7 @@ int image_util_encode_set_quality(image_util_encode_h handle, int quality);
 *
 * @pre image_util_encode_create()
 *
-* @post image_util_encode_run()/image_util_encode_run_async()
+* @post image_util_encode_run() / image_util_encode_run_async()
 * @post image_util_encode_destroy()
 *
 * @see image_util_encode_create()
@@ -1234,13 +1235,48 @@ int image_util_encode_set_quality(image_util_encode_h handle, int quality);
 */
 int image_util_encode_set_png_compression(image_util_encode_h handle, image_util_png_compression_e compression);
 
+/**
+* @brief Sets the time delay between each frame in the encoded animated gif image.
+* @since_tizen 3.0
+*
+* @remarks In case animated gif image if this is not set then there will be no delay between each frame.\n
+*          This should be set for each frame in the animated gif image.\n
+*          This can be set a different value for each frame, which results in different delay time between different frames.
+*
+* @param[in] handle The handle to image util encoding
+* @param[in] delay_time Time delay between each frame in the encoded image, in 0.01sec units.
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT Format not supported
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+*
+* @pre image_util_encode_create()
+*
+* @post image_util_encode_run() / image_util_encode_run_async()
+* @post image_util_encode_destroy()
+*
+* @see image_util_encode_create()
+* @see image_util_encode_set_resolution()
+* @see image_util_encode_set_input_buffer()
+* @see image_util_encode_set_output_path()
+* @see image_util_encode_set_output_buffer()
+* @see image_util_encode_run()
+* @see image_util_encode_run_async()
+* @see image_util_encode_destroy()
+*/
+int image_util_encode_set_gif_frame_delay_time(image_util_encode_h handle, unsigned long long delay_time);
+
 /**
 * @brief Sets the input buffer from which to encode.
 * @since_tizen 3.0
 *
 * @remarks Either image_util_encode_set_output_path() or image_util_encode_set_output_buffer() should be set.\n
 *          By default the input buffer colorspace will be considered as IMAGE_UTIL_COLORSPACE_RGBA8888.\n
-*          Use image_util_encode_set_colorspace to change the colorspace.
+*          Use image_util_encode_set_colorspace to change the colorspace.\n
+*          While encoding animated gif image, input buffer should be set for each frame.
 *
 * @param[in] handle The handle to image util decoding
 * @param[in] src_buffer The input image buffer
@@ -1254,7 +1290,7 @@ int image_util_encode_set_png_compression(image_util_encode_h handle, image_util
 *
 * @pre image_util_encode_create()
 *
-* @post image_util_encode_run()/image_util_encode_run_async()
+* @post image_util_encode_run() / image_util_encode_run_async()
 * @post image_util_encode_destroy()
 *
 * @see image_util_encode_create()
@@ -1291,7 +1327,7 @@ int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigne
 *
 * @pre image_util_encode_create()
 *
-* @post image_util_encode_run()/image_util_encode_run_async()
+* @post image_util_encode_run() / image_util_encode_run_async()
 * @post image_util_encode_destroy()
 *
 * @see image_util_encode_create()
@@ -1324,7 +1360,7 @@ int image_util_encode_set_output_path(image_util_encode_h handle, const char *pa
 *
 * @pre image_util_encode_create()
 *
-* @post image_util_encode_run()/image_util_encode_run_async()
+* @post image_util_encode_run() / image_util_encode_run_async()
 * @post image_util_encode_destroy()
 *
 * @see image_util_encode_create()
@@ -1342,7 +1378,9 @@ int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned cha
 *
 * @remarks The output will be stored in the pointer set to image_util_encode_set_output_buffer() or image_util_encode_set_output_path().\n
 *              The function executes synchronously.\n
-*              When any of the @pre functions are not called, IMAGE_UTIL_ERROR_INVALID_PARAMETER is returned.
+*              When any of the @pre functions are not called, IMAGE_UTIL_ERROR_INVALID_PARAMETER is returned.\n
+*              In case of animated gif encoding, image_util_encode_set_resolution(), image_util_encode_set_input_buffer() and\n
+*              image_util_encode_set_gif_frame_delay_time() MUST be called for each frame.
 *
 * @param[in] handle The handle to image util encoding
 * @param[out] size Size of the encoded image
@@ -1357,13 +1395,14 @@ int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned cha
 * @pre image_util_encode_create()
 * @pre image_util_encode_set_resolution()
 * @pre image_util_encode_set_input_buffer()
-* @pre image_util_encode_set_output_buffer()/image_util_encode_set_output_path()
+* @pre image_util_encode_set_output_buffer() / image_util_encode_set_output_path()
 *
 * @post image_util_encode_destroy()
 *
 * @see image_util_encode_create()
 * @see image_util_encode_set_resolution()
 * @see image_util_encode_set_input_buffer()
+* @see image_util_encode_set_gif_frame_delay_time()
 * @see image_util_encode_set_output_path()
 * @see image_util_encode_set_output_buffer()
 * @see image_util_encode_destroy()
@@ -1376,7 +1415,9 @@ int image_util_encode_run(image_util_encode_h handle, unsigned long long *size);
 *
 * @remarks The output will be stored in the pointer set to image_util_encode_set_output_buffer() or image_util_encode_set_output_path().\n
 *              The function executes asynchronously, which contains complete callback.\n
-*              When any of the @pre functions are not called, IMAGE_UTIL_ERROR_INVALID_PARAMETER is returned.
+*              When any of the @pre functions are not called, IMAGE_UTIL_ERROR_INVALID_PARAMETER is returned.\n
+*              In case of animated gif encoding, image_util_encode_set_resolution(), image_util_encode_set_input_buffer() and\n
+*              image_util_encode_set_gif_frame_delay_time() MUST be called for each frame.
 *
 * @param[in] handle The handle to image util encoding
 * @param[in] callback The callback function to be invoked
@@ -1392,13 +1433,14 @@ int image_util_encode_run(image_util_encode_h handle, unsigned long long *size);
 * @pre image_util_encode_create()
 * @pre image_util_encode_set_resolution()
 * @pre image_util_encode_set_input_buffer()
-* @pre image_util_encode_set_output_buffer()/image_util_encode_set_output_path()
+* @pre image_util_encode_set_output_buffer() / image_util_encode_set_output_path()
 *
 * @post image_util_encode_destroy()
 *
 * @see image_util_encode_create()
 * @see image_util_encode_set_resolution()
 * @see image_util_encode_set_input_buffer()
+* @see image_util_encode_set_gif_frame_delay_time()
 * @see image_util_encode_set_output_path()
 * @see image_util_encode_set_output_buffer()
 * @see image_util_encode_destroy()
index f4ae7fe739fc46755e6edc721bda256c7fbb88f3..ea42eb49aa13b555b1782a5972eeac6810e6805f 100755 (executable)
@@ -102,7 +102,7 @@ typedef struct {
 
 typedef struct {
        image_util_type_e image_type;
-       void *src_buffer;
+       void **src_buffer;
        unsigned long long src_size;
        void **dst_buffer;
        unsigned long long dst_size;
@@ -112,6 +112,10 @@ typedef struct {
        unsigned long height;
        bool is_decode;
         int quality;
+       unsigned int image_count;
+       unsigned int current_buffer_count;
+       unsigned int current_resolution_count;
+       unsigned int current_delay_count;
        image_util_colorspace_e colorspace;
        image_util_scale_e down_scale;
        decode_cb_s *_decode_cb;
index 234517807051b429992daa27ab3de2dc93f04922..9e3a68d0aca91b6fa4e30ce451e0408804805b03 100755 (executable)
@@ -963,6 +963,7 @@ int image_util_decode_create(image_util_decode_h * handle)
        _handle->image_h = 0;
        _handle->is_decode = TRUE;
        _handle->image_type = -1;
+       _handle->image_count = 1;
 
        *handle = (image_util_decode_h) _handle;
 
@@ -1058,7 +1059,7 @@ int image_util_decode_set_input_path(image_util_decode_h handle, const char *pat
 
        fp = fopen(path, "r");
        if (fp == NULL) {
-               image_util_error("File open failed");
+               image_util_error("File open failed %s", path);
                return IMAGE_UTIL_ERROR_NO_SUCH_FILE;
        }
        src_buffer = (void *)malloc(sizeof(_PNG_HEADER));
@@ -1100,7 +1101,9 @@ int image_util_decode_set_input_buffer(image_util_decode_h handle, const unsigne
 
        err = _image_util_decode_create_image_handle(_handle, src_buffer);
 
-       _handle->src_buffer = (void *)src_buffer;
+       if (!_handle->src_buffer)
+               _handle->src_buffer = (void *)calloc(1, sizeof(void *));
+       _handle->src_buffer[0] = (void *)src_buffer;
        _handle->src_size = src_size;
 
        return err;
@@ -1201,9 +1204,9 @@ static int _image_util_decode_internal(decode_encode_s * _handle)
                                        err = mm_util_decode_from_jpeg_file(jpeg_data, _handle->path, _convert_jpeg_colorspace_tbl[_handle->colorspace]);
                        } else {
                                if (_handle->down_scale < sizeof(image_util_scale_e))
-                                       err = mm_util_decode_from_jpeg_memory_with_downscale(jpeg_data, _handle->src_buffer, _handle->src_size, _convert_jpeg_colorspace_tbl[_handle->colorspace], _convert_decode_scale_tbl[_handle->down_scale]);
+                                       err = mm_util_decode_from_jpeg_memory_with_downscale(jpeg_data, _handle->src_buffer[0], _handle->src_size, _convert_jpeg_colorspace_tbl[_handle->colorspace], _convert_decode_scale_tbl[_handle->down_scale]);
                                else
-                                       err = mm_util_decode_from_jpeg_memory(jpeg_data, _handle->src_buffer, _handle->src_size, _convert_jpeg_colorspace_tbl[_handle->colorspace]);
+                                       err = mm_util_decode_from_jpeg_memory(jpeg_data, _handle->src_buffer[0], _handle->src_size, _convert_jpeg_colorspace_tbl[_handle->colorspace]);
                        }
 
                        if (err == MM_UTIL_ERROR_NONE) {
@@ -1227,7 +1230,7 @@ static int _image_util_decode_internal(decode_encode_s * _handle)
                        if (_handle->path)
                                err = mm_util_decode_from_png_file(png_data, _handle->path);
                        else
-                               err = mm_util_decode_from_png_memory(png_data, &_handle->src_buffer, _handle->src_size);
+                               err = mm_util_decode_from_png_memory(png_data, &_handle->src_buffer[0], _handle->src_size);
 
                        if (err == MM_UTIL_ERROR_NONE) {
                                *(_handle->dst_buffer) = png_data->data;
@@ -1250,10 +1253,10 @@ static int _image_util_decode_internal(decode_encode_s * _handle)
                        if (_handle->path)
                                err = mm_util_decode_from_gif_file(gif_data, _handle->path);
                        else
-                               err = mm_util_decode_from_gif_memory(gif_data, &_handle->src_buffer);
+                               err = mm_util_decode_from_gif_memory(gif_data, &_handle->src_buffer[0]);
 
                        if (err == MM_UTIL_ERROR_NONE) {
-                               *(_handle->dst_buffer) = gif_data->frames[0].data;
+                               *(_handle->dst_buffer) = gif_data->frames[0]->data;
                                _handle->dst_size = gif_data->size;
                                _handle->width = gif_data->width;
                                _handle->height = gif_data->height;
@@ -1273,7 +1276,7 @@ static int _image_util_decode_internal(decode_encode_s * _handle)
                        if (_handle->path)
                                err = mm_util_decode_from_bmp_file(bmp_data, _handle->path);
                        else
-                               err = mm_util_decode_from_bmp_memory(bmp_data, &_handle->src_buffer, _handle->src_size);
+                               err = mm_util_decode_from_bmp_memory(bmp_data, &_handle->src_buffer[0], _handle->src_size);
 
                        if (err == MM_UTIL_ERROR_NONE) {
                                *(_handle->dst_buffer) = bmp_data->data;
@@ -1422,7 +1425,7 @@ int image_util_decode_destroy(image_util_decode_h handle)
        int err = IMAGE_UTIL_ERROR_NONE;
        decode_encode_s *_handle = (decode_encode_s *) handle;
 
-       image_util_debug("image_util_encode_png_destroy");
+       image_util_debug("image_util_decode_destroy");
 
        if (_handle == NULL || _handle->is_decode == FALSE) {
                image_util_error("Invalid Handle");
@@ -1496,7 +1499,7 @@ int image_util_decode_destroy(image_util_decode_h handle)
 
                g_cond_clear(&(_handle->thread_cond));
        }
-
+       IMAGE_UTIL_SAFE_FREE(_handle->src_buffer);
        IMAGE_UTIL_SAFE_FREE(_handle);
 
        return err;
@@ -1543,14 +1546,19 @@ 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));
+       _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);
+               return MM_UTIL_ERROR_OUT_OF_MEMORY;
+       }
 
-       mm_util_gif_encode_set_image_count(_handle, 1);
        handle->image_h = (mm_util_imgp_h) _handle;
 
        return err;
@@ -1587,6 +1595,10 @@ 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->image_count = 1;
+       _handle->current_buffer_count = 0;
+       _handle->current_resolution_count = 0;
+       _handle->current_delay_count = 0;
 
        switch (image_type) {
        case IMAGE_UTIL_JPEG:
@@ -1664,8 +1676,38 @@ int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long w
                                image_util_error("Invalid gif data");
                                return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
                        }
-                       mm_util_gif_encode_set_width(gif_data, width);
-                       mm_util_gif_encode_set_height(gif_data, height);
+
+                       if (!_handle->current_resolution_count) {
+                               mm_util_gif_encode_set_width(gif_data, width);
+                               mm_util_gif_encode_set_height(gif_data, height);
+                               _handle->width = width;
+                               _handle->height = height;
+                       } else if ((width > gif_data->frames[0]->width) || (height > gif_data->frames[0]->height)) {
+                               image_util_error("Image resolution cannot be more than the resolution of the first image");
+                               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+                       }
+
+                       if(_handle->image_count <= _handle->current_resolution_count) {
+                               gif_data->frames = (mm_util_gif_frame_data **) realloc(gif_data->frames, (_handle->image_count + 1) * sizeof(mm_util_gif_frame_data *));
+                               if (gif_data->frames == NULL) {
+                                       image_util_error("Error - OUT_OF_MEMORY");
+                                       IMAGE_UTIL_SAFE_FREE(_handle);
+                                       return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
+                               }
+                               gif_data->frames[_handle->image_count] = (mm_util_gif_frame_data *) calloc(1, sizeof(mm_util_gif_frame_data));
+                               if (gif_data->frames[_handle->image_count] == NULL) {
+                                       image_util_error("Error - OUT_OF_MEMORY");
+                                       IMAGE_UTIL_SAFE_FREE(_handle);
+                                       return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
+                               }
+                               _handle->image_count++;
+                       }
+
+                       gif_data->frames[_handle->current_resolution_count]->width = width;
+                       gif_data->frames[_handle->current_resolution_count]->height = height;
+                       _handle->current_resolution_count++;
+
+                       return err;
                }
                break;
        case IMAGE_UTIL_BMP:
@@ -1773,6 +1815,52 @@ int image_util_encode_set_png_compression(image_util_encode_h handle, image_util
        return err;
 }
 
+int image_util_encode_set_gif_frame_delay_time(image_util_encode_h handle, unsigned long long delay_time)
+{
+       int err = IMAGE_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+       mm_util_gif_data *gif_data;
+
+       if (_handle == NULL || _handle->is_decode == TRUE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       if (_handle->image_type != IMAGE_UTIL_GIF) {
+               image_util_error("Wrong image format");
+               return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
+       }
+
+       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;
+       }
+       if (gif_data->frames == NULL) {
+               image_util_error("Error allocating gif frames.");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       if(_handle->image_count <= _handle->current_delay_count) {
+               gif_data->frames = (mm_util_gif_frame_data **) realloc(gif_data->frames, (_handle->image_count + 1) * sizeof(mm_util_gif_frame_data *));
+               if (gif_data->frames == NULL) {
+                       image_util_error("Error - OUT_OF_MEMORY");
+                       IMAGE_UTIL_SAFE_FREE(_handle);
+                       return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
+               }
+               gif_data->frames[_handle->image_count] = (mm_util_gif_frame_data *) calloc(1, sizeof(mm_util_gif_frame_data));
+               if (gif_data->frames[_handle->image_count] == NULL) {
+                       image_util_error("Error - OUT_OF_MEMORY");
+                       IMAGE_UTIL_SAFE_FREE(_handle);
+                       return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
+               }
+               _handle->image_count++;
+       }
+
+       mm_util_gif_encode_set_frame_delay_time(gif_data->frames[_handle->current_delay_count], delay_time);
+       _handle->current_delay_count++;
+
+       return err;
+}
+
 int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigned char *src_buffer)
 {
        int err = IMAGE_UTIL_ERROR_NONE;
@@ -1787,7 +1875,37 @@ int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigne
                return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
        }
 
-       _handle->src_buffer = (void *)src_buffer;
+       _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;
+
+       if (_handle->image_type == IMAGE_UTIL_GIF) {
+               mm_util_gif_data *gif_data;
+
+               gif_data = (mm_util_gif_data *) _handle->image_h;
+
+               if (gif_data->frames == NULL) {
+                       image_util_error("Error allocating gif frames.");
+                       return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+               }
+               if(_handle->image_count <= _handle->current_buffer_count) {
+                       gif_data->frames = (mm_util_gif_frame_data **) realloc(gif_data->frames, (_handle->image_count + 1) * sizeof(mm_util_gif_frame_data *));
+                       if (gif_data->frames == NULL) {
+                               image_util_error("Error - OUT_OF_MEMORY");
+                               IMAGE_UTIL_SAFE_FREE(_handle);
+                               return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
+                       }
+                       gif_data->frames[_handle->image_count] = (mm_util_gif_frame_data *) calloc(1, sizeof(mm_util_gif_frame_data));
+                       if (gif_data->frames[_handle->image_count] == NULL) {
+                               image_util_error("Error - OUT_OF_MEMORY");
+                               IMAGE_UTIL_SAFE_FREE(_handle);
+                               return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
+                       }
+                       _handle->image_count++;
+               }
+
+               gif_data->frames[_handle->current_buffer_count]->data = _handle->src_buffer[_handle->current_buffer_count];
+               _handle->current_buffer_count++;
+       }
 
        return err;
 }
@@ -1845,9 +1963,9 @@ static int _image_util_encode_internal(decode_encode_s * _handle)
        case IMAGE_UTIL_JPEG:
                {
                        if (_handle->path)
-                               err = mm_util_jpeg_encode_to_file(_handle->path, _handle->src_buffer, _handle->width, _handle->height, _convert_jpeg_colorspace_tbl[_handle->colorspace], _handle->quality);
+                               err = mm_util_jpeg_encode_to_file(_handle->path, _handle->src_buffer[0], _handle->width, _handle->height, _convert_jpeg_colorspace_tbl[_handle->colorspace], _handle->quality);
                        else
-                               err = mm_util_jpeg_encode_to_memory(_handle->dst_buffer, (int *)&(_handle->dst_size), _handle->src_buffer, _handle->width, _handle->height, _convert_jpeg_colorspace_tbl[_handle->colorspace], _handle->quality);
+                               err = mm_util_jpeg_encode_to_memory(_handle->dst_buffer, (int *)&(_handle->dst_size), _handle->src_buffer[0], _handle->width, _handle->height, _convert_jpeg_colorspace_tbl[_handle->colorspace], _handle->quality);
                }
                break;
        case IMAGE_UTIL_PNG:
@@ -1861,9 +1979,9 @@ static int _image_util_encode_internal(decode_encode_s * _handle)
                        }
 
                        if (_handle->path)
-                               err = mm_util_encode_to_png_file(&(_handle->src_buffer), png_data, _handle->path);
+                               err = mm_util_encode_to_png_file(&(_handle->src_buffer[0]), png_data, _handle->path);
                        else
-                               err = mm_util_encode_to_png_memory(&(_handle->src_buffer), png_data);
+                               err = mm_util_encode_to_png_memory(&(_handle->src_buffer[0]), png_data);
 
                        if (err == MM_UTIL_ERROR_NONE) {
                                if (_handle->dst_buffer)
@@ -1880,12 +1998,16 @@ static int _image_util_encode_internal(decode_encode_s * _handle)
                        void *dst_buffer = NULL;
 
                        gif_data = (mm_util_gif_data *) _handle->image_h;
-                       if (gif_data == NULL || gif_data->frames == NULL) {
+                       if (gif_data == NULL) {
                                image_util_error("Invalid gif data");
                                return MM_UTIL_ERROR_INVALID_PARAMETER;
                        }
+                       if ((_handle->image_count > 1) && ((_handle->image_count != _handle->current_buffer_count) || (_handle->image_count != _handle->current_resolution_count) || (_handle->image_count != _handle->current_delay_count))) {
+                               image_util_error("Total frame count does not match with the data set, for animated gif encoding");
+                               return MM_UTIL_ERROR_INVALID_OPERATION;
+                       }
 
-                       gif_data->frames[0].data = _handle->src_buffer;
+                       mm_util_gif_encode_set_image_count(gif_data, _handle->image_count);
                        if (_handle->path)
                                err = mm_util_encode_gif_to_file(gif_data, _handle->path);
                        else
@@ -1910,7 +2032,7 @@ static int _image_util_encode_internal(decode_encode_s * _handle)
                                return MM_UTIL_ERROR_INVALID_PARAMETER;
                        }
 
-                       bmp_data->data = _handle->src_buffer;
+                       bmp_data->data = _handle->src_buffer[0];
                        if (_handle->path)
                                err = mm_util_encode_bmp_to_file(bmp_data, _handle->path);
                        else {
@@ -2100,12 +2222,16 @@ int image_util_encode_destroy(image_util_encode_h handle)
        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;
                        }
+                       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);
                }
@@ -2142,6 +2268,7 @@ int image_util_encode_destroy(image_util_encode_h handle)
                g_cond_clear(&(_handle->thread_cond));
        }
 
+       IMAGE_UTIL_SAFE_FREE(_handle->src_buffer);
        IMAGE_UTIL_SAFE_FREE(_handle);
 
        return err;