image-util: Add decoding/encoding utilites for GIF,PNG 11/52011/1 accepted/tizen/mobile/20151119.033414 accepted/tizen/tv/20151119.033426 accepted/tizen/wearable/20151119.033439 submit/tizen/20151118.234340
authorVineeth TM <vineeth.tm@samsung.com>
Wed, 18 Nov 2015 03:02:39 +0000 (12:02 +0900)
committerVineeth TM <vineeth.tm@samsung.com>
Wed, 18 Nov 2015 07:12:56 +0000 (16:12 +0900)
Change-Id: I9fd2e400bd260d18fcf83aeda481bba978fe9803
Signed-off-by: Vineeth TM <vineeth.tm@samsung.com>
CMakeLists.txt
decode-test/CMakeLists.txt [new file with mode: 0755]
decode-test/image_util_decode_encode_testsuite.c [new file with mode: 0755]
include/image_util.h
include/image_util_private.h
include/image_util_type.h
packaging/capi-media-image-util.spec
src/image_util.c

index 3a85ffb636c1766ff62d66eb8b0762346e10532d..748afa4838fce1de984a66166f9ba6d395da273e 100755 (executable)
@@ -24,7 +24,7 @@ SET(service "media")
 SET(submodule "image-util")
 
 # for package file
-SET(dependents "dlog mmutil-jpeg mmutil-imgp mmutil-imgcv capi-base-common capi-media-tool")
+SET(dependents "dlog mmutil-gif mmutil-png mmutil-jpeg mmutil-imgp mmutil-imgcv capi-base-common capi-media-tool")
 SET(pc_dependents "dlog capi-base-common capi-media-tool")
 
 SET(fw_name "${project_prefix}-${service}-${submodule}")
@@ -92,6 +92,7 @@ CONFIGURE_FILE(
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 
 #ADD_SUBDIRECTORY(test)
+ADD_SUBDIRECTORY(decode-test)
 
 IF(UNIX)
 
diff --git a/decode-test/CMakeLists.txt b/decode-test/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..82f0cad
--- /dev/null
@@ -0,0 +1,21 @@
+SET(fw_test "${fw_name}-decode-test")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_test} REQUIRED glib-2.0)
+
+FOREACH(flag ${${fw_test}_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+    MESSAGE(${flag})
+ENDFOREACH()
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -pie -Wall")
+
+aux_source_directory(. sources)
+FOREACH(src ${sources})
+    GET_FILENAME_COMPONENT(src_name ${src} NAME_WE)
+    MESSAGE("${src_name}")
+    ADD_EXECUTABLE(${fw_test} ${src})
+    TARGET_LINK_LIBRARIES(${fw_test} ${fw_name} ${${fw_test}_LDFLAGS})
+ENDFOREACH()
+
+INSTALL(TARGETS ${fw_test} DESTINATION bin)
diff --git a/decode-test/image_util_decode_encode_testsuite.c b/decode-test/image_util_decode_encode_testsuite.c
new file mode 100755 (executable)
index 0000000..fc7b912
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * image-utility
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Vineeth T M <vineeth.tm@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <image_util.h>
+#include <glib.h>
+
+#define DECODE_RESULT_PATH "/media/decode_test."
+#define BUFFER_SIZE 128
+
+unsigned long image_width = 0, image_height = 0;
+unsigned long long image_size = 0;
+
+GCond g_thread_cond;
+GMutex g_thread_mutex;
+
+void _wait()
+{
+       g_mutex_lock(&g_thread_mutex);
+       fprintf(stderr, "waiting... until finishing \n");
+       g_cond_wait(&g_thread_cond, &g_thread_mutex);
+       fprintf(stderr, "<=== get signal from callback \n");
+       g_mutex_unlock(&g_thread_mutex);
+}
+
+void _signal()
+{
+       g_mutex_lock(&g_thread_mutex);
+       g_cond_signal(&g_thread_cond);
+       fprintf(stderr, "===> send signal to test proc \n");
+       g_mutex_unlock(&g_thread_mutex);
+}
+
+static inline void flush_stdin()
+{
+       int ch;
+       while ((ch = getchar()) != EOF && ch != '\n') ;
+}
+
+static int _read_file(char *file_name, void **data, unsigned long long *data_size)
+{
+       FILE *fp = NULL;
+       long file_size = 0;
+
+       if (!file_name || !data || !data_size) {
+               fprintf(stderr, "\tNULL pointer\n");
+               return FALSE;
+       }
+
+       fprintf(stderr, "\tTry to open %s to read\n", file_name);
+
+       fp = fopen(file_name, "r");
+       if (fp == NULL) {
+               fprintf(stderr, "\tfile open failed %d\n", errno);
+               return FALSE;
+       }
+
+       fseek(fp, 0, SEEK_END);
+       file_size = ftell(fp);
+       if (file_size > -1L) {
+               rewind(fp);
+               *data = (void *)malloc(file_size);
+               if (*data == NULL) {
+                       fprintf(stderr, "\tmalloc failed %d\n", errno);
+                       fclose(fp);
+                       fp = NULL;
+                       return FALSE;
+               } else {
+                       if (fread(*data, 1, file_size, fp)) {
+                               fprintf(stderr, "#Success# fread\n");
+                       } else {
+                               fprintf(stderr, "#Error# fread\n");
+                               fclose(fp);
+                               fp = NULL;
+                               return FALSE;
+                       }
+               }
+               fclose(fp);
+               fp = NULL;
+
+               if (*data) {
+                       *data_size = file_size;
+                       return TRUE;
+               } else {
+                       *data_size = 0;
+                       return FALSE;
+               }
+       } else {
+               fprintf(stderr, "#Error# ftell\n");
+               fclose(fp);
+               fp = NULL;
+               return FALSE;
+       }
+}
+
+static int _write_file(const char *file_name, void *data, unsigned long long data_size)
+{
+       FILE *fp = NULL;
+
+       if (!file_name || !data || data_size <= 0) {
+               fprintf(stderr, "\tinvalid data %s %p size:%lld\n", file_name, data, data_size);
+               return FALSE;
+       }
+
+       fprintf(stderr, "\tTry to open %s to write\n", file_name);
+
+       fp = fopen(file_name, "w");
+       if (fp == NULL) {
+               fprintf(stderr, "\tfile open failed %d\n", errno);
+               return FALSE;
+       }
+
+       fwrite(data, 1, data_size, fp);
+       fclose(fp);
+       fp = NULL;
+
+       fprintf(stderr, "\tfile [%s] write DONE\n", file_name);
+
+       return TRUE;
+}
+
+bool decode_completed_cb(int error, void *user_param, unsigned long width, unsigned long height, unsigned long long size)
+{
+       image_width = width;
+       image_height = height;
+       _signal();
+
+       return TRUE;
+}
+
+bool encode_completed_cb(int error, void *user_param, unsigned long long size)
+{
+       image_size = size;
+       _signal();
+
+       return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+       int ret = 0;
+       image_util_decode_h decoded = NULL;
+       image_util_encode_h encoded = NULL;
+       void *src = NULL;
+       unsigned char *data = NULL;
+       unsigned char *dst = NULL;
+       unsigned long long src_size = 0;
+       int image_type = -1;
+       int encode_image_type = -1;
+
+       if (argc < 4) {
+               fprintf(stderr, "\t[usage]\n");
+               fprintf(stderr, "\t\t1. decode : mm_util_png_testsuite decode image_type filepath encode_image_type\n");
+               return 0;
+       }
+
+       image_type = atoi(argv[2]);
+       if(argv[4])
+               encode_image_type = atoi(argv[4]);
+       else
+               encode_image_type = atoi(argv[2]);
+
+       if (!strcmp("decode", argv[1]) || !strcmp("decode-mem", argv[1]) || !strcmp("decode-async", argv[1])) {
+               ret = image_util_decode_create(image_type, &decoded);
+               if (ret != IMAGE_UTIL_ERROR_NONE)
+                       return 0;
+
+               if (!strcmp("decode", argv[1])) {
+                       ret = image_util_decode_set_input_path(decoded, argv[3]);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+               } else {
+                       if (_read_file(argv[3], &src, &src_size))
+                               image_util_decode_set_input_buffer(decoded, (unsigned char *)src, src_size);
+                       else
+                               return 0;
+               }
+               ret = image_util_decode_set_output_buffer(decoded, &data);
+               if (ret != IMAGE_UTIL_ERROR_NONE)
+                       return 0;
+
+               if(!strcmp("decode-async", argv[1]))
+               {
+                       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);
+               if (ret != IMAGE_UTIL_ERROR_NONE)
+                       return 0;
+
+
+
+               ret = image_util_decode_destroy(decoded);
+               if (ret != IMAGE_UTIL_ERROR_NONE)
+                       return 0;
+               free(src);
+       } else {
+               fprintf(stderr, "\tunknown command [%s]\n", argv[1]);
+               return 0;
+       }
+
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               fprintf(stderr, "\tERROR is occurred %x\n", ret);
+       } else {
+               fprintf(stderr, "\tIMAGE OPERATION SUCCESS\n");
+               if (data) {
+                       fprintf(stderr, "\t##Decoded data##: %p\t width: %lu\t height:%lu\n", data, (long unsigned int)image_width, (long unsigned int)image_height);
+                       char filename[BUFFER_SIZE] = { 0, }, type[4] = {
+                       0,};
+                       memset(filename, 0, BUFFER_SIZE);
+
+                       switch (encode_image_type) {
+                       case IMAGE_UTIL_PNG:
+                               snprintf(type, 4, "%s", "png");
+                               break;
+                       case IMAGE_UTIL_GIF:
+                               snprintf(type, 4, "%s", "gif");
+                               break;
+                       default:
+                               break;
+                       }
+                       snprintf(filename, BUFFER_SIZE, "%s%s", DECODE_RESULT_PATH, type);
+
+                       ret = image_util_encode_create(encode_image_type, &encoded);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+
+                       ret = image_util_encode_set_resolution(encoded, image_width, image_height);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+
+                       ret = image_util_encode_set_input_buffer(encoded, data);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+
+                       if (!strcmp("decode-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, filename);
+                               if (ret != IMAGE_UTIL_ERROR_NONE)
+                                       return 0;
+                       }
+
+                       if(!strcmp("decode-async", argv[1]))
+                       {
+                               ret = image_util_encode_run_async(encoded, (image_util_encode_completed_cb) encode_completed_cb, NULL);
+                               _wait();
+                       }
+                       else
+                               ret = image_util_encode_run(encoded, &image_size);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+
+                       if (!strcmp("decode-mem", argv[1])) {
+                               _write_file(filename, (void *)dst, image_size);
+                               free(dst);
+                       }
+
+                       ret = image_util_encode_destroy(encoded);
+                       if (ret != IMAGE_UTIL_ERROR_NONE)
+                               return 0;
+
+                       free(data);
+               } else {
+                       fprintf(stderr, "\tDECODED data is NULL\n");
+               }
+       }
+       return 0;
+}
index 21921ee987e8f47cdf712109cb90363fae9e9be8..bdfaa51b12819ff0d6602ba8ba80f893deea68e8 100755 (executable)
@@ -751,6 +751,485 @@ int image_util_encode_jpeg_to_memory(const unsigned char *image_buffer, int widt
 */
 int image_util_extract_color_from_memory(const unsigned char *image_buffer, int width, int height, unsigned char *rgb_r, unsigned char *rgb_g, unsigned char *rgb_b);
 
+/**
+* @brief Creates a handle to image util decoding.
+* @since_tizen 3.0
+*
+* @details This function creates a handle to image util decoding.
+*
+* @remarks You must release the @a image util handle using image_util_decode_destroy().
+*
+* @param[in] image_type The type of image for which to create decode handle.
+* @param[out] handle A handle to image util decoding
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory
+*
+* @see image_util_decode_destroy()
+*
+*/
+int image_util_decode_create(image_util_type_e image_type, image_util_decode_h *handle);
+
+/**
+* @brief Sets the input file path from which to decode.
+* @since_tizen 3.0
+*
+* @remarks One of image_util_decode_set_input_path() or image_util_decode_set_input_buffer() should be set.\n
+*          If both are set then the latest input set, is considered.\n
+*          http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage.\n
+*          http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage.
+*
+* @param[in] handle The handle to image util decoding
+* @param[in] path The path to input image
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_NO_SUCH_FILE No such file
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+* @retval #IMAGE_UTIL_ERROR_PERMISSION_DENIED The application does not have the privilege to call this funtion
+*
+* @pre image_util_decode_create()
+*
+* @post image_util_decode_run()/image_util_decode_run_async()
+* @post image_util_decode_destroy()
+*
+* @see image_util_decode_create()
+* @see image_util_decode_set_output_buffer()
+* @see image_util_decode_run()
+* @see image_util_decode_run_async()
+* @see image_util_decode_destroy()
+*/
+int image_util_decode_set_input_path(image_util_decode_h handle, const char *path);
+
+/**
+* @brief Sets the input buffer from which to decode.
+* @since_tizen 3.0
+*
+* @remarks One of image_util_decode_set_input_path() or image_util_decode_set_input_buffer() should be set.\n
+*          If both are set then the latest input set, is considered.
+*
+* @param[in] handle The handle to image util decoding
+* @param[in] src_buffer The input image buffer
+* @param[in] src_size The input image buffer size
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+*
+* @pre image_util_decode_create()
+*
+* @post image_util_decode_run()/image_util_decode_run_async()
+* @post image_util_decode_destroy()
+*
+* @see image_util_decode_create()
+* @see image_util_decode_set_output_buffer()
+* @see image_util_decode_run()
+* @see image_util_decode_run_async()
+* @see image_util_decode_destroy()
+*/
+int image_util_decode_set_input_buffer(image_util_decode_h handle, const unsigned char *src_buffer, unsigned long long src_size);
+
+/**
+* @brief Sets the output buffer to which the decoded buffer will be written to.
+* @since_tizen 3.0
+*
+* @remarks Either image_util_decode_set_input_path() or image_util_decode_set_input_buffer() should be set.\n
+*          The decoded output buffer will be RGBA format.
+*
+* @param[in] handle The handle to image util decoding
+* @param[in] dst_buffer The decoded output buffer
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+*
+* @pre image_util_decode_create()
+*
+* @post image_util_decode_run()/image_util_decode_run_async()
+* @post image_util_decode_destroy()
+*
+* @see image_util_decode_create()
+* @see image_util_decode_set_input_path()
+* @see image_util_decode_set_input_buffer()
+* @see image_util_decode_run()
+* @see image_util_decode_run_async()
+* @see image_util_decode_destroy()
+*/
+int image_util_decode_set_output_buffer(image_util_decode_h handle, unsigned char **dst_buffer);
+
+/**
+* @brief Starts decoding of the image and fills the output buffer set using image_util_decode_set_output_buffer().
+* @since_tizen 3.0
+*
+* @remarks The output will be stored in the pointer set using image_util_decode_set_output_buffer().
+*              The function executes synchronously.
+*
+* @param[in] handle The handle to image util decoding
+* @param[out] width Width of the decoded image
+* @param[out] height Height of the decoded image
+* @param[out] size Size of the decoded image
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @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_output_buffer()
+*
+* @post image_util_decode_destroy()
+*
+* @see image_util_decode_create()
+* @see image_util_decode_set_input_path()
+* @see image_util_decode_set_input_buffer()
+* @see image_util_decode_set_output_buffer()
+* @see image_util_decode_destroy()
+*/
+int image_util_decode_run(image_util_decode_h handle, unsigned long *width, unsigned long *height, unsigned long long *size);
+
+/**
+* @brief Starts decoding of the image and fills the output buffer set using image_util_decode_set_output_buffer().
+* @since_tizen 3.0
+*
+* @remarks The output will be stored in the pointer set using image_util_decode_set_output_buffer().\n
+*              The function executes asynchronously, which contains complete callback.
+*
+* @param[in] handle The handle to image util decoding
+* @param[in] callback The callback function to be invoked
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @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_output_buffer()
+*
+* @post image_util_decode_destroy()
+*
+* @see image_util_decode_create()
+* @see image_util_decode_set_input_path()
+* @see image_util_decode_set_input_buffer()
+* @see image_util_decode_set_output_buffer()
+* @see image_util_decode_destroy()
+*/
+int image_util_decode_run_async(image_util_decode_h handle, image_util_decode_completed_cb callback, void *user_data);
+
+/**
+* @brief Destroys the image decoding handle.
+* @since_tizen 3.0
+*
+* @remarks Any image handle created should be destroyed.
+*
+* @param[in] handle The handle to image util decoding
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+*
+* @pre image_util_decode_create()
+*
+* @see image_util_decode_create()
+*/
+int image_util_decode_destroy(image_util_decode_h handle);
+
+/**
+* @brief Creates a handle to image util encoding.
+* @since_tizen 3.0
+*
+* @details This function creates a handle to image util encoding.
+*
+* @remarks You must release the @a image util handle using image_util_encode_destroy().
+*
+* @param[in] image_type The type of image for which to create encode handle.
+* @param[out] handle A handle to image util encoding
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory
+*
+* @see image_util_encode_destroy()
+*
+*/
+int image_util_encode_create(image_util_type_e image_type, image_util_encode_h *handle);
+
+/**
+* @brief Sets the resolution of the encoded image.
+* @since_tizen 3.0
+*
+* @remarks This should be called before calling image_util_encode_run().
+*
+* @param[in] handle The handle to image util encoding
+* @param[in] width Width of the original image
+* @param[in] height Height of the original image
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+*
+* @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_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_resolution(image_util_encode_h handle, unsigned long width, unsigned long height);
+
+/**
+* @brief Sets the compression value of png image encoding(0~9).
+* @since_tizen 3.0
+*
+* @remarks If application does not set this, then default compression of 6 is set.
+*
+* @param[in] handle The handle to image util encoding
+* @param[in] compression The compression value valid from 0~9
+*
+* @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
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+*
+* @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_png_compression(image_util_encode_h handle, image_util_png_compression_e compression);
+
+/**
+* @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.
+*          The input buffer should be RGBA format.
+*
+* @param[in] handle The handle to image util decoding
+* @param[in] src_buffer The input image buffer
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+*
+* @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_input_buffer(image_util_encode_h handle, const unsigned char *src_buffer);
+
+/**
+* @brief Sets the output path to which to encoded buffer will be written to.
+* @since_tizen 3.0
+*
+* @remarks One of image_util_encode_set_output_path() or image_util_encode_set_output_buffer() should be set.\n
+*          If both are set then the latest output set is considered.\n
+*          http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage.\n
+*          http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage.
+*
+* @param[in] handle The handle to image util encoding
+* @param[in] path The output file path
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_NO_SUCH_FILE No such file
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+* @retval #IMAGE_UTIL_ERROR_PERMISSION_DENIED The application does not have the privilege to call this funtion
+*
+* @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_run()
+* @see image_util_encode_run_async()
+* @see image_util_encode_destroy()
+*/
+int image_util_encode_set_output_path(image_util_encode_h handle, const char *path);
+
+/**
+* @brief Sets the output buffer to which to encoded buffer will be written to.
+* @since_tizen 3.0
+*
+* @remarks One of image_util_encode_set_output_path() or image_util_encode_set_output_buffer() should be set.\n
+*          If both are set then the latest output set is considered.
+*
+* @param[in] handle The handle to image util encoding
+* @param[in] dst_buffer The output image buffer
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+*
+* @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_run()
+* @see image_util_encode_run_async()
+* @see image_util_encode_destroy()
+*/
+int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned char **dst_buffer);
+
+/**
+* @brief Starts encoding of the image and fills the output buffer, set using image_util_encode_set_output_buffer() or image_util_encode_set_output_path().
+* @since_tizen 3.0
+*
+* @remarks The output will be stored in the pointer set to image_util_encode_set_output_buffer() or image_util_encode_set_output_path().
+*              The function executes synchronously.
+*
+* @param[in] handle The handle to image util encoding
+* @param[out] size Size of the encoded image
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+*
+* @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()
+*
+* @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_destroy()
+*/
+int image_util_encode_run(image_util_encode_h handle, unsigned long long *size);
+
+/**
+* @brief Starts encoding of the image and fills the output buffer, set using image_util_encode_set_output_buffer() or image_util_encode_set_output_path().
+* @since_tizen 3.0
+*
+* @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.
+*
+* @param[in] handle The handle to image util encoding
+* @param[in] callback The callback function to be invoked
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+*
+* @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()
+*
+* @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_destroy()
+*/
+int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_completed_cb callback, void *user_data);
+
+/**
+* @brief Destroys the image encoding handle.
+* @since_tizen 3.0
+*
+* @remarks Any image handle created should be destroyed.
+*
+* @param[in] handle The handle to image util encoding
+*
+* @return @c 0 on success,
+*               otherwise a negative error value
+*
+* @retval #IMAGE_UTIL_ERROR_NONE Successful
+* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+*
+* @pre image_util_encode_create()
+*
+* @see image_util_encode_create()
+*/
+int image_util_encode_destroy(image_util_encode_h handle);
 
 /**
  * @}
index 07228265a77d4e3b77bf0ea6cf7001c6a905e1bd..15be49099c561310000aac6ea3ef202830a7d4d3 100755 (executable)
@@ -20,6 +20,7 @@
 #include <image_util_type.h>
 #include <dlog.h>
 #include <stdlib.h>
+#include <glib.h>
 
 #ifdef __cplusplus
 extern "C"
@@ -84,6 +85,37 @@ typedef struct {
        bool set_crop;
 } transformation_s;
 
+typedef struct {
+       void *user_data;
+       image_util_decode_completed_cb image_decode_completed_cb;
+} decode_cb_s;
+
+typedef struct {
+       void *user_data;
+       image_util_encode_completed_cb image_encode_completed_cb;
+} encode_cb_s;
+
+typedef struct {
+       image_util_type_e image_type;
+       void *src_buffer;
+       unsigned long long src_size;
+       void **dst_buffer;
+       unsigned long long dst_size;
+       const char *path;
+       MMHandleType image_h;
+       unsigned long width;
+       unsigned long height;
+       bool is_decode;
+       decode_cb_s *_decode_cb;
+       encode_cb_s *_encode_cb;
+
+       /* for multi instance */
+       GCond thread_cond;
+       GMutex thread_mutex;
+       GThread *thread;
+
+       bool is_finish;
+} decode_encode_s;
 
 /**
 * @}
index 1d81fbaf6b4ba71743d7e3fb90825dba12df3411..5d851cee16be9f43ed3d5e5c49a29e556f26f674 100755 (executable)
@@ -124,6 +124,84 @@ typedef struct transformation_s *transformation_h;
 */
 typedef void(*image_util_transform_completed_cb)(media_packet_h *dst, int error_code, void *user_data);
 
+/**
+ * @brief Enumeration for Image types.
+ * @since_tizen 3.0
+ */
+typedef enum {
+       IMAGE_UTIL_PNG,          /**< Image format PNG */
+       IMAGE_UTIL_GIF,          /**< Image format GIF */
+} image_util_type_e;
+
+/**
+ * @brief Enumeration for PNG compression values.
+ * @since_tizen 3.0
+ */
+typedef enum {
+       IMAGE_UTIL_PNG_COMPRESSION_0 = 0, /**< No compression */
+       IMAGE_UTIL_PNG_COMPRESSION_1 = 1, /**< Compression Level 1. Best speed */
+       IMAGE_UTIL_PNG_COMPRESSION_2 = 2, /**< Compression Level 2 */
+       IMAGE_UTIL_PNG_COMPRESSION_3 = 3, /**< Compression Level 3 */
+       IMAGE_UTIL_PNG_COMPRESSION_4 = 4, /**< Compression Level 4 */
+       IMAGE_UTIL_PNG_COMPRESSION_5 = 5, /**< Compression Level 5 */
+       IMAGE_UTIL_PNG_COMPRESSION_6 = 6, /**< Compression Level 6 */
+       IMAGE_UTIL_PNG_COMPRESSION_7 = 7, /**< Compression Level 7 */
+       IMAGE_UTIL_PNG_COMPRESSION_8 = 8, /**< Compression Level 8 */
+       IMAGE_UTIL_PNG_COMPRESSION_9 = 9  /**< Compression Level 9. Best compression */
+} image_util_png_compression_e;
+
+/**
+* @ingroup CAPI_MEDIA_IMAGE_UTIL_MODULE
+* @brief Called when Image-util decoding is finished just before returning the output.
+* @since_tizen 3.0
+*
+* @remarks The output will be stored in the pointer set using image_util_decode_set_output_buffer() after this callback.
+*
+* @param[in] error_code The error code of image util decoding
+*                      #IMAGE_UTIL_ERROR_NONE Successful
+*                      #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+*                      #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+* @param[in] user_data The user data passed from the callback registration function
+* @param[in] width Width of the decoded image
+* @param[in] height Height of the decoded image
+* @param[in] size Size of the decoded image
+*
+* @pre image_util_decode_run() will invoke this function.
+*/
+typedef void (*image_util_decode_completed_cb) (int error_code, void *user_data, unsigned long width, unsigned long height, unsigned long long size);
+
+/**
+* @ingroup CAPI_MEDIA_IMAGE_UTIL_MODULE
+* @brief Called when Image-util encoding is finished just before returning the output.
+* @since_tizen 3.0
+*
+* @remarks The output will be stored in the pointer set using image_util_encode_set_output_buffer() or image_util_encode_set_output_path() after this callback.
+*
+* @param[in] error_code The error code of image util encoding
+*                      #IMAGE_UTIL_ERROR_NONE Successful
+*                      #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+*                      #IMAGE_UTIL_ERROR_INVALID_OPERATION Invalid operation
+* @param[in] user_data The user data passed from the callback registration function
+* @param[in] size Size of the encoded image
+*
+* @pre image_util_encode_run() will invoke this function.
+*/
+typedef void (*image_util_encode_completed_cb) (int error_code, void *user_data, unsigned long long size);
+
+/**
+* @ingroup CAPI_MEDIA_IMAGE_UTIL_MODULE
+* @brief Image-util decoding handle.
+* @since_tizen 3.0
+*/
+typedef void *image_util_decode_h;
+
+/**
+* @ingroup CAPI_MEDIA_IMAGE_UTIL_MODULE
+* @brief Image-util encoding handle.
+* @since_tizen 3.0
+*/
+typedef void *image_util_encode_h;
+
 /**
  * @}
  */
index 78a98c9de975cc0ed84281d48cec0ebc502ab007..10c6d3f07084c16d071018aa29e68a10f61c6fbd 100755 (executable)
@@ -10,9 +10,13 @@ BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(mmutil-jpeg)
 BuildRequires:  pkgconfig(mmutil-imgp)
 BuildRequires:  pkgconfig(mmutil-imgcv)
+BuildRequires:  pkgconfig(mmutil-png)
+BuildRequires:  pkgconfig(mmutil-gif)
 BuildRequires:  pkgconfig(capi-base-common)
 BuildRequires:  pkgconfig(capi-media-tool)
 BuildRequires:  cmake
+BuildRequires:  libpng-devel
+BuildRequires:  giflib-devel
 
 %description
 A Image Utility library in Tizen Native API package
@@ -26,11 +30,21 @@ Requires:  pkgconfig(mm-common)
 Requires:  pkgconfig(mmutil-jpeg)
 Requires:  pkgconfig(mmutil-imgp)
 Requires:  pkgconfig(mmutil-imgcv)
+Requires:  pkgconfig(mmutil-png)
+Requires:  pkgconfig(mmutil-gif)
 Requires:  pkgconfig(capi-base-common)
 
 %description devel
 A Image Utility library in Tizen Native API (Development) package
 
+%package tool
+Summary:    Image Utility tools
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+
+%description tool
+Image Utility Library - Tools.
+
 %prep
 %setup -q
 cp %{SOURCE1001} .
@@ -69,3 +83,8 @@ cp LICENSE.APLv2.0 %{buildroot}/usr/share/license/%{name}
 %{_libdir}/lib*.so
 %{_libdir}/pkgconfig/*.pc
 %{_includedir}/media/*.h
+
+%files tool
+%manifest %{name}.manifest
+%defattr(-,root,root,-) 
+%{_bindir}/*
index 74ddf4d290ce9fa1f48468283156f1734c0f7584..5864b401f78e82ae44f55bae574fd3554196c001 100755 (executable)
@@ -19,6 +19,8 @@
 #include <mm_util_imgp.h>
 #include <mm_util_jpeg.h>
 #include <mm_util_imgcv.h>
+#include <mm_util_png.h>
+#include <mm_util_gif.h>
 #include <image_util.h>
 #include <image_util_private.h>
 #include <stdio.h>
@@ -751,3 +753,841 @@ int image_util_extract_color_from_memory(const unsigned char *image_buffer, int
 
        return _convert_image_util_error_code(__func__, ret);
 }
+
+static int _image_util_decode_create_png_handle(decode_encode_s * handle)
+{
+       int err = MM_UTIL_ERROR_NONE;
+
+       image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid 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);
+
+       mm_util_init_decode_png(_handle);
+
+       handle->image_h = (MMHandleType) _handle;
+
+       return err;
+}
+
+static int _image_util_decode_create_gif_handle(decode_encode_s * handle)
+{
+       int err = MM_UTIL_ERROR_NONE;
+
+       image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid 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->image_h = (MMHandleType) _handle;
+
+       return err;
+}
+
+int image_util_decode_create(image_util_type_e image_type, image_util_decode_h * handle)
+{
+       int err = MM_UTIL_ERROR_NONE;
+
+       image_util_debug("image_util_decode_create");
+
+       image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
+
+       decode_encode_s *_handle = (decode_encode_s *) calloc(1, sizeof(decode_encode_s));
+       image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
+
+       _handle->image_type = image_type;
+       _handle->src_buffer = NULL;
+       _handle->dst_buffer = NULL;
+       _handle->path = NULL;
+       _handle->image_h = 0;
+       _handle->is_decode = TRUE;
+
+       switch (image_type) {
+       case IMAGE_UTIL_PNG:
+               err = _image_util_decode_create_png_handle(_handle);
+               break;
+       case IMAGE_UTIL_GIF:
+               err = _image_util_decode_create_gif_handle(_handle);
+               break;
+       default:
+               err = MM_UTIL_ERROR_INVALID_PARAMETER;
+               break;
+       }
+
+       if (err != MM_UTIL_ERROR_NONE) {
+               image_util_error("Error - create image handle");
+               IMAGE_UTIL_SAFE_FREE(_handle);
+               return _convert_image_util_error_code(__func__, err);
+       }
+
+       *handle = (image_util_decode_h) _handle;
+
+       return _convert_image_util_error_code(__func__, err);
+}
+
+int image_util_decode_set_input_path(image_util_decode_h handle, const char *path)
+{
+       int err = IMAGE_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == FALSE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       image_util_retvm_if((path == NULL || strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
+
+       if (_handle->src_buffer)
+               _handle->src_buffer = NULL;
+
+       _handle->path = path;
+
+       return err;
+}
+
+int image_util_decode_set_input_buffer(image_util_decode_h handle, const unsigned char *src_buffer, unsigned long long src_size)
+{
+       int err = IMAGE_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == FALSE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       if (src_buffer == NULL || src_size == 0) {
+               image_util_error("Invalid input buffer");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (_handle->path)
+               _handle->path = NULL;
+
+       _handle->src_buffer = (void *)src_buffer;
+       _handle->src_size = src_size;
+
+       return err;
+}
+
+int image_util_decode_set_output_buffer(image_util_decode_h handle, unsigned char **dst_buffer)
+{
+       int err = IMAGE_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == FALSE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       if (dst_buffer == NULL) {
+               image_util_error("Invalid output buffer");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+
+       _handle->dst_buffer = (void **)dst_buffer;
+
+       return err;
+}
+
+static int _image_util_decode_internal(decode_encode_s * _handle)
+{
+       int err = MM_UTIL_ERROR_NONE;
+
+       switch (_handle->image_type) {
+       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 MM_UTIL_ERROR_INVALID_PARAMETER;
+                       }
+
+                       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);
+
+                       if (err == MM_UTIL_ERROR_NONE) {
+                               *(_handle->dst_buffer) = png_data->data;
+                               _handle->dst_size = png_data->size;
+                               _handle->width = png_data->width;
+                               _handle->height = png_data->height;
+                       }
+               }
+               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 MM_UTIL_ERROR_INVALID_PARAMETER;
+                       }
+
+                       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);
+
+                       if (err == MM_UTIL_ERROR_NONE) {
+                               *(_handle->dst_buffer) = gif_data->frames[0].data;
+                               _handle->dst_size = gif_data->size;
+                               _handle->width = gif_data->width;
+                               _handle->height = gif_data->height;
+                       }
+               }
+               break;
+       default:
+               err = MM_UTIL_ERROR_INVALID_PARAMETER;
+               break;
+       }
+
+       return err;
+}
+
+int image_util_decode_run(image_util_decode_h handle, unsigned long *width, unsigned long *height, unsigned long long *size)
+{
+       int err = MM_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == FALSE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       if ((_handle->path == NULL && _handle->src_buffer == NULL) || _handle->dst_buffer == NULL) {
+               image_util_error("Invalid input/output");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+
+       err = _image_util_decode_internal(_handle);
+
+       if (err != MM_UTIL_ERROR_NONE) {
+               image_util_error("Error - decode run");
+               return _convert_image_util_error_code(__func__, err);
+       }
+
+       if (width)
+               *width = _handle->width;
+       if (height)
+               *height = _handle->height;
+       if (size)
+               *size = _handle->dst_size;
+
+       return _convert_image_util_error_code(__func__, err);
+}
+
+gpointer _image_util_decode_thread(gpointer data)
+{
+       decode_encode_s *_handle = (decode_encode_s *) data;
+       int err = MM_UTIL_ERROR_NONE;
+       gint64 end_time = 0;
+
+       if (!_handle) {
+               image_util_error("[ERROR] - handle");
+               return NULL;
+       }
+
+       while (!_handle->is_finish) {
+               end_time = g_get_monotonic_time() + 1 * G_TIME_SPAN_SECOND;
+               image_util_debug("waiting...");
+               g_mutex_lock(&(_handle->thread_mutex));
+               g_cond_wait_until(&(_handle->thread_cond), &(_handle->thread_mutex), end_time);
+               image_util_debug("<=== get run decode thread signal");
+               g_mutex_unlock(&(_handle->thread_mutex));
+
+               if (_handle->is_finish) {
+                       image_util_debug("exit loop");
+                       break;
+               }
+
+               err = _image_util_decode_internal(_handle);
+               if(err == MM_UTIL_ERROR_NONE) {
+                       image_util_debug("Success - decode_internal");
+               } else{
+                       image_util_error("Error - decode_internal");
+               }
+               if (_handle->_decode_cb) {
+                       image_util_debug("completed_cb");
+                       _handle->is_finish = TRUE;
+                       _handle->_decode_cb->image_decode_completed_cb(_convert_image_util_error_code(__func__, err), _handle->_decode_cb->user_data, _handle->width, _handle->height, _handle->dst_size);
+               }
+       }
+
+       image_util_debug("exit thread");
+
+       return NULL;
+}
+
+static int _image_util_decode_create_thread(decode_encode_s * handle)
+{
+       int err = MM_UTIL_ERROR_NONE;
+
+       image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
+
+       g_mutex_init(&(handle->thread_mutex));
+
+       g_cond_init(&(handle->thread_cond));
+
+       /*create threads */
+       handle->thread = g_thread_new("decode_thread", (GThreadFunc) _image_util_decode_thread, (gpointer) handle);
+       if (!handle->thread) {
+               image_util_error("ERROR - create thread");
+               g_mutex_clear(&(handle->thread_mutex));
+
+               g_cond_clear(&(handle->thread_cond));
+               return MM_UTIL_ERROR_INVALID_OPERATION;
+       }
+
+       return err;
+}
+
+int image_util_decode_run_async(image_util_decode_h handle, image_util_decode_completed_cb completed_cb, void *user_data)
+{
+       int err = MM_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == FALSE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       if ((_handle->path == NULL && _handle->src_buffer == NULL) || _handle->dst_buffer == NULL) {
+               image_util_error("Invalid input/output");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
+
+       if (_handle->_decode_cb != NULL) {
+               IMAGE_UTIL_SAFE_FREE(_handle->_decode_cb);
+               _handle->_decode_cb = NULL;
+       }
+       _handle->_decode_cb = (decode_cb_s *) calloc(1, sizeof(decode_cb_s));
+       image_util_retvm_if((_handle->_decode_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
+
+       _handle->_decode_cb->user_data = user_data;
+       _handle->_decode_cb->image_decode_completed_cb = completed_cb;
+
+       err = _image_util_decode_create_thread(_handle);
+
+       return _convert_image_util_error_code(__func__, err);
+}
+
+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");
+
+       if (_handle == NULL || _handle->is_decode == FALSE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+
+       switch (_handle->image_type) {
+       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;
+       default:
+               err = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+               break;
+       }
+
+       /* g_thread_exit(handle->thread); */
+       if (_handle->thread) {
+               _handle->is_finish = TRUE;
+               g_mutex_lock(&(_handle->thread_mutex));
+               g_cond_signal(&(_handle->thread_cond));
+               image_util_debug("===> send signal(finish) to decode_thread");
+               g_mutex_unlock(&(_handle->thread_mutex));
+
+               g_thread_join(_handle->thread);
+
+               g_mutex_clear(&(_handle->thread_mutex));
+
+               g_cond_clear(&(_handle->thread_cond));
+       }
+
+       IMAGE_UTIL_SAFE_FREE(_handle);
+
+       return err;
+}
+
+static int _image_util_encode_create_png_handle(decode_encode_s * handle)
+{
+       int err = MM_UTIL_ERROR_NONE;
+
+       image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid 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);
+
+       mm_util_init_encode_png(_handle);
+
+       handle->image_h = (MMHandleType) _handle;
+
+       return err;
+}
+
+static int _image_util_encode_create_gif_handle(decode_encode_s * handle)
+{
+       int err = MM_UTIL_ERROR_NONE;
+
+       image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid 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));
+       image_util_retvm_if((_handle->frames == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
+
+       mm_util_gif_encode_set_image_count(_handle, 1);
+       handle->image_h = (MMHandleType) _handle;
+
+       return err;
+}
+
+int image_util_encode_create(image_util_type_e image_type, image_util_encode_h * handle)
+{
+       int err = MM_UTIL_ERROR_NONE;
+
+       image_util_debug("image_util_encode_create");
+
+       image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
+
+       decode_encode_s *_handle = (decode_encode_s *) calloc(1, sizeof(decode_encode_s));
+       image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
+
+       _handle->image_type = image_type;
+       _handle->src_buffer = NULL;
+       _handle->dst_buffer = NULL;
+       _handle->path = NULL;
+       _handle->image_h = 0;
+       _handle->is_decode = FALSE;
+
+       switch (image_type) {
+       case IMAGE_UTIL_PNG:
+               err = _image_util_encode_create_png_handle(_handle);
+               break;
+       case IMAGE_UTIL_GIF:
+               err = _image_util_encode_create_gif_handle(_handle);
+               break;
+       default:
+               err = MM_UTIL_ERROR_INVALID_PARAMETER;
+               break;
+       }
+
+       if (err != MM_UTIL_ERROR_NONE) {
+               image_util_error("Error - create image handle");
+               IMAGE_UTIL_SAFE_FREE(_handle);
+               return _convert_image_util_error_code(__func__, err);
+       }
+
+       *handle = (image_util_encode_h) _handle;
+
+       return _convert_image_util_error_code(__func__, err);
+}
+
+int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long width, unsigned long height)
+{
+       int err = IMAGE_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == TRUE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       image_util_retvm_if((_image_util_check_resolution(width, height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
+
+       switch (_handle->image_type) {
+       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;
+                       }
+                       mm_util_png_encode_set_width(png_data, width);
+                       mm_util_png_encode_set_height(png_data, height);
+               }
+               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;
+                       }
+                       mm_util_gif_encode_set_width(gif_data, width);
+                       mm_util_gif_encode_set_height(gif_data, height);
+               }
+               break;
+       default:
+               err = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+               break;
+       }
+
+       _handle->width = width;
+       _handle->height = height;
+
+       return err;
+}
+
+int image_util_encode_set_png_compression(image_util_encode_h handle, image_util_png_compression_e compression)
+{
+       int err = IMAGE_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+       mm_util_png_data *png_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_PNG) {
+               image_util_error("Wrong image format");
+               return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
+       }
+       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;
+       }
+
+       mm_util_png_encode_set_compression_level(png_data, compression);
+
+       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;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == TRUE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       if (src_buffer == NULL) {
+               image_util_error("Invalid input buffer");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+
+       _handle->src_buffer = (void *)src_buffer;
+
+       return err;
+}
+
+int image_util_encode_set_output_path(image_util_encode_h handle, const char *path)
+{
+       int err = IMAGE_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == TRUE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       image_util_retvm_if((path == NULL || strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
+
+       if (_handle->dst_buffer)
+               _handle->dst_buffer = NULL;
+
+       _handle->path = path;
+
+       return err;
+}
+
+int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned char **dst_buffer)
+{
+       int err = IMAGE_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == TRUE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       if (dst_buffer == NULL) {
+               image_util_error("Invalid output buffer");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (_handle->path)
+               _handle->path = NULL;
+
+       _handle->dst_buffer = (void **)dst_buffer;
+
+       return err;
+}
+
+static int _image_util_encode_internal(decode_encode_s * _handle)
+{
+       int err = MM_UTIL_ERROR_NONE;
+
+       switch (_handle->image_type) {
+       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 MM_UTIL_ERROR_INVALID_PARAMETER;
+                       }
+
+                       if (_handle->path)
+                               err = mm_util_encode_to_png_file(&(_handle->src_buffer), png_data, _handle->path);
+                       else
+                               err = mm_util_encode_to_png_memory(&(_handle->src_buffer), png_data);
+
+                       if (err == MM_UTIL_ERROR_NONE) {
+                               if (_handle->dst_buffer)
+                                       *(_handle->dst_buffer) = png_data->data;
+                               _handle->dst_size = png_data->size;
+                               _handle->width = png_data->width;
+                               _handle->height = png_data->height;
+                       }
+               }
+               break;
+       case IMAGE_UTIL_GIF:
+               {
+                       mm_util_gif_data *gif_data;
+                       void *dst_buffer = NULL;
+
+                       gif_data = (mm_util_gif_data *) _handle->image_h;
+                       if (gif_data == NULL) {
+                               image_util_error("Invalid png data");
+                               return MM_UTIL_ERROR_INVALID_PARAMETER;
+                       }
+
+                       gif_data->frames[0].data = _handle->src_buffer;
+                       if (_handle->path)
+                               err = mm_util_encode_gif_to_file(gif_data, _handle->path);
+                       else
+                               err = mm_util_encode_gif_to_memory(gif_data, &dst_buffer);
+
+                       if (err == MM_UTIL_ERROR_NONE) {
+                               if (_handle->dst_buffer)
+                                       *(_handle->dst_buffer) = (unsigned char *)dst_buffer;
+                               _handle->dst_size = gif_data->size;
+                               _handle->width = gif_data->width;
+                               _handle->height = gif_data->height;
+                       }
+               }
+               break;
+       default:
+               err = MM_UTIL_ERROR_INVALID_PARAMETER;
+               break;
+       }
+
+       return err;
+}
+
+int image_util_encode_run(image_util_encode_h handle, unsigned long long *size)
+{
+       int err = MM_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == TRUE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       if ((_handle->path == NULL && _handle->dst_buffer == NULL) || _handle->src_buffer == NULL) {
+               image_util_error("Invalid input/output");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       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);
+
+       if (err != MM_UTIL_ERROR_NONE) {
+               image_util_error("Error - encode run");
+               return _convert_image_util_error_code(__func__, err);
+       }
+
+       if(size)
+               *size = _handle->dst_size;
+
+       return _convert_image_util_error_code(__func__, err);
+}
+
+gpointer _image_util_encode_thread(gpointer data)
+{
+       decode_encode_s *_handle = (decode_encode_s *) data;
+       int err = MM_UTIL_ERROR_NONE;
+       gint64 end_time = 0;
+
+       if (!_handle) {
+               image_util_error("[ERROR] - handle");
+               return NULL;
+       }
+
+       while (!_handle->is_finish) {
+               end_time = g_get_monotonic_time() + 1 * G_TIME_SPAN_SECOND;
+               image_util_debug("waiting...");
+               g_mutex_lock(&(_handle->thread_mutex));
+               g_cond_wait_until(&(_handle->thread_cond), &(_handle->thread_mutex), end_time);
+               image_util_debug("<=== get run encode thread signal");
+               g_mutex_unlock(&(_handle->thread_mutex));
+
+               if (_handle->is_finish) {
+                       image_util_debug("exit loop");
+                       break;
+               }
+
+               err = _image_util_encode_internal(_handle);
+               if(err == MM_UTIL_ERROR_NONE) {
+                       image_util_debug("Success - encode_internal");
+               } else{
+                       image_util_error("Error - encode_internal");
+               }
+               if (_handle->_encode_cb) {
+                       image_util_debug("completed_cb");
+                       _handle->is_finish = TRUE;
+                       _handle->_encode_cb->image_encode_completed_cb(_convert_image_util_error_code(__func__, err), _handle->_encode_cb->user_data, _handle->dst_size);
+               }
+       }
+
+       image_util_debug("exit thread");
+
+       return NULL;
+}
+
+static int _image_util_encode_create_thread(decode_encode_s * handle)
+{
+       int ret = MM_UTIL_ERROR_NONE;
+
+       image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
+
+       g_mutex_init(&(handle->thread_mutex));
+
+       g_cond_init(&(handle->thread_cond));
+
+       /*create threads */
+       handle->thread = g_thread_new("encode_thread", (GThreadFunc) _image_util_encode_thread, (gpointer) handle);
+       if (!handle->thread) {
+               image_util_error("ERROR - create thread");
+               g_mutex_clear(&(handle->thread_mutex));
+
+               g_cond_clear(&(handle->thread_cond));
+               return MM_UTIL_ERROR_INVALID_OPERATION;
+       }
+
+       return ret;
+}
+
+int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_completed_cb completed_cb, void *user_data)
+{
+       int err = MM_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       if (_handle == NULL || _handle->is_decode == TRUE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       if ((_handle->path == NULL && _handle->dst_buffer == NULL) || _handle->src_buffer == NULL) {
+               image_util_error("Invalid input/output");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+       image_util_retvm_if((_image_util_check_resolution(_handle->width, _handle->height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
+
+       image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
+
+       if (_handle->_encode_cb != NULL) {
+               IMAGE_UTIL_SAFE_FREE(_handle->_encode_cb);
+               _handle->_encode_cb = NULL;
+       }
+       _handle->_encode_cb = (encode_cb_s *) calloc(1, sizeof(encode_cb_s));
+       image_util_retvm_if((_handle->_encode_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
+
+       _handle->_encode_cb->user_data = user_data;
+       _handle->_encode_cb->image_encode_completed_cb = completed_cb;
+
+       err = _image_util_encode_create_thread(_handle);
+
+       return _convert_image_util_error_code(__func__, err);
+}
+
+int image_util_encode_destroy(image_util_encode_h handle)
+{
+       int err = IMAGE_UTIL_ERROR_NONE;
+       decode_encode_s *_handle = (decode_encode_s *) handle;
+
+       image_util_debug("image_util_encode_destroy");
+
+       if (_handle == NULL || _handle->is_decode == TRUE) {
+               image_util_error("Invalid Handle");
+               return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+       }
+
+       switch (_handle->image_type) {
+       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;
+       default:
+               err = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+               break;
+       }
+
+       /* g_thread_exit(handle->thread); */
+       if (_handle->thread) {
+               _handle->is_finish = TRUE;
+               g_mutex_lock(&(_handle->thread_mutex));
+               g_cond_signal(&(_handle->thread_cond));
+               image_util_debug("===> send signal(finish) to decode_thread");
+               g_mutex_unlock(&(_handle->thread_mutex));
+
+               g_thread_join(_handle->thread);
+
+               g_mutex_clear(&(_handle->thread_mutex));
+
+               g_cond_clear(&(_handle->thread_cond));
+       }
+
+       IMAGE_UTIL_SAFE_FREE(_handle);
+
+       return err;
+}