[ACR-1374] [Add] Add new sync transform APIs (convert, crop, resize, rotate) 75/200575/47
authorhj kim <backto.kim@samsung.com>
Wed, 27 Feb 2019 02:56:53 +0000 (11:56 +0900)
committerhj kim <backto.kim@samsung.com>
Thu, 4 Apr 2019 03:00:05 +0000 (12:00 +0900)
[Added]
image_util_create_image(unsigned int width, unsigned int height, image_util_colorspace_e colorspace, const unsigned char *data, size_t data_size, image_h *image)
image_util_get_image(image_h image, unsigned int *width, unsigned int *height, image_util_colorspace_e *colorspace, unsigned char **data, size_t *data_size)
image_util_clone_image(image_h src, image_h *dst)
image_util_destroy_image(image_h image)

typedef void(*image_util_transform_completed_2_cb)(image_h dst, int error_code, void *user_data)
image_util_transform_run_2(transformation_h handle, image_h image, image_h *dst)
image_util_transform_run_2_async(transformation_h handle, image_h src, image_util_transform_completed_2_cb callback, void *user_data)

Change-Id: I0a2dd604134f1e5fe44314794641bb4fefa33c39

include/image_util.h
include/image_util_private.h
include/image_util_type.h
src/image_util.c
test/image_util_test.c [changed mode: 0755->0644]

index 5d6a823..cf2a287 100755 (executable)
@@ -353,7 +353,72 @@ int image_util_transform_get_crop_area(transformation_h handle, unsigned int *st
 int image_util_transform_run(transformation_h handle, media_packet_h src, image_util_transform_completed_cb callback, void *user_data);
 
 /**
-* @brief Destroys a handle of image util.
+* @brief Transforms an image with given transformation handle.
+* @details This function transforms @a src image synchronously.\n
+* @since_tizen 5.5
+*
+* @remarks If transforming is failed, the @a dst will be null.
+*               The @a dst should be released using image_util_destroy_image().
+*
+* @param[in] handle The handle of transform
+* @param[in] src A handle of src image
+* @param[out] dst The transformed 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
+* @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory
+*
+* @pre Create a transformation handle by calling image_util_transform_create().
+* @pre Set the transformation information by calling image_util_transform_set_colorspace(), image_util_transform_set_resolution(), \n
+*         image_util_transform_set_rotation(), image_util_transform_set_crop_area().
+* @see image_util_transform_create()
+* @see image_util_transform_destroy()
+* @see image_util_transform_set_colorspace()
+* @see image_util_transform_set_resolution()
+* @see image_util_transform_set_rotation()
+* @see image_util_transform_set_crop_area()
+*/
+int image_util_transform_run2(transformation_h handle, image_h src, image_h *dst);
+
+/**
+* @brief Transforms an image with given transformation handle.
+* @details This function transforms @a src image asynchronously, @a callback will be called after completing transform. \n
+* @since_tizen 5.5
+*
+* @remarks If transforming is failed, the dst of callback parameter will be null.
+*
+* @param[in] handle The handle of transform
+* @param[in] src The image handle to transform
+* @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
+* @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory
+*
+* @pre Create a transformation handle by calling image_util_transform_create().
+* @pre Set the transformation information by calling image_util_transform_set_colorspace(), image_util_transform_set_resolution(), \n
+*         image_util_transform_set_rotation(), image_util_transform_set_crop_area().
+* @see image_util_transform_create()
+* @see image_util_transform_destroy()
+* @see image_util_transform_set_colorspace()
+* @see image_util_transform_set_resolution()
+* @see image_util_transform_set_rotation()
+* @see image_util_transform_set_crop_area()
+* @see image_util_transform_completed2_cb()
+*/
+int image_util_transform_run2_async(transformation_h handle, image_h src, image_util_transform_completed2_cb callback, void *user_data);
+
+/**
+* @brief Destroys a handle to image util.
 * @details The function frees all resources related to the image util handle. The image util
 *               handle no longer can be used to perform any operations. A new image util handle
 *               has to be created before the next usage.
@@ -373,6 +438,95 @@ int image_util_transform_run(transformation_h handle, media_packet_h src, image_
 int image_util_transform_destroy(transformation_h handle);
 
 /**
+* @brief Creates a image handle.
+* @since_tizen 5.5
+*
+* @remarks The @a image should be released using image_util_destroy_image().
+*
+* @param[in] width             The width of image
+* @param[in] height            The height of image
+* @param[in] colorspace        The colorspace of image
+* @param[in] data              The data of image
+* @param[in] data_size The size of data
+* @param[out] image            A handle of 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_OUT_OF_MEMORY Out of memory
+*
+* @see image_util_destroy_image()
+* @see image_util_get_image()
+* @see image_util_clone_image()
+*/
+int image_util_create_image(unsigned int width, unsigned int height, image_util_colorspace_e colorspace, const unsigned char *data, size_t data_size, image_h *image);
+
+/**
+* @brief Clones a image handle.
+* @since_tizen 5.5
+*
+* @remarks The @a dst should be released using image_util_destroy_image().
+*
+* @param[in] src               The handle of image
+* @param[out] dst              A handle of cloned 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_OUT_OF_MEMORY Out of memory
+*
+* @see image_util_destroy_image()
+* @see image_util_get_image()
+*/
+int image_util_clone_image(image_h src, image_h *dst);
+
+/**
+* @brief Gets the information from the image.
+* @since_tizen 5.5
+*
+* @remarks The @a data should be released using free() if that's not NULL. And if you don't want to get specific information, you can set parameters to NULL.
+*
+* @param[in] image             A handle to image
+* @param[out] width            The width of image
+* @param[out] height           The height of image
+* @param[out] colorspace       The colorspace of image
+* @param[out] data             The data of image
+* @param[out] data_size        The size of data
+*
+* @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_create_image()
+*/
+int image_util_get_image(image_h image, unsigned int *width, unsigned int *height, image_util_colorspace_e *colorspace, unsigned char **data, size_t *data_size);
+
+/**
+* @brief Destroys a image handle.
+* @details The function frees all resources related to the @ image. The image handle no longer can be used to perform any operations.
+*               A new image handle has to be created before the next usage.
+* @since_tizen 5.5
+*
+* @param[in] image A handle to 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
+*
+* @see image_util_create_image()
+*/
+int image_util_destroy_image(image_h image);
+
+/**
  * @}
  */
 
index 05063d8..f1f0113 100755 (executable)
@@ -91,11 +91,6 @@ extern "C"
 typedef gboolean(*ModuleFunc)(void *, int, int, unsigned char *, unsigned char *, unsigned char *);
 
 typedef struct {
-       void *user_data;
-       image_util_transform_completed_cb completed_cb;
-} image_util_cb_s;
-
-typedef struct {
        /* for converting colorspace */
        mm_util_color_format_e color;
        /* for image crop */
@@ -108,14 +103,12 @@ typedef struct {
        /* for rotation */
        mm_util_img_rotate_type rotation;
 
-       bool set_convert;
-       bool set_crop;
-       bool set_resize;
-       bool set_rotate;
+       gboolean set_convert;
+       gboolean set_crop;
+       gboolean set_resize;
+       gboolean set_rotate;
 
        /* for multi instance */
-       image_util_cb_s *_util_cb;
-       gboolean is_finish;
        GThread* thread;
        GAsyncQueue *queue;
 } transformation_s;
index 7de974b..10aaf49 100755 (executable)
@@ -77,12 +77,18 @@ typedef enum {
        IMAGE_UTIL_COLORSPACE_BGRA8888, /**< BGRA8888, high-byte is Alpha */
        IMAGE_UTIL_COLORSPACE_RGBA8888, /**< RGBA8888, high-byte is Alpha */
        IMAGE_UTIL_COLORSPACE_BGRX8888, /**< BGRX8888, high-byte is X */
-       IMAGE_UTIL_COLORSPACE_NV21,      /**< NV12- planar */
+       IMAGE_UTIL_COLORSPACE_NV21,      /**< NV21- planar */
        IMAGE_UTIL_COLORSPACE_NV16,      /**< NV16- planar */
        IMAGE_UTIL_COLORSPACE_NV61,      /**< NV61- planar */
 } image_util_colorspace_e;
 
 /**
+* @brief Image handle.
+* @since_tizen 5.5
+*/
+typedef void *image_h;
+
+/**
  * @}
  */
 
@@ -127,6 +133,26 @@ typedef struct transformation_s *transformation_h;
 typedef void(*image_util_transform_completed_cb)(media_packet_h *dst, int error_code, void *user_data);
 
 /**
+* @ingroup CAPI_MEDIA_IMAGE_UTIL_TRANSFORM_MODULE
+* @brief Called when transforming image is completed.
+*
+* @since_tizen 5.5
+*
+* @remarks The @a dst can be used only in the callback. To use outside, make a copy using image_util_clone_image(). \n
+*          The callback is called in a separate thread(not in the main loop).
+*
+* @param[in] dst The transformed image
+* @param[in] error_code The error code of transformation
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre image_util_transform_run2_async()
+*
+* @see image_util_transform_run2_async()
+* @see image_util_clone_image()
+*/
+typedef void(*image_util_transform_completed2_cb)(image_h dst, int error_code, void *user_data);
+
+/**
  * @}
  */
 
index d214d6b..11231c0 100644 (file)
@@ -28,6 +28,15 @@ typedef struct {
        const char *mimetype_name;
 } image_format_mimetype_pair_s;
 
+typedef struct {
+       gboolean thread_stop;
+       transformation_h transform;
+       image_h src;
+       void *completed_cb;
+       void *user_data;
+       gboolean is_transform2;
+} t_data_s;
+
 static const image_format_mimetype_pair_s image_format_mimetype_table[MM_UTIL_COLOR_NUM] = {
        { MM_UTIL_COLOR_YUV420, MEDIA_FORMAT_YV12,              "MEDIA_FORMAT_YV12" },
        { MM_UTIL_COLOR_YUV422, MEDIA_FORMAT_422P,              "MEDIA_FORMAT_422P" },
@@ -147,38 +156,39 @@ static int __create_media_packet(media_format_h fmt, media_packet_h *new_pkt, vo
        return IMAGE_UTIL_ERROR_NONE;
 }
 
-static int __mm_util_transform(transformation_s *operation, mm_util_image_h origin, mm_util_image_h *transform)
+static int __mm_util_transform(transformation_h handle, image_h origin, image_h *transform)
 {
        int ret = IMAGE_UTIL_ERROR_NONE;
-       mm_util_image_h _src = origin;
-       mm_util_image_h _dst = NULL;
+       transformation_s *_handle = (transformation_s *) handle;
+       image_h _src = origin;
+       image_h _dst = NULL;
 
-       image_util_retvm_if(!operation, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid operation");
+       image_util_retvm_if(!handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle");
        image_util_retvm_if(!mm_image_is_valid_image(origin), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid origin");
        image_util_retvm_if(!transform, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid transform");
 
        image_util_fenter();
 
-       if (operation->set_crop) {
-               ret = mm_util_crop_image(_src, operation->x, operation->y, operation->width, operation->height, &_dst);
+       if (_handle->set_crop) {
+               ret = mm_util_crop_image(_src, _handle->x, _handle->y, _handle->width, _handle->height, &_dst);
                image_util_retvm_if(ret != MM_UTIL_ERROR_NONE, _image_error_capi(ret), "mm_util_crop_image failed");
                _src = _dst;
-       } else if (operation->set_resize) {
-               ret = mm_util_resize_image(_src, operation->width, operation->height, &_dst);
+       } else if (_handle->set_resize) {
+               ret = mm_util_resize_image(_src, _handle->width, _handle->height, &_dst);
                image_util_retvm_if(ret != MM_UTIL_ERROR_NONE, _image_error_capi(ret), "mm_util_resize_image failed");
                _src = _dst;
        }
 
-       if (operation->set_convert) {
-               ret = mm_util_convert_colorspace(_src, operation->color, &_dst);
+       if (_handle->set_convert) {
+               ret = mm_util_convert_colorspace(_src, _handle->color, &_dst);
                if (origin != _src)
                        mm_image_destroy_image(_src);
                image_util_retvm_if(ret != MM_UTIL_ERROR_NONE, _image_error_capi(ret), "mm_util_convert_colorspace failed");
                _src = _dst;
        }
 
-       if (operation->set_rotate) {
-               ret = mm_util_rotate_image(_src, operation->rotation, &_dst);
+       if (_handle->set_rotate) {
+               ret = mm_util_rotate_image(_src, _handle->rotation, &_dst);
                if (origin != _src)
                        mm_image_destroy_image(_src);
                image_util_retvm_if(ret != MM_UTIL_ERROR_NONE, _image_error_capi(ret), "mm_util_rotate_image failed");
@@ -188,12 +198,12 @@ static int __mm_util_transform(transformation_s *operation, mm_util_image_h orig
 
        image_util_fleave();
 
-       return ret;
+       return _image_error_capi(ret);
 }
 
-static int __image_util_image_to_packet(mm_image_info_s *image, media_packet_h *packet)
+static int __image_util_image_to_packet(image_h image, media_packet_h *packet)
 {
-       int err = IMAGE_UTIL_ERROR_NONE;
+       int ret = IMAGE_UTIL_ERROR_NONE;
        mm_util_color_format_e format = 0;
        unsigned int width = 0, height = 0;
        unsigned char *buffer = NULL;
@@ -205,21 +215,22 @@ static int __image_util_image_to_packet(mm_image_info_s *image, media_packet_h *
 
        image_util_fenter();
 
-       image_util_retvm_if((image == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle");
+       image_util_retvm_if(!image, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image");
+       image_util_retvm_if(!packet, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid packet");
 
-       err = mm_image_get_image((mm_util_image_h)image, &width, &height, &format, &buffer, &buffer_size);
-       image_util_retvm_if((err != MM_UTIL_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "mm_image_get_image failed");
+       ret = mm_image_get_image(image, &width, &height, &format, &buffer, &buffer_size);
+       image_util_retvm_if((ret != MM_UTIL_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "mm_image_get_image failed");
 
-       err = __create_media_format(__image_format_to_mimetype(format), width, height, &fmt);
-       if (err != IMAGE_UTIL_ERROR_NONE) {
-               image_util_error("__create_media_format failed (%d)", err);
+       ret = __create_media_format(__image_format_to_mimetype(format), width, height, &fmt);
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               image_util_error("__create_media_format failed (%d)", ret);
                IMAGE_UTIL_SAFE_FREE(buffer);
                return IMAGE_UTIL_ERROR_INVALID_OPERATION;
        }
 
-       err = __create_media_packet(fmt, packet, &packet_ptr, &packet_size);
-       if (err != MEDIA_PACKET_ERROR_NONE) {
-               image_util_error("__create_media_packet failed (%d)", err);
+       ret = __create_media_packet(fmt, packet, &packet_ptr, &packet_size);
+       if (ret != MEDIA_PACKET_ERROR_NONE) {
+               image_util_error("__create_media_packet failed (%d)", ret);
                media_format_unref(fmt);
                IMAGE_UTIL_SAFE_FREE(buffer);
                return IMAGE_UTIL_ERROR_INVALID_OPERATION;
@@ -235,9 +246,9 @@ static int __image_util_image_to_packet(mm_image_info_s *image, media_packet_h *
        memcpy(packet_ptr, buffer, size);
        IMAGE_UTIL_SAFE_FREE(buffer);
 
-       err = media_packet_set_buffer_size(*packet, (uint64_t)size);
-       if (err != MEDIA_PACKET_ERROR_NONE) {
-               image_util_error("media_packet_set_buffer_size failed (%d)", err);
+       ret = media_packet_set_buffer_size(*packet, (uint64_t)size);
+       if (ret != MEDIA_PACKET_ERROR_NONE) {
+               image_util_error("media_packet_set_buffer_size failed (%d)", ret);
                media_packet_destroy(*packet);
                return IMAGE_UTIL_ERROR_INVALID_OPERATION;
        }
@@ -247,99 +258,161 @@ static int __image_util_image_to_packet(mm_image_info_s *image, media_packet_h *
        return IMAGE_UTIL_ERROR_NONE;
 }
 
-gpointer __mm_util_thread_repeate(gpointer data)
+gpointer __transform_thread(gpointer data)
 {
-       transformation_s *handle = (transformation_s *) data;
        int ret = IMAGE_UTIL_ERROR_NONE;
-       mm_util_image_h origin_image = NULL;
-       mm_util_image_h transformed_image = NULL;
-       media_packet_h packet = NULL;
+       GAsyncQueue *_queue = (GAsyncQueue *)data;
+       t_data_s *_t_data = NULL;
+       image_util_transform_completed_cb callback = NULL;
+       image_util_transform_completed2_cb callback_2 = NULL;
+       media_packet_h _transformed_packet = NULL;
+       image_h _transformed_image = NULL;
+
+       image_util_fenter();
 
-       image_util_retvm_if(handle == NULL, NULL, "invalid handle");
+       while (1) {
+               image_util_warning("thread is running...");
 
-       while (!handle->is_finish) {
-               image_util_debug("waiting...");
-               origin_image = g_async_queue_timeout_pop(handle->queue, 300 * G_TIME_SPAN_MILLISECOND);
-               image_util_debug("get from data or timeout");
+               _t_data = g_async_queue_pop(_queue);
+               image_util_debug("g_async_queue_pop is done");
 
-               if (origin_image == NULL) {
-                       image_util_error("The data is null");
+               if (!_t_data) {
+                       image_util_error("Invalid handle");
                        continue;
                }
 
-               mm_image_debug_image(origin_image, "Origin");
+               if (_t_data->thread_stop) {
+                       image_util_warning("thread stopped");
+                       break;
+               }
 
-               ret = __mm_util_transform(handle, origin_image, &transformed_image);
-               if (ret == IMAGE_UTIL_ERROR_NONE) {
-                       mm_image_debug_image(transformed_image, "Transformed");
-                       image_util_debug("Success - transform");
-               } else {
-                       image_util_error("Error - transform");
+               if (!_t_data->completed_cb) {
+                       image_util_error("Invalid callback");
+                       continue;
                }
 
-               if ((handle->_util_cb != NULL) && (handle->_util_cb->completed_cb != NULL)) {
-                       image_util_debug("completed_cb is called");
-                       ret = __image_util_image_to_packet(transformed_image, &packet);
+               ret = __mm_util_transform(_t_data->transform, _t_data->src, &_transformed_image);
+               if (ret != IMAGE_UTIL_ERROR_NONE)
+                               image_util_error("__mm_util_transform failed (%d)", ret);
+               else
+                       mm_image_debug_image(_transformed_image, "Transformed(Async)");
+
+               if (_t_data->is_transform2) {
+                       image_util_debug("invoke callback with image[%d]", ret);
+
+                       callback_2 = (image_util_transform_completed2_cb)_t_data->completed_cb;
+                       callback_2(_transformed_image, ret, _t_data->user_data);
+
+               } else {
+                       callback = (image_util_transform_completed_cb)_t_data->completed_cb;
+
                        if (ret != IMAGE_UTIL_ERROR_NONE) {
-                               image_util_error("__image_util_image_to_packet failed (%d)", ret);
-                               handle->_util_cb->completed_cb(NULL, ret, handle->_util_cb->user_data);
+                               image_util_error("__mm_util_transform failed (%d)", ret);
+                               callback(NULL, ret, _t_data->user_data);
                        } else {
-                               handle->_util_cb->completed_cb(&packet, ret, handle->_util_cb->user_data);
+                               ret = __image_util_image_to_packet(_transformed_image, &_transformed_packet);
+                               if (ret != IMAGE_UTIL_ERROR_NONE) {
+                                       callback(NULL, ret, _t_data->user_data);
+                               } else {
+                                       image_util_debug("invoke callback with packet[%d]", ret);
+                                       callback(&_transformed_packet, ret, _t_data->user_data);
+                               }
                        }
-               } else {
-                       image_util_error("There is no callback");
                }
-               mm_image_destroy_image(origin_image);
-               mm_image_destroy_image(transformed_image);
+
+               mm_image_destroy_image(_transformed_image);
+               mm_image_destroy_image(_t_data->src);
+               IMAGE_UTIL_SAFE_FREE(_t_data->transform);
+               IMAGE_UTIL_SAFE_FREE(_t_data);
        }
 
-       image_util_debug("exit thread");
-       handle->thread = NULL;
+       image_util_fleave();
 
        return NULL;
 }
 
-static int _image_util_packet_to_image(media_packet_h packet, mm_util_image_h *color_image)
+static int __image_util_packet_to_image(media_packet_h packet, image_h *image)
 {
-       int err = IMAGE_UTIL_ERROR_NONE;
+       int ret = IMAGE_UTIL_ERROR_NONE;
        media_format_mimetype_e mimetype = 0;
        int width = 0, height = 0;
        uint64_t size = 0;
        void *ptr = NULL;
        media_format_h fmt = NULL;
 
-       image_util_retvm_if(((packet == NULL) || (color_image == NULL)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       image_util_retvm_if(!packet, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid packet");
+       image_util_retvm_if(!image, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image");
 
-       err = media_packet_get_format(packet, &fmt);
-       image_util_retvm_if((err != MEDIA_PACKET_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "media_packet_get_format failed (%d)", err);
+       ret = media_packet_get_format(packet, &fmt);
+       image_util_retvm_if((ret != MEDIA_PACKET_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "media_packet_get_format failed (%d)", ret);
 
-       err = media_format_get_video_info(fmt, &mimetype, &width, &height, NULL, NULL);
-       if (err != MEDIA_FORMAT_ERROR_NONE) {
-               image_util_error("media_packet_get_format failed (%d)", err);
+       ret = media_format_get_video_info(fmt, &mimetype, &width, &height, NULL, NULL);
+       if (ret != MEDIA_FORMAT_ERROR_NONE) {
+               image_util_error("media_packet_get_format failed (%d)", ret);
                media_format_unref(fmt);
                return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
        }
        media_format_unref(fmt);
 
-       err = media_packet_get_buffer_size(packet, &size);
-       image_util_retvm_if((err != MEDIA_PACKET_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "media_packet_get_buffer_size failed (%d)", err);
+       ret = media_packet_get_buffer_size(packet, &size);
+       image_util_retvm_if((ret != MEDIA_PACKET_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "media_packet_get_buffer_size failed (%d)", ret);
 
        if (size) {
-               err = media_packet_get_buffer_data_ptr(packet, &ptr);
-               image_util_retvm_if((err != MEDIA_PACKET_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "media_packet_get_buffer_data_ptr failed (%d)", err);
+               ret = media_packet_get_buffer_data_ptr(packet, &ptr);
+               image_util_retvm_if((ret != MEDIA_PACKET_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "media_packet_get_buffer_data_ptr failed (%d)", ret);
        }
 
        image_util_debug("[Fotmat: %u] W x H : %d x %d", mimetype, width, height);
        image_util_retvm_if(((width <= 0) || (height <= 0) || (size == 0) || (ptr == NULL)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid source packet");
 
-       err = mm_image_create_image(width, height, __mimetype_to_image_format(mimetype), ptr, (size_t)size, color_image);
-       image_util_retvm_if((err != IMAGE_UTIL_ERROR_NONE), err, "mm_image_create_image failed (%d)", err);
+       ret = mm_image_create_image(width, height, __mimetype_to_image_format(mimetype), ptr, (size_t)size, image);
+       image_util_retvm_if((ret != IMAGE_UTIL_ERROR_NONE), ret, "mm_image_create_image failed (%d)", ret);
 
-       image_util_debug("_image_util_packet_to_image succeed");
+       image_util_debug("__image_util_packet_to_image succeed");
 
        return IMAGE_UTIL_ERROR_NONE;
 }
 
+static int __clone_transform(transformation_h src, transformation_h *dst)
+{
+       int ret = IMAGE_UTIL_ERROR_NONE;
+       transformation_s *_src = (transformation_s *)src;
+       transformation_s *_dst = NULL;
+
+       image_util_retvm_if(!src, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid src");
+       image_util_retvm_if(!dst, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dst");
+
+       _dst = calloc(1, sizeof(transformation_s));
+       image_util_retvm_if(!_dst, IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Memory allocation failed");
+
+       memcpy(_dst, _src, sizeof(transformation_s));
+
+       *dst = (transformation_h)_dst;
+
+       return ret;
+}
+
+static void __destroy_async_queue(gpointer data)
+{
+       t_data_s *_t_data = (t_data_s *)data;
+
+       image_util_retm_if((data == NULL), "Invalid data");
+
+       mm_image_destroy_image(_t_data->src);
+       IMAGE_UTIL_SAFE_FREE(_t_data->transform);
+       IMAGE_UTIL_SAFE_FREE(_t_data);
+}
+
+static gboolean __is_valid_condition(transformation_h handle)
+{
+       transformation_s *_handle = (transformation_s *) handle;
+
+       image_util_retvm_if(!handle, FALSE, "Invalid handle");
+
+       image_util_retvm_if((!_handle->set_convert && !_handle->set_resize && !_handle->set_rotate && !_handle->set_crop), FALSE, "Invalid condition");
+
+       return TRUE;
+}
 int image_util_transform_create(transformation_h * handle)
 {
        image_util_fenter();
@@ -357,26 +430,38 @@ int image_util_transform_create(transformation_h * handle)
        _handle->y = 0;
        _handle->width = 0;
        _handle->height = 0;
-       _handle->is_finish = FALSE;
 
        _handle->set_convert = FALSE;
        _handle->set_crop = FALSE;
        _handle->set_resize = FALSE;
        _handle->set_rotate = FALSE;
 
-       /*These are a communicator for thread*/
-       if (!_handle->queue)
-               _handle->queue = g_async_queue_new();
-
-       if (_handle->queue == NULL) {
+       /* The queue is a communicator for thread */
+       _handle->queue = g_async_queue_new_full(__destroy_async_queue);
+       if (!_handle->queue) {
                image_util_error("g_async_queue_new failed");
-               IMAGE_UTIL_SAFE_FREE(_handle);
-               return IMAGE_UTIL_ERROR_INVALID_OPERATION;
+               goto Error;
+       }
+
+       /* create thread */
+       _handle->thread = g_thread_new("transform_thread", (GThreadFunc)__transform_thread, (gpointer)_handle->queue);
+       if (!_handle->thread) {
+               image_util_error("Fail - Create thread");
+               goto Error;
        }
 
        *handle = (transformation_h) _handle;
 
        return IMAGE_UTIL_ERROR_NONE;
+
+Error:
+       if (_handle->queue)
+               g_async_queue_unref(_handle->queue);
+       if (_handle->thread)
+               g_thread_unref(_handle->thread);
+       IMAGE_UTIL_SAFE_FREE(_handle);
+
+       return IMAGE_UTIL_ERROR_INVALID_OPERATION;
 }
 
 int image_util_transform_set_hardware_acceleration(transformation_h handle, bool mode)
@@ -530,66 +615,93 @@ int image_util_transform_get_crop_area(transformation_h handle, unsigned int *st
        return IMAGE_UTIL_ERROR_NONE;
 }
 
-int image_util_transform_run(transformation_h handle, media_packet_h src, image_util_transform_completed_cb completed_cb, void *user_data)
+static int __mm_util_transform_async(transformation_h handle, image_h src, void *callback, void *user_data, gboolean is_transform2)
 {
-       int err = IMAGE_UTIL_ERROR_NONE;
-       transformation_s *_handle = (transformation_s *) handle;
-       mm_util_image_h color_image = NULL;
+       int ret = IMAGE_UTIL_ERROR_NONE;
+       transformation_s *_handle = (transformation_s *)handle;
+       t_data_s *_t_data = NULL;
 
        image_util_fenter();
 
-       image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
-       image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
-       image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid source");
-       image_util_retvm_if((_handle->queue == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid queue");
-       image_util_retvm_if((!_handle->set_convert && !_handle->set_resize && !_handle->set_rotate && !_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid transform");
+       image_util_retvm_if(!_handle, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
+       image_util_retvm_if(!src, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid source");
+       image_util_retvm_if(!callback, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
+       image_util_retvm_if(!_handle->queue || !_handle->thread, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid thread");
+       image_util_retvm_if(!__is_valid_condition(handle), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid transform condition");
 
-       err = _image_util_packet_to_image(src, &color_image);
-       image_util_retvm_if((err != IMAGE_UTIL_ERROR_NONE), err, "_image_util_packet_to_image failed");
+       _t_data = calloc(1, sizeof(t_data_s));
+       image_util_retvm_if(!_t_data, IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Memory allocation failed");
 
-       IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
+       ret = __clone_transform(handle, &_t_data->transform);
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               image_util_error("__clone_transform failed (%d)", ret);
+               IMAGE_UTIL_SAFE_FREE(_t_data);
+               return ret;
+       }
 
-       _handle->_util_cb = (image_util_cb_s *) calloc(1, sizeof(image_util_cb_s));
-       if (_handle->_util_cb == NULL) {
-               image_util_error("Memory allocation failed");
-               mm_image_destroy_image(color_image);
-               return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
+       if (is_transform2) {
+               ret = image_util_clone_image(src, &_t_data->src);
+               if (ret != IMAGE_UTIL_ERROR_NONE) {
+                       image_util_error("mm_util_clone_image failed (%d)", ret);
+                       IMAGE_UTIL_SAFE_FREE(_t_data->transform);
+                       IMAGE_UTIL_SAFE_FREE(_t_data);
+                       return ret;
+               }
+       } else {
+               _t_data->src = src;     //already copied
        }
 
-       _handle->_util_cb->user_data = user_data;
-       _handle->_util_cb->completed_cb = completed_cb;
+       _t_data->thread_stop = FALSE;
+       _t_data->completed_cb = callback;
+       _t_data->user_data = user_data;
+       _t_data->is_transform2 = is_transform2;
 
        image_util_debug("g_async_queue_push");
-       g_async_queue_push(_handle->queue, GINT_TO_POINTER(color_image));
+       g_async_queue_push(_handle->queue, GINT_TO_POINTER(_t_data));
 
-       if (!_handle->thread) {
-               /*create threads*/
-               _handle->thread = g_thread_new("transform_thread", (GThreadFunc)__mm_util_thread_repeate, (gpointer)_handle);
-               if (_handle->thread == NULL) {
-                       image_util_error("Fail - Create thread");
-                       mm_image_destroy_image(color_image);
-                       return IMAGE_UTIL_ERROR_INVALID_OPERATION;
-               } else {
-                       image_util_debug("Success - Create thread");
-               }
-       } else {
-               image_util_debug("Thread alreay exist");
-       }
+       image_util_fleave();
 
        return IMAGE_UTIL_ERROR_NONE;
 }
 
+int image_util_transform_run(transformation_h handle, media_packet_h src, image_util_transform_completed_cb callback, void *user_data)
+{
+       int ret = IMAGE_UTIL_ERROR_NONE;
+       image_h _src = NULL;
+
+       ret = __image_util_packet_to_image(src, &_src);
+       image_util_retvm_if(ret != IMAGE_UTIL_ERROR_NONE, ret, "Fail to __image_util_packet_to_image");
+
+       return __mm_util_transform_async(handle, _src, callback, user_data, FALSE);
+}
+
+int image_util_transform_run2(transformation_h handle, image_h src, image_h *dst)
+{
+       image_util_fenter();
+
+       image_util_retvm_if(!__is_valid_condition(handle), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid transform condition");
+
+       return __mm_util_transform(handle, src, dst);
+}
+
+int image_util_transform_run2_async(transformation_h handle, image_h src, image_util_transform_completed2_cb callback, void *user_data)
+{
+       return __mm_util_transform_async(handle, src, callback, user_data, TRUE);
+}
+
 int image_util_transform_destroy(transformation_h handle)
 {
        transformation_s *_handle = (transformation_s *) handle;
+       t_data_s _thread_stop = { TRUE, NULL, NULL, NULL, NULL, FALSE};
 
        image_util_fenter();
 
        image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
 
        if (_handle->thread) {
-               _handle->is_finish = TRUE;
+               g_async_queue_push_front(_handle->queue, GINT_TO_POINTER(&_thread_stop));
                g_thread_join(_handle->thread);
+               _handle->thread = NULL;
        }
 
        if (_handle->queue) {
@@ -597,7 +709,6 @@ int image_util_transform_destroy(transformation_h handle)
                _handle->queue = NULL;
        }
 
-       IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
        IMAGE_UTIL_SAFE_FREE(_handle);
 
        image_util_fleave();
@@ -605,6 +716,42 @@ int image_util_transform_destroy(transformation_h handle)
        return IMAGE_UTIL_ERROR_NONE;
 }
 
+int image_util_create_image(unsigned int width, unsigned int height, image_util_colorspace_e colorspace, const unsigned char *data, size_t data_size, image_h *image)
+{
+       int ret = IMAGE_UTIL_ERROR_NONE;
+
+       ret = mm_image_create_image(width, height, colorspace, data, data_size, image);
+
+       return _image_error_capi(ret);
+}
+
+int image_util_clone_image(image_h src, image_h *dst)
+{
+       int ret = IMAGE_UTIL_ERROR_NONE;
+
+       ret = mm_image_clone_image(src, dst);
+
+       return _image_error_capi(ret);
+}
+
+int image_util_get_image(image_h image, unsigned int *width, unsigned int *height, image_util_colorspace_e *colorspace, unsigned char **data, size_t *data_size)
+{
+       int ret = IMAGE_UTIL_ERROR_NONE;
+
+       ret = mm_image_get_image(image, width, height, (mm_util_color_format_e *)colorspace, data, data_size);
+
+       return _image_error_capi(ret);
+}
+
+int image_util_destroy_image(image_h image)
+{
+       image_util_retvm_if(!image, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image");
+
+       mm_image_destroy_image(image);
+
+       return IMAGE_UTIL_ERROR_NONE;
+}
+
 int image_util_calculate_buffer_size(int width, int height, image_util_colorspace_e colorspace, unsigned int *size)
 {
        int err = IMAGE_UTIL_ERROR_NONE;
old mode 100755 (executable)
new mode 100644 (file)
index da2439f..6dbd64d
 
 #define MAX_STRING_LEN 128
 #define IMAGE_FORMAT_LABEL_BUFFER_SIZE 4
-#define IMAGE_TEST_MAX_REPEAT_COUNT 100
+#define MAX_REPEAT_COUNT 100
 
 #define IMAGE_UTIL_SAFE_FREE(src)      { if (src) {free(src); src = NULL; } }
 
 
 GMainLoop *g_loop = NULL;
 transformation_h g_handle = NULL;
-media_packet_h g_src = NULL;
+static media_packet_h g_src_packet = NULL;
+static image_h g_src_image = NULL;
 char *g_path = NULL;
 unsigned int g_width = 0;
 unsigned int g_height = 0;
 image_util_rotation_e g_angle = IMAGE_UTIL_ROTATION_NONE;
 int g_format = -1;
-
-GCond g_thread_cond;
-GMutex g_thread_mutex;
+static unsigned int g_request_count = 0;
 
 enum {
        CURRENT_STATE_MAIN_MENU,
-       CURRENT_STATE_SET_IMAGE_MENU,
        CURRENT_STATE_SET_ROTATION_PARAMETER_MENU,
 };
 
-enum {
-       CURRENT_STATE_SET_IMAGE_NONE,
-       CURRENT_STATE_SET_IMAGE_PATH,
-       CURRENT_STATE_SET_IMAGE_WIDTH,
-       CURRENT_STATE_SET_IMAGE_HEIGHT,
-       CURRENT_STATE_SET_IMAGE_FORMAT,
-};
-
 int g_menu_state = CURRENT_STATE_MAIN_MENU;
-int g_menu_set_image_state = CURRENT_STATE_SET_IMAGE_NONE;
 int g_menu_rotation_parameter = IMAGE_UTIL_ROTATION_NONE;
 
-void _wait()
-{
-       g_mutex_lock(&g_thread_mutex);
-       g_printf("waiting... untill finishing transform \n");
-       g_cond_wait(&g_thread_cond, &g_thread_mutex);
-       g_printf("<=== 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);
-       g_printf("===> send signal to test proc \n");
-       g_mutex_unlock(&g_thread_mutex);
-}
+static void display_menu(void);
 
 media_format_mimetype_e
 _image_util_mapping_imgp_format_to_mime(image_util_colorspace_e colorspace)
@@ -130,7 +104,166 @@ _image_util_mapping_imgp_format_to_mime(image_util_colorspace_e colorspace)
        return mimetype;
 }
 
-bool test_transform_completed_cb(media_packet_h *packet, image_util_error_e error, void *user_data)
+static gboolean __read_file(char *path, void **data, size_t *length)
+{
+       FILE *fp = NULL;
+       long len = 0;
+
+       if (!path || !data || length == 0) {
+               fprintf(stderr, "\tinvalid data %s %p %p\n", path, data, length);
+               return FALSE;
+       }
+
+       fprintf(stderr, "\t%s read\n", path);
+
+       fp = fopen(path, "r");
+       if (fp == NULL) {
+               fprintf(stderr, "\tfopen failed (%d) \n", errno);
+               return FALSE;
+       }
+
+       if (fseek(fp, 0, SEEK_END) < 0) {
+               fprintf(stderr, "\tfseek failed \n");
+               fclose(fp);
+               return FALSE;
+       }
+
+       len = ftell(fp);
+       if (len < 0) {
+               fprintf(stderr, "\tftell failed \n");
+               fclose(fp);
+               return FALSE;
+       }
+
+       rewind(fp);
+       *data = (void *)calloc(1, len);
+       if (*data == NULL) {
+               fprintf(stderr, "\tmemory allocation failed \n");
+               fclose(fp);
+               return FALSE;
+       }
+
+       *length = fread(*data, 1, (size_t)len, fp);
+       if (*length != (size_t)len) {
+               fprintf(stderr, "\tfread failed \n");
+       }
+
+       fclose(fp);
+
+       if (*data == NULL) {
+               *length = 0;
+               return FALSE;
+       }
+
+       *length = (size_t)len;
+
+       fprintf(stderr, "\t%s %zu read DONE\n", path, *length);
+
+       return TRUE;
+}
+
+static gboolean __write_file(const char *path, void *data, size_t length)
+{
+       FILE *fp = NULL;
+       size_t len = 0;
+
+       if (!path || !data || length == 0) {
+               g_printf("\tinvalid data %s %p %zu\n", path, data, length);
+               return FALSE;
+       }
+
+       g_printf("\t%s %p %zu write\n", path, data, length);
+
+       fp = fopen(path, "w");
+       if (fp == NULL) {
+               g_printf("\tfopen failed (%d) \n", errno);
+               return FALSE;
+       }
+
+       len = fwrite(data, 1, length, fp);
+       if (len != length) {
+               g_printf("\tfwrite failed \n");
+       }
+
+       fclose(fp);
+       fp = NULL;
+
+       g_printf("\t%s write DONE\n", path);
+
+       return TRUE;
+}
+
+static gboolean __save_image(image_h image)
+{
+       int ret = IMAGE_UTIL_ERROR_NONE;
+       char out_file[PATH_MAX] = { 0, };
+
+       unsigned int width = 0, height = 0;
+       image_util_colorspace_e color = 0;
+       unsigned char *buf = NULL;
+       size_t buf_size = 0;
+
+       ret = image_util_get_image(image, &width, &height, &color, &buf, &buf_size);
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               g_printf("image_util_get_image failed (%d)", ret);
+               return FALSE;;
+       }
+
+       snprintf(out_file, PATH_MAX, "result2_%dx%d_%d.raw", width, height, color);
+
+       if (!__write_file(out_file, (void *)buf, buf_size))
+               g_printf("__write_file failed");
+
+       IMAGE_UTIL_SAFE_FREE(buf);
+
+       return TRUE;
+}
+
+void test_transform_completed2_cb(image_h image, image_util_error_e error, void *user_data)
+{
+       g_printf("completed_cb [%d][%d] \n", error, --g_request_count);
+
+       if (error != IMAGE_UTIL_ERROR_NONE) {
+               g_printf("Invalid error_code (%d)", error);
+               goto END;
+       }
+
+       if (!image) {
+               g_printf("Invalid image");
+               goto END;
+       }
+
+       if (!__save_image(image))
+               g_printf("_save_image failed");
+
+       g_printf("<<<<< SUCCESS >>>>>\n");
+END:
+       if (g_request_count == 0)
+               display_menu();
+}
+
+static gboolean __create_src_image()
+{
+       int ret = 0;
+       void *buf = NULL;
+       size_t buf_size = 0;
+
+       if (!__read_file(g_path, &buf, &buf_size)) {
+               g_printf("__read_file failed\n");
+               return FALSE;
+       }
+
+       ret = image_util_create_image(g_width, g_height, g_format, buf, buf_size, &g_src_image);
+       IMAGE_UTIL_SAFE_FREE(buf);
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               g_printf("image_util_create_image failed (%d)", ret);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+void test_transform_completed_cb(media_packet_h *packet, image_util_error_e error, void *user_data)
 {
        uint64_t size = 0;
        char output_file[25] = {};
@@ -139,104 +272,84 @@ bool test_transform_completed_cb(media_packet_h *packet, image_util_error_e erro
        media_format_mimetype_e dst_mimetype;
        int dst_width, dst_height, dst_avg_bps, dst_max_bps;
        char *output_fmt = NULL;
+       void *dst = NULL;
 
-       g_printf("test_transform_completed_cb============= [%d] \n", error);
-       if (error == IMAGE_UTIL_ERROR_NONE) {
-               g_printf("<<<<< SUCCESS >>>>>\n");
-               output_fmt = (char *)malloc(sizeof(char) * IMAGE_FORMAT_LABEL_BUFFER_SIZE);
-               if (output_fmt) {
-                       if (media_packet_get_format(*packet, &dst_fmt) != MEDIA_PACKET_ERROR_NONE) {
-                               g_printf("Imedia_packet_get_format");
-                               _signal();
-                               IMAGE_UTIL_SAFE_FREE(output_fmt);
-                               return FALSE;
-                       }
+       g_printf("test_transform_completed_cb [%d][%d] \n", error, --g_request_count);
+       if (error != IMAGE_UTIL_ERROR_NONE) {
+               goto END;
+       }
 
-                       if (media_format_get_video_info(dst_fmt, &dst_mimetype, &dst_width, &dst_height, &dst_avg_bps, &dst_max_bps) == MEDIA_FORMAT_ERROR_NONE) {
-                               memset(output_fmt, 0, IMAGE_FORMAT_LABEL_BUFFER_SIZE);
-                               if (dst_mimetype  == MEDIA_FORMAT_YV12 || dst_mimetype == MEDIA_FORMAT_422P || dst_mimetype == MEDIA_FORMAT_I420
-                                   || dst_mimetype == MEDIA_FORMAT_NV12 || dst_mimetype == MEDIA_FORMAT_UYVY || dst_mimetype == MEDIA_FORMAT_YUYV) {
-                                       strncpy(output_fmt, "yuv", strlen("yuv"));
-                               } else {
-                                       strncpy(output_fmt, "rgb", strlen("rgb"));
-                               }
-                               g_printf("[mimetype: %d] W x H : %d x %d \n", dst_mimetype, dst_width, dst_height);
-                               snprintf(output_file, 25, "result_%dx%d.%s", dst_width, dst_height, output_fmt);
-                       }
-               }
+       output_fmt = (char *)malloc(sizeof(char) * IMAGE_FORMAT_LABEL_BUFFER_SIZE);
+       if (!output_fmt) {
+               g_printf("memory allocation failed");
+               goto END;
+       }
 
-               FILE *fpout = fopen(output_file, "w");
-               if (fpout) {
-                       void *dst = NULL;
-                       if(media_packet_get_buffer_size(*packet, &size) != MEDIA_PACKET_ERROR_NONE)
-                               g_printf("Fail to media_packet_get_buffer_size \n");
-
-                       if (media_packet_get_buffer_data_ptr(*packet, &dst) != MEDIA_PACKET_ERROR_NONE) {
-                               IMAGE_UTIL_SAFE_FREE(dst);
-                               IMAGE_UTIL_SAFE_FREE(output_fmt);
-                               fclose(fpout);
-                               g_printf("[dst] media_packet_get_extra \n");
-                               _signal();
-                               return FALSE;
-                       }
-                       //g_printf("dst: %p [%llu] \n", dst, size);
-                       fwrite(dst, 1, size, fpout);
-                       g_printf("FREE \n");
-                       fclose(fpout);
+       if (media_packet_get_format(*packet, &dst_fmt) != MEDIA_PACKET_ERROR_NONE) {
+               g_printf("Imedia_packet_get_format");
+               goto END;
+       }
+
+       if (media_format_get_video_info(dst_fmt, &dst_mimetype, &dst_width, &dst_height, &dst_avg_bps, &dst_max_bps) == MEDIA_FORMAT_ERROR_NONE) {
+               memset(output_fmt, 0, IMAGE_FORMAT_LABEL_BUFFER_SIZE);
+               if (dst_mimetype  == MEDIA_FORMAT_YV12 || dst_mimetype == MEDIA_FORMAT_422P || dst_mimetype == MEDIA_FORMAT_I420
+                   || dst_mimetype == MEDIA_FORMAT_NV12 || dst_mimetype == MEDIA_FORMAT_UYVY || dst_mimetype == MEDIA_FORMAT_YUYV) {
+                       strncpy(output_fmt, "yuv", strlen("yuv"));
+               } else {
+                       strncpy(output_fmt, "rgb", strlen("rgb"));
                }
+               g_printf("[mimetype: %d] W x H : %d x %d \n", dst_mimetype, dst_width, dst_height);
+               snprintf(output_file, 25, "result_%dx%d.%s", dst_width, dst_height, output_fmt);
+       }
 
-               g_printf("Result is written to %s\n", output_file);
-               g_printf("Free (output_fmt) \n");
-               IMAGE_UTIL_SAFE_FREE(output_fmt);
-       } else {
-               g_printf("<<<<< ERROR >>>>> complete cb");
-               _signal();
-               return FALSE;
+       if (media_packet_get_buffer_size(*packet, &size) != MEDIA_PACKET_ERROR_NONE)
+               g_printf("Fail to media_packet_get_buffer_size \n");
+
+       if (media_packet_get_buffer_data_ptr(*packet, &dst) != MEDIA_PACKET_ERROR_NONE) {
+               IMAGE_UTIL_SAFE_FREE(dst);
+               g_printf("[dst] media_packet_get_extra \n");
+               goto END;
+       }
+       if (!__write_file(output_file, dst, size)) {
+               g_printf("__write_file failed");
+               goto END;
        }
+       g_printf("<<<<< SUCCESS >>>>>\n");
 
-       media_packet_destroy(*packet);
+END:
 
-       _signal();
+       IMAGE_UTIL_SAFE_FREE(output_fmt);
+       media_packet_destroy(*packet);
 
-       return TRUE;
+       if (g_request_count == 0)
+               display_menu();
 }
 
-static int
-create_media_packet()
+static gboolean __create_src_packet()
 {
        int ret = 0;
        media_format_h fmt;
-       void *src = NULL;
+       void *buf = NULL;
+       size_t buf_size = 0;
        void *ptr = NULL;
+       uint64_t ptr_size = 0;
        if (media_format_create(&fmt) == MEDIA_FORMAT_ERROR_NONE) {
                if (media_format_set_video_mime(fmt, _image_util_mapping_imgp_format_to_mime(g_format)) != MEDIA_FORMAT_ERROR_NONE) {
                        media_format_unref(fmt);
                        g_printf("[Error] Set - video mime\n");
-                       return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+                       return FALSE;
                }
 
                if (media_format_set_video_width(fmt, g_width) != MEDIA_FORMAT_ERROR_NONE) {
                        media_format_unref(fmt);
                        g_printf("[Error] Set - video width\n");
-                       return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+                       return FALSE;
                }
 
                if (media_format_set_video_height(fmt, g_height) != MEDIA_FORMAT_ERROR_NONE) {
                        media_format_unref(fmt);
                        g_printf("[Error] Set - video heigh\nt");
-                       return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
-               }
-
-               if (media_format_set_video_avg_bps(fmt, 2000000) != MEDIA_FORMAT_ERROR_NONE) {
-                       media_format_unref(fmt);
-                       g_printf("[Error] Set - video avg bps\n");
-                       return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
-               }
-
-               if (media_format_set_video_max_bps(fmt, 15000000) != MEDIA_FORMAT_ERROR_NONE) {
-                       media_format_unref(fmt);
-                       g_printf("[Error] Set - video max bps\n");
-                       return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
+                       return FALSE;
                }
 
                g_printf("media_format_set_video_info success! file[%s] w[%d] h[%d] mime[%d]\n", g_path, g_width, g_height, _image_util_mapping_imgp_format_to_mime(g_format));
@@ -244,44 +357,33 @@ create_media_packet()
                g_printf("media_format_create failed...");
        }
 
-       ret = media_packet_create_alloc(fmt, NULL, NULL, &g_src);
+       ret = media_packet_create_alloc(fmt, NULL, NULL, &g_src_packet);
        if (ret == MEDIA_PACKET_ERROR_NONE) {
                g_printf("Success - media_packet_create_alloc\n");
-               uint64_t size = 0;
-               size_t readed = 0;
-
-               if (media_packet_get_buffer_size(g_src, &size) == MEDIA_PACKET_ERROR_NONE) {
-                       if (media_packet_get_buffer_data_ptr(g_src, &ptr) == MEDIA_PACKET_ERROR_NONE) {
-                               FILE *fp = fopen(g_path, "r");
-                               if (fp == NULL) {
-                                       g_printf("\tfile open failed %d\n", errno);
-                                       return IMAGE_UTIL_ERROR_NO_SUCH_FILE;
-                               }
-                               src = malloc(size);
-                               if (src == NULL) {
-                                       g_printf("\tmemory allocation failed\n");
-                                       fclose(fp);
-                                       return IMAGE_UTIL_ERROR_NO_SUCH_FILE;
+               if (media_packet_get_buffer_size(g_src_packet, &ptr_size) == MEDIA_PACKET_ERROR_NONE) {
+                       if (media_packet_get_buffer_data_ptr(g_src_packet, &ptr) == MEDIA_PACKET_ERROR_NONE) {
+                               if (!__read_file(g_path, &buf, &buf_size)) {
+                                       g_printf("\t__read_file failed\n");
+                                       media_format_unref(fmt);
+                                       return FALSE;
                                }
-                               readed = fread(src, 1, (size_t)size, fp);
-                               if (readed <= size) {
+                               if (buf_size <= ptr_size) {
                                        g_printf("#Success# fread\n");
-                                       memcpy(ptr, src, (int)size);
+                                       memcpy(ptr, buf, (int)ptr_size);
                                        g_printf("memcpy\n");
                                } else {
-                                       g_printf("#Error# fread readed[%zu] size[%" PRIu64 "]\n", readed, size);
+                                       g_printf("#Error# fread readed[%zu] size[%" PRIu64 "]\n", buf_size, ptr_size);
                                }
-                               fclose(fp);
-                               IMAGE_UTIL_SAFE_FREE(src);
+                               IMAGE_UTIL_SAFE_FREE(buf);
                        }
                }
        } else {
-               media_format_unref(fmt);
                g_printf("ERROR - media_packet_create_alloc");
-               return ret;
+               media_format_unref(fmt);
+               return FALSE;
        }
        media_format_unref(fmt);
-       return ret;
+       return TRUE;
 }
 
 static void _create()
@@ -299,20 +401,7 @@ static void _create()
                g_printf("[%d]Error image_util_transform_create [%d]\n", __LINE__, ret);
        else
                g_printf("[%d]Success image_util_transform_create [%d]\n", __LINE__, ret);
-}
-
-static void _set_image()
-{
-       int ret = 0;
-       if (g_src) {
-               media_packet_destroy(g_src);
-               g_printf("[%d]Success source packet is destroyed \n", __LINE__);
-       }
-       ret = create_media_packet();
-       if (ret == MEDIA_PACKET_ERROR_NONE)
-               g_printf("Success - Create_media_packet\n");
-       else
-               g_printf("Error - Create_media_packet\n");
+       g_request_count = 0;
 }
 
 static void _destroy()
@@ -383,23 +472,53 @@ static void _transform(const char *cmd)
        }
 
        if (!strcmp("run", cmd)) {
-               ret = image_util_transform_run(g_handle, g_src, (image_util_transform_completed_cb)test_transform_completed_cb, NULL);
+               ret = image_util_transform_run(g_handle, g_src_packet, (image_util_transform_completed_cb)test_transform_completed_cb, NULL);
                if (ret != IMAGE_UTIL_ERROR_NONE) {
                        g_printf("[%d]Error image_util_transform_run [%d]\n", __LINE__, ret);
                        return;
                }
-               _wait();
+               g_request_count++;
        }
 
+       if (!strcmp("run2", cmd)) {
+               image_h transformed_image = NULL;
+
+               ret = image_util_transform_run2(g_handle, g_src_image, &transformed_image);
+               if (ret != IMAGE_UTIL_ERROR_NONE) {
+                       g_printf("[%d]Error image_util_transform_run2 [%d]\n", __LINE__, ret);
+                       return;
+               }
+               __save_image(transformed_image);
+               g_printf("<<<<< SUCCESS >>>>>\n");
+       }
+
+       if (!strcmp("run2_async", cmd)) {
+               ret = image_util_transform_run2_async(g_handle, g_src_image, (image_util_transform_completed2_cb)test_transform_completed2_cb, NULL);
+               if (ret != IMAGE_UTIL_ERROR_NONE) {
+                       g_printf("[%d]Error image_util_transform_run2_async [%d]\n", __LINE__, ret);
+                       return;
+               }
+               g_request_count++;
+       }
 }
 
-static void _loop_test(const int count)
+static void _async_test()
 {
        int i = 0;
-       for (i = 0; i < count; i++) {
+       g_request_count = 0;
+       for (i = 0; i < MAX_REPEAT_COUNT; i++) {
                _transform("run");
-               _set_image();
-               g_printf("<<<<< %03d >>>>>\n", i);
+               g_printf("<<<<< %03d >>>>>\n", g_request_count);
+       }
+}
+
+static void _async_test2()
+{
+       int i = 0;
+       g_request_count = 0;
+       for (i = 0; i < MAX_REPEAT_COUNT; i++) {
+               _transform("run2_async");
+               g_printf("<<<<< %03d >>>>>\n", g_request_count);
        }
 }
 
@@ -430,22 +549,6 @@ static void display_set_rotation_parameter_menu(void)
        g_print("====================================================\n");
 }
 
-static void display_set_image_menu(void)
-{
-       g_print("\n");
-       g_print("====================================================\n");
-       g_print("    image-util Core-API test: Main menu v0.2\n");
-       g_print("----------------------------------------------------\n");
-       g_print("1. set image path \n");
-       g_print("2. set image width \n");
-       g_print("3. set image height \n");
-       g_print("4. set image format \n");
-       g_print("0. back \n");
-       g_print("----------------------------------------------------\n");
-       g_print("====================================================\n");
-
-}
-
 static void display_menu(void)
 {
        g_print("\n");
@@ -453,14 +556,16 @@ static void display_menu(void)
        g_print("   image-util Core-API test: Main menu v0.2\n");
        g_print("----------------------------------------------------\n");
        g_print("1. create handle \n");
-       g_print("2. set image \n");
-       g_print("3. set convert \n");
-       g_print("4. set crop \n");
-       g_print("5. set resize \n");
-       g_print("6. set rotate \n");
-       g_print("7. run \n");
-       g_print("8. run repeatly \n");
+       g_print("2. set convert \n");
+       g_print("3. set crop \n");
+       g_print("4. set resize \n");
+       g_print("5. set rotate \n");
+       g_print("6. run \n");
+       g_print("7. run2 \n");
+       g_print("8. run2_async \n");
        g_print("9. destroy handle \n");
+       g_print("11. run %d times \n", MAX_REPEAT_COUNT);
+       g_print("12. run2_async %d times \n", MAX_REPEAT_COUNT);
        g_print("0. quit \n");
        g_print("----------------------------------------------------\n");
        g_print("====================================================\n");
@@ -478,58 +583,6 @@ static void interpret_rotation_parameter_cmd(char *cmd)
        g_angle = choice;
 }
 
-static void interpret_set_image_cmd(char *cmd)
-{
-       int len = strlen(cmd);
-       if (g_menu_set_image_state == CURRENT_STATE_SET_IMAGE_NONE) {
-               if (len == 1) {
-                       if (!strncmp(cmd, "1", len)) {
-                               g_menu_set_image_state = CURRENT_STATE_SET_IMAGE_PATH;
-                               g_print("Path: ");
-                       } else if (!strncmp(cmd, "2", len)) {
-                               g_menu_set_image_state = CURRENT_STATE_SET_IMAGE_WIDTH;
-                               g_print("Width: ");
-                       } else if (!strncmp(cmd, "3", len)) {
-                               g_menu_set_image_state = CURRENT_STATE_SET_IMAGE_HEIGHT;
-                               g_print("height: ");
-                       } else if (!strncmp(cmd, "4", len)) {
-                               g_menu_set_image_state = CURRENT_STATE_SET_IMAGE_FORMAT;
-                               g_print("Format: ");
-                       } else if (!strncmp(cmd, "0", len)) {
-                               _set_image();
-                               reset_current_menu_state();
-                               display_menu();
-                       }
-               } else {
-                       g_print("wrong command\n");
-                       display_set_image_menu();
-               }
-       } else if (g_menu_set_image_state == CURRENT_STATE_SET_IMAGE_PATH) {
-               IMAGE_UTIL_SAFE_FREE(g_path);
-               g_path = (char *)g_malloc(MAX_STRING_LEN * sizeof(char));
-               if (g_path == NULL) {
-                       g_printf("memory allocation fail. \n");
-                       return;
-               }
-               memset(g_path, 0x00, MAX_STRING_LEN);
-               snprintf(g_path, MAX_STRING_LEN, "%s", cmd);
-               g_menu_set_image_state = CURRENT_STATE_SET_IMAGE_NONE;
-               display_set_image_menu();
-       } else if (g_menu_set_image_state == CURRENT_STATE_SET_IMAGE_WIDTH) {
-               g_width = atoi(cmd);
-               g_menu_set_image_state = CURRENT_STATE_SET_IMAGE_NONE;
-               display_set_image_menu();
-       } else if (g_menu_set_image_state == CURRENT_STATE_SET_IMAGE_HEIGHT) {
-               g_height = atoi(cmd);
-               g_menu_set_image_state = CURRENT_STATE_SET_IMAGE_NONE;
-               display_set_image_menu();
-       } else if (g_menu_set_image_state == CURRENT_STATE_SET_IMAGE_FORMAT) {
-               g_format = atoi(cmd);
-               g_menu_set_image_state = CURRENT_STATE_SET_IMAGE_NONE;
-               display_set_image_menu();
-       }
-}
-
 static void interpret_cmd(char *cmd)
 {
        int len = strlen(cmd);
@@ -538,36 +591,43 @@ static void interpret_cmd(char *cmd)
                        if (!strncmp(cmd, "1", len)) {
                                _create();
                        } else if (!strncmp(cmd, "2", len)) {
-                               g_menu_state = CURRENT_STATE_SET_IMAGE_MENU;
-                               g_menu_set_image_state = CURRENT_STATE_SET_IMAGE_NONE;
-                               display_set_image_menu();
-                               return;
-                       } else if (!strncmp(cmd, "3", len)) {
                                _transform("convert");
-                       } else if (!strncmp(cmd, "4", len)) {
+                       } else if (!strncmp(cmd, "3", len)) {
                                _transform("crop");
-                       } else if (!strncmp(cmd, "5", len)) {
+                       } else if (!strncmp(cmd, "4", len)) {
                                _transform("resize");
-                       } else if (!strncmp(cmd, "6", len)) {
+                       } else if (!strncmp(cmd, "5", len)) {
                                g_menu_state = CURRENT_STATE_SET_ROTATION_PARAMETER_MENU;
                                display_set_rotation_parameter_menu();
                                return;
-                       } else if (!strncmp(cmd, "7", len)) {
+                       } else if (!strncmp(cmd, "6", len)) {
                                _transform("run");
+                               return;
+                       } else if (!strncmp(cmd, "7", len)) {
+                               _transform("run2");
                        } else if (!strncmp(cmd, "8", len)) {
-                               _loop_test(IMAGE_TEST_MAX_REPEAT_COUNT);
+                               _transform("run2_async");
+                               return;
                        } else if (!strncmp(cmd, "9", len)) {
                                _destroy();
                        } else if (!strncmp(cmd, "0", len)) {
                                quit();
                        }
+               } else if (len == 2) {
+                       if (!strncmp(cmd, "11", len)) {
+                               _async_test();
+                               return;
+                       } else if (!strncmp(cmd, "12", len)) {
+                               _async_test2();
+                               return;
+                       } else {
+                               g_print("wrong command\n");
+                       }
                } else {
                        g_print("wrong command\n");
                }
 
                display_menu();
-       } else if (g_menu_state == CURRENT_STATE_SET_IMAGE_MENU) {
-               interpret_set_image_cmd(cmd);
        } else if (g_menu_state == CURRENT_STATE_SET_ROTATION_PARAMETER_MENU) {
                interpret_rotation_parameter_cmd(cmd);
                _transform("rotate");
@@ -609,7 +669,7 @@ int main(int argc, char **argv)
        }
 
        g_handle = NULL;
-       g_src = NULL;
+       g_src_packet = NULL;
        g_path = (char *)g_malloc(MAX_STRING_LEN * sizeof(char));
        if (g_path == NULL) {
                g_printf("memory allocation fail. \n");
@@ -621,20 +681,19 @@ int main(int argc, char **argv)
        g_height = atoi(argv[3]);
        g_format = atoi(argv[4]);
 
-       g_mutex_init(&g_thread_mutex);
-       g_cond_init(&g_thread_cond);
-
        ret = image_util_transform_create(&g_handle);
        if (ret != IMAGE_UTIL_ERROR_NONE) {
                g_printf("[%d]Error image_util_transform_create [%d]\n", __LINE__, ret);
                goto Exit;
        }
 
-       ret = create_media_packet();
-       if (ret == MEDIA_PACKET_ERROR_NONE) {
-               g_printf("Success - Create_media_packet\n");
-       } else {
-               g_printf("Error - Create_media_packet\n");
+       if (!__create_src_image()) {
+               g_printf("Error - Create_src_image\n");
+               goto Exit;
+       }
+
+       if (!__create_src_packet()) {
+               g_printf("Error - Create_src_packet\n");
                goto Exit;
        }
 
@@ -646,19 +705,19 @@ int main(int argc, char **argv)
        g_main_loop_unref(g_loop);
 
 Exit:
-       g_mutex_clear(&g_thread_mutex);
-       g_cond_clear(&g_thread_cond);
        if (g_path) {
                IMAGE_UTIL_SAFE_FREE(g_path);
                g_printf("[%d]Success file path is destroyed \n", __LINE__);
-       } else {
-               g_printf("[%d]Error file path was already destroyed \n", __LINE__);
        }
-       if (g_src) {
-               media_packet_destroy(g_src);
+
+       if (g_src_image) {
+               image_util_destroy_image(g_src_image);
+               g_printf("[%d]Success source image is destroyed \n", __LINE__);
+       }
+
+       if (g_src_packet) {
+               media_packet_destroy(g_src_packet);
                g_printf("[%d]Success source packet is destroyed \n", __LINE__);
-       } else {
-               g_printf("[%d]Error source packet was already destroyed \n", __LINE__);
        }
        _destroy();