From c9d76062fab4d3dace2217939514b4498a9f8257 Mon Sep 17 00:00:00 2001 From: hj kim Date: Mon, 8 Oct 2018 16:36:39 +0900 Subject: [PATCH] Get transform code from libmm-utility except gstreamer related code Change-Id: Iedb0f4b1e672a33ffe5b3064edd8f556d9aa3ebe --- src/image_util.c | 338 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 320 insertions(+), 18 deletions(-) diff --git a/src/image_util.c b/src/image_util.c index 81c908b..ebd67dc 100755 --- a/src/image_util.c +++ b/src/image_util.c @@ -113,6 +113,308 @@ static int __create_media_format(media_format_mimetype_e mimetype, unsigned int return IMAGE_UTIL_ERROR_NONE; } +static void __mm_util_destroy_color_image(mm_util_color_image_h image) +{ + mm_image_info_s *_color_image = (mm_image_info_s *)image; + + if (_color_image == NULL) { + image_util_error("[ERROR] - image"); + return; + } + + IMAGE_UTIL_SAFE_FREE(_color_image->data); + IMAGE_UTIL_SAFE_FREE(_color_image); +} + +static int __mm_util_create_color_image(mm_util_color_image_h *image, unsigned long width, unsigned long height, mm_util_color_format_e color, void *data, size_t size) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + mm_image_info_s *_color_image = NULL; + + image_util_retvm_if((image == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle"); + image_util_retvm_if((color >= MM_UTIL_COLOR_NUM), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid color"); + image_util_retvm_if((data == NULL || size == 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid data"); + + _color_image = (mm_image_info_s *)calloc(1, sizeof(mm_image_info_s)); + image_util_retvm_if((_color_image == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Memory allocation failed"); + + _color_image->data = calloc(1, size); + if (_color_image->data == NULL) { + image_util_error("Memory allocation failed"); + __mm_util_destroy_color_image(_color_image); + *image = NULL; + return IMAGE_UTIL_ERROR_OUT_OF_MEMORY; + } + + memcpy(_color_image->data, data, size); + + _color_image->size = size; + _color_image->width = width; + _color_image->height = height; + _color_image->color = color; + + image_util_debug("w [%lu], h [%lu], color [%u], size [%zu], data [%p]", _color_image->width, _color_image->height, _color_image->color, _color_image->size, _color_image->data); + + *image = (mm_util_color_image_h)_color_image; + + return ret; +} + +static int __mm_util_get_color_image(mm_util_color_image_h image, unsigned long *width, unsigned long *height, mm_util_color_format_e *color, void **data, size_t *size) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + mm_image_info_s *_color_image = (mm_image_info_s *)image; + + image_util_retvm_if((_color_image == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid handle"); + + if (width != NULL) + *width = _color_image->width; + + if (height != NULL) + *height = _color_image->height; + + if (color != NULL) + *color = _color_image->color; + + if (data != NULL) + *data = _color_image->data; + + if (size != NULL) + *size = _color_image->size; + + return ret; +} + +static void __mm_destroy_temp_buffer(unsigned char *buffer[]) +{ + int i = 0; + + for (i = 0; i < 4; i++) + IMAGE_UTIL_SAFE_FREE(buffer[i]); +} + +static int __mm_util_processing(mm_util_s *handle) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + unsigned char *dst_buf[4] = {NULL,}; + unsigned int src_width = 0, src_height = 0; + mm_util_color_format_e src_format = -1; + unsigned int src_index = 0, dst_index = 0; + unsigned int res_w = 0; + unsigned int res_h = 0; + unsigned char *res_buffer = NULL; + unsigned char *res_buffer_conv = NULL; + unsigned char *res_buffer_rotate = NULL; + size_t res_buffer_size = 0; + + image_util_retvm_if(handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "invalid handle"); + + image_util_debug("src: %p, dst: %p", handle->src, handle->dst); + + dst_buf[src_index] = calloc(1, handle->src->size); + src_width = handle->src->width; + src_height = handle->src->height; + src_format = handle->src->color; + if (dst_buf[src_index] == NULL) { + image_util_error("[multi func] memory allocation error"); + return IMAGE_UTIL_ERROR_INVALID_OPERATION; + } + memcpy(dst_buf[src_index], handle->src->data, handle->src->size); + + if (handle->set_crop) { + dst_index++; + + ret = mm_util_crop_image(dst_buf[src_index], src_width, src_height, src_format, handle->start_x, handle->start_y, handle->dst_width, handle->dst_height, &res_buffer, &res_w, &res_h, &res_buffer_size); + if (ret != MM_UTIL_ERROR_NONE) { + __mm_destroy_temp_buffer(dst_buf); + image_util_error("mm_util_crop_image failed"); + return _image_error_capi(ERR_TYPE_TRANSFORM, ret); + } + + dst_buf[dst_index] = res_buffer; + src_index = dst_index; + src_width = res_w; + src_height = res_h; + } else if (handle->set_resize) { + dst_index++; + + ret = mm_util_resize_image(dst_buf[src_index], src_width, src_height, src_format, handle->dst_width, handle->dst_height, &res_buffer, &res_w, &res_h, &res_buffer_size); + if (ret != MM_UTIL_ERROR_NONE) { + __mm_destroy_temp_buffer(dst_buf); + image_util_error("mm_util_resize_image failed"); + return _image_error_capi(ERR_TYPE_TRANSFORM, ret); + } + + dst_buf[dst_index] = res_buffer; + src_index = dst_index; + src_width = res_w; + src_height = res_h; + } + + if (handle->set_convert) { + dst_index++; + + ret = mm_util_convert_colorspace(dst_buf[src_index], src_width, src_height, src_format, handle->dst_format, &res_buffer_conv, &res_w, &res_h, &res_buffer_size); + if (ret != MM_UTIL_ERROR_NONE) { + __mm_destroy_temp_buffer(dst_buf); + image_util_error("mm_util_convert_colorspace failed"); + return _image_error_capi(ERR_TYPE_TRANSFORM, ret); + } + + dst_buf[dst_index] = res_buffer_conv; + src_index = dst_index; + src_format = handle->dst_format; + src_width = res_w; + src_height = res_h; + } + + if (handle->set_rotate) { + dst_index++; + + ret = mm_util_rotate_image(dst_buf[src_index], src_width, src_height, src_format, handle->rotation, &res_buffer_rotate, &res_w, &res_h, &res_buffer_size); + if (ret != MM_UTIL_ERROR_NONE) { + __mm_destroy_temp_buffer(dst_buf); + image_util_error("mm_util_rotate_image failed"); + return _image_error_capi(ERR_TYPE_TRANSFORM, ret); + } + + dst_buf[dst_index] = res_buffer_rotate; + src_index = dst_index; + src_width = res_w; + src_height = res_h; + } + + if (dst_buf[dst_index] != NULL && res_buffer_size != 0) { + ret = __mm_util_create_color_image((mm_util_color_image_h *)&(handle->dst), (unsigned long)src_width, (unsigned long)src_height, src_format, (void *)dst_buf[dst_index], res_buffer_size); + if (ret != IMAGE_UTIL_ERROR_NONE) + image_util_error("__mm_util_create_color_image failed"); + } else { + image_util_error("invalid result %p %zu", dst_buf[dst_index], res_buffer_size); + ret = IMAGE_UTIL_ERROR_INVALID_OPERATION; + } + __mm_destroy_temp_buffer(dst_buf); + + image_util_error("mm_util_processing was finished"); + + return ret; +} + +static int __mm_util_transform_exec(mm_util_s *handle, mm_image_info_s *source_image) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + + image_util_retvm_if(handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "invalid handle"); + image_util_retvm_if(source_image == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "invalid source_image"); + + image_util_debug("orig_image: %p [%zu] %lu X %lu (%u)", source_image->data, source_image->size, + source_image->width, source_image->height, source_image->color); + + handle->src = source_image; + handle->dst = NULL; + + ret = __mm_util_processing(handle); + image_util_retvm_if(ret != IMAGE_UTIL_ERROR_NONE, ret, "__mm_util_processing failed [%d]", ret); + + image_util_debug("result_image: %p [%zu] %lu X %lu (%u)", handle->dst->data, handle->dst->size, + handle->dst->width, handle->dst->height, handle->dst->color); + + return ret; +} + +gpointer __mm_util_thread_repeate(gpointer data) +{ + mm_util_s *handle = (mm_util_s *) data; + int ret = IMAGE_UTIL_ERROR_NONE; + mm_util_color_image_h pop_data = NULL; + + image_util_retvm_if(handle == NULL, NULL, "invalid handle"); + + while (!handle->is_finish) { + image_util_debug("waiting..."); + pop_data = (mm_util_color_image_h)g_async_queue_timeout_pop(handle->queue, 300 * G_TIME_SPAN_MILLISECOND); + image_util_debug("get from data or timeout"); + + if (pop_data == NULL) { + image_util_error("The data is null"); + continue; + } + + ret = __mm_util_transform_exec(handle, (mm_image_info_s *)pop_data); /* Need to block */ + if (ret == IMAGE_UTIL_ERROR_NONE) + image_util_debug("Success - transform_exec"); + else + image_util_error("Error - transform_exec"); + + if (handle->_util_cb->completed_cb) { + image_util_debug("completed_cb is called"); + handle->_util_cb->completed_cb(handle->dst, ret, handle->_util_cb->user_data); + } + __mm_util_destroy_color_image(pop_data); + __mm_util_destroy_color_image(handle->dst); + handle->is_completed = FALSE; + } + + image_util_debug("exit thread"); + handle->thread = NULL; + + return NULL; +} + +static int __mm_util_create_thread(mm_util_s *handle) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + + image_util_retvm_if(handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "invalid handle"); + image_util_retvm_if(handle->thread != NULL, IMAGE_UTIL_ERROR_NONE, "[NO-ERROR] Thread is already created"); + + /*create threads*/ + handle->thread = g_thread_new("transform_thread", (GThreadFunc)__mm_util_thread_repeate, (gpointer)handle); + image_util_retvm_if(handle->thread == NULL, IMAGE_UTIL_ERROR_INVALID_OPERATION, "ERROR - create thread"); + + image_util_debug("New thread is created"); + + return ret; +} + +static int __mm_util_transform(mm_util_imgp_h imgp_handle, mm_util_color_image_h image, mm_util_completed_callback completed_callback, void *user_data) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + mm_util_s *handle = (mm_util_s *) imgp_handle; + + image_util_fenter(); + + image_util_retvm_if(handle == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "invalid handle"); + image_util_retvm_if(image == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "invalid image"); + image_util_retvm_if(completed_callback == NULL, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "invalid completed_callback"); + + image_util_debug("image: %p", image); + + IMAGE_UTIL_SAFE_FREE(handle->_util_cb); + handle->_util_cb = (mm_util_cb_s *)calloc(1, sizeof(mm_util_cb_s)); + if (handle->_util_cb) { + handle->_util_cb->completed_cb = completed_callback; + handle->_util_cb->user_data = user_data; + } else { + image_util_error("[ERROR] _util_cb_s"); + } + + if (handle->queue) { + image_util_debug("g_async_queue_push"); + g_async_queue_push(handle->queue, GINT_TO_POINTER(image)); + ret = __mm_util_create_thread(handle); + if (ret != IMAGE_UTIL_ERROR_NONE) { + image_util_error("ERROR - Create thread"); + return ret; + } else { + image_util_debug("Success -__mm_util_create_thread"); + } + } + + image_util_fleave(); + + return ret; +} + static int _image_util_packet_to_image(media_packet_h packet, mm_util_color_image_h *color_image) { int err = IMAGE_UTIL_ERROR_NONE; @@ -146,8 +448,8 @@ static int _image_util_packet_to_image(media_packet_h packet, mm_util_color_imag 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_util_create_color_image(color_image, (unsigned long)width, (unsigned long)height, __mimetype_to_image_format(mimetype), ptr, (size_t)size); - image_util_retvm_if((err != MM_UTIL_ERROR_NONE), _image_error_capi(ERR_TYPE_TRANSFORM, err), "mm_util_create_color_image failed (%d)", err); + err = __mm_util_create_color_image(color_image, (unsigned long)width, (unsigned long)height, __mimetype_to_image_format(mimetype), ptr, (size_t)size); + image_util_retvm_if((err != IMAGE_UTIL_ERROR_NONE), err, "__mm_util_create_color_image failed (%d)", err); image_util_debug("_image_util_packet_to_image succeed"); @@ -166,8 +468,8 @@ static int _image_util_image_to_packet(mm_util_color_image_h image, media_packet uint64_t packet_size = 0; size_t size = 0; - err = mm_util_get_color_image(image, &width, &height, &format, &buffer, &buffer_size); - image_util_retvm_if((err != MM_UTIL_ERROR_NONE), _image_error_capi(ERR_TYPE_TRANSFORM, err), "mm_util_get_color_image failed (%d)", err); + err = __mm_util_get_color_image(image, &width, &height, &format, &buffer, &buffer_size); + image_util_retvm_if((err != IMAGE_UTIL_ERROR_NONE), err, "__mm_util_get_color_image failed (%d)", err); err = __create_media_format(__image_format_to_mimetype(format), (unsigned int)width, (unsigned int)height, &fmt); image_util_retvm_if((err != IMAGE_UTIL_ERROR_NONE), err, "__create_media_format failed (%d)", err); @@ -222,7 +524,7 @@ static void _image_util_transform_completed_cb(mm_util_color_image_h raw_image, if ((_util_cb != NULL) && (_util_cb->completed_cb != NULL)) { err = _image_util_image_to_packet(raw_image, &packet); - if (err != MM_UTIL_ERROR_NONE) { + if (err != IMAGE_UTIL_ERROR_NONE) { image_util_error("_image_util_image_to_packet failed (%d)", err); _util_cb->completed_cb(NULL, err, _util_cb->user_data); } else { @@ -267,7 +569,7 @@ static int _image_util_create_transform_handle(transformation_s *handle) if (_handle->queue == NULL) { image_util_error("g_async_queue_new failed"); IMAGE_UTIL_SAFE_FREE(_handle); - return MM_UTIL_ERROR_INVALID_OPERATION; + return IMAGE_UTIL_ERROR_INVALID_OPERATION; } handle->image_h = _handle; @@ -277,7 +579,7 @@ static int _image_util_create_transform_handle(transformation_s *handle) int image_util_transform_create(transformation_h * handle) { - int err = MM_UTIL_ERROR_NONE; + int err = IMAGE_UTIL_ERROR_NONE; image_util_fenter(); @@ -290,10 +592,10 @@ int image_util_transform_create(transformation_h * handle) _handle->image_h = NULL; err = _image_util_create_transform_handle(_handle); - if (err != MM_UTIL_ERROR_NONE) { + if (err != IMAGE_UTIL_ERROR_NONE) { image_util_error("Error - create transform handle"); IMAGE_UTIL_SAFE_FREE(_handle); - return MM_UTIL_ERROR_INVALID_OPERATION; + return IMAGE_UTIL_ERROR_INVALID_OPERATION; } *handle = (transformation_h) _handle; @@ -460,7 +762,7 @@ 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 completed_cb, void *user_data) { - int err = MM_UTIL_ERROR_NONE; + int err = IMAGE_UTIL_ERROR_NONE; transformation_s *_handle = (transformation_s *) handle; image_util_fenter(); @@ -479,17 +781,17 @@ int image_util_transform_run(transformation_h handle, media_packet_h src, image_ _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_util_destroy_color_image(color_image); + __mm_util_destroy_color_image(color_image); return IMAGE_UTIL_ERROR_OUT_OF_MEMORY; } _handle->_util_cb->user_data = user_data; _handle->_util_cb->completed_cb = completed_cb; - err = mm_util_transform(_handle->image_h, color_image, (mm_util_completed_callback) _image_util_transform_completed_cb, (void *)_handle->_util_cb); - if (err != MM_UTIL_ERROR_NONE) { + err = __mm_util_transform(_handle->image_h, color_image, (mm_util_completed_callback) _image_util_transform_completed_cb, (void *)_handle->_util_cb); + if (err != IMAGE_UTIL_ERROR_NONE) { image_util_error("Error - Run transform (%d)", err); - mm_util_destroy_color_image(color_image); - return _image_error_capi(ERR_TYPE_TRANSFORM, err); + __mm_util_destroy_color_image(color_image); + return err; } return IMAGE_UTIL_ERROR_NONE; @@ -522,12 +824,12 @@ int image_util_transform_destroy(transformation_h handle) image_util_fleave(); - return MM_UTIL_ERROR_NONE; + 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 = MM_UTIL_ERROR_NONE; + int err = IMAGE_UTIL_ERROR_NONE; size_t size_ptr = 0; image_util_retvm_if((is_valid_colorspace(colorspace) == FALSE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace"); @@ -543,7 +845,7 @@ int image_util_calculate_buffer_size(int width, int height, image_util_colorspac 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) { - int ret = MM_UTIL_ERROR_NONE; + int ret = IMAGE_UTIL_ERROR_NONE; image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null"); -- 2.7.4