4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: YoungHun Kim <yh8004.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
24 #include "mm_util_private.h"
25 #include "mm_util_imgp.h"
26 #include "mm_util_imgp_internal.h"
27 #include "mm_util_common.h"
29 #define MM_UTIL_ROUND_UP_2(num) (((num)+1)&~1)
30 #define MM_UTIL_ROUND_UP_4(num) (((num)+3)&~3)
31 #define MM_UTIL_ROUND_UP_8(num) (((num)+7)&~7)
32 #define MM_UTIL_ROUND_UP_16(num) (((num)+15)&~15)
33 #define GEN_MASK(x) ((1<<(x))-1)
34 #define ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) & ~GEN_MASK(x))
35 #define DIV_ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) >> (x))
38 typedef gboolean(*IMGPInfoFunc) (imgp_info_s *, const unsigned char *, unsigned char **, imgp_plugin_type_e);
39 static int __mm_util_transform_exec(mm_util_s *handle, color_image_data_s *source_image);
41 static int check_valid_picture_size(int width, int height)
43 if ((int)width > 0 && (int)height > 0 &&
44 ((width + 128) * (unsigned long long)(height + 128)) < INT_MAX/4)
45 return MM_UTIL_ERROR_NONE;
47 return MM_UTIL_ERROR_INVALID_PARAMETER;
50 static void __mm_destroy_temp_buffer(unsigned char *buffer[])
54 for (i = 0; i < 4; i++)
55 MMUTIL_SAFE_FREE(buffer[i]);
58 static gboolean __mm_gst_can_resize_format(mm_util_color_format_e color_format)
60 gboolean _bool = FALSE;
62 mm_util_debug("color_format [%d]", color_format);
64 switch (color_format) {
65 case MM_UTIL_COLOR_YUV420:
66 case MM_UTIL_COLOR_YUV422:
67 case MM_UTIL_COLOR_I420:
68 case MM_UTIL_COLOR_UYVY:
69 case MM_UTIL_COLOR_YUYV:
70 case MM_UTIL_COLOR_RGB16:
71 case MM_UTIL_COLOR_RGB24:
72 case MM_UTIL_COLOR_ARGB:
73 case MM_UTIL_COLOR_BGRA:
74 case MM_UTIL_COLOR_RGBA:
75 case MM_UTIL_COLOR_BGRX:
79 mm_util_error("Not supported format"); //only not support NV12
85 static gboolean __mm_gst_can_rotate_format(mm_util_color_format_e color_format)
87 gboolean _bool = FALSE;
89 mm_util_debug("color_format [%d]", color_format);
91 switch (color_format) {
92 case MM_UTIL_COLOR_YUV420:
93 case MM_UTIL_COLOR_I420:
94 case MM_UTIL_COLOR_RGB24:
95 case MM_UTIL_COLOR_ARGB:
96 case MM_UTIL_COLOR_BGRA:
97 case MM_UTIL_COLOR_RGBA:
101 mm_util_error("Not supported format");
107 static gboolean __mm_select_convert_plugin(mm_util_color_format_e src_format, mm_util_color_format_e dst_format)
109 gboolean _bool = FALSE;
111 mm_util_debug("src_format: %d, dst_format:%d", src_format, dst_format);
113 if (((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_NV12)) ||
114 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
115 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
116 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_ARGB)) ||
117 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_BGRA)) ||
118 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_RGBA)) ||
119 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_NV12_TILED)) ||
121 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_NV12)) ||
122 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
123 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
124 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_ARGB)) ||
125 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_BGRA)) ||
126 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_RGBA)) ||
127 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_NV12_TILED)) ||
129 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
130 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_I420)) ||
131 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
132 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
133 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_ARGB)) ||
134 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_BGRA)) ||
135 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_RGBA)) ||
137 ((src_format == MM_UTIL_COLOR_UYVY) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
138 ((src_format == MM_UTIL_COLOR_UYVY) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
140 ((src_format == MM_UTIL_COLOR_YUYV) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
141 ((src_format == MM_UTIL_COLOR_YUYV) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
142 ((src_format == MM_UTIL_COLOR_YUYV) && (dst_format == MM_UTIL_COLOR_ARGB)) ||
143 ((src_format == MM_UTIL_COLOR_YUYV) && (dst_format == MM_UTIL_COLOR_BGRA)) ||
144 ((src_format == MM_UTIL_COLOR_YUYV) && (dst_format == MM_UTIL_COLOR_RGBA)) ||
146 ((src_format == MM_UTIL_COLOR_RGB16) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
147 ((src_format == MM_UTIL_COLOR_RGB16) && (dst_format == MM_UTIL_COLOR_I420)) ||
148 ((src_format == MM_UTIL_COLOR_RGB16) && (dst_format == MM_UTIL_COLOR_NV12)) ||
150 ((src_format == MM_UTIL_COLOR_RGB24) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
151 ((src_format == MM_UTIL_COLOR_RGB24) && (dst_format == MM_UTIL_COLOR_I420)) ||
152 ((src_format == MM_UTIL_COLOR_RGB24) && (dst_format == MM_UTIL_COLOR_NV12)) ||
154 ((src_format == MM_UTIL_COLOR_ARGB) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
155 ((src_format == MM_UTIL_COLOR_ARGB) && (dst_format == MM_UTIL_COLOR_I420)) ||
156 ((src_format == MM_UTIL_COLOR_ARGB) && (dst_format == MM_UTIL_COLOR_NV12)) ||
158 ((src_format == MM_UTIL_COLOR_BGRA) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
159 ((src_format == MM_UTIL_COLOR_BGRA) && (dst_format == MM_UTIL_COLOR_I420)) ||
160 ((src_format == MM_UTIL_COLOR_BGRA) && (dst_format == MM_UTIL_COLOR_NV12)) ||
161 ((src_format == MM_UTIL_COLOR_RGBA) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
162 ((src_format == MM_UTIL_COLOR_RGBA) && (dst_format == MM_UTIL_COLOR_I420)) ||
163 ((src_format == MM_UTIL_COLOR_RGBA) && (dst_format == MM_UTIL_COLOR_NV12)) ||
164 ((src_format == MM_UTIL_COLOR_RGBA) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
166 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
167 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_I420)) ||
168 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_NV12)) ||
169 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
170 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
171 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_ARGB)) ||
172 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_BGRA)) ||
173 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_RGBA))) {
181 static gboolean __mm_select_resize_plugin(mm_util_color_format_e _format)
183 gboolean _bool = FALSE;
185 mm_util_debug("_format: %d", _format);
187 if ((_format == MM_UTIL_COLOR_UYVY) || (_format == MM_UTIL_COLOR_YUYV) ||
188 (_format == MM_UTIL_COLOR_RGBA) || (_format == MM_UTIL_COLOR_BGRX))
196 static gboolean __mm_select_rotate_plugin(mm_util_color_format_e _format)
198 mm_util_debug("_format: %d", _format);
200 if ((_format == MM_UTIL_COLOR_YUV420) || (_format == MM_UTIL_COLOR_I420) || (_format == MM_UTIL_COLOR_NV12)
201 || (_format == MM_UTIL_COLOR_RGB24 || _format == MM_UTIL_COLOR_RGB16)) {
208 static int __mm_util_get_crop_image_size(mm_util_color_format_e format, unsigned int width, unsigned int height, unsigned int *imgsize)
210 int ret = MM_UTIL_ERROR_NONE;
211 unsigned char x_chroma_shift = 0;
212 unsigned char y_chroma_shift = 0;
213 int size, w2, h2, size2;
218 mm_util_retvm_if(imgsize == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid imgsize");
219 mm_util_retvm_if(check_valid_picture_size(width, height) != MM_UTIL_ERROR_NONE, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid width and height");
224 case MM_UTIL_COLOR_I420:
225 case MM_UTIL_COLOR_YUV420:
228 stride = MM_UTIL_ROUND_UP_4(width);
229 h2 = ROUND_UP_X(height, x_chroma_shift);
231 w2 = DIV_ROUND_UP_X(width, x_chroma_shift);
232 stride2 = MM_UTIL_ROUND_UP_4(w2);
233 h2 = DIV_ROUND_UP_X(height, y_chroma_shift);
234 size2 = stride2 * h2;
235 *imgsize = size + 2 * size2;
237 case MM_UTIL_COLOR_YUV422:
238 case MM_UTIL_COLOR_YUYV:
239 case MM_UTIL_COLOR_UYVY:
240 case MM_UTIL_COLOR_NV16:
241 case MM_UTIL_COLOR_NV61:
242 stride = MM_UTIL_ROUND_UP_4(width) * 2;
243 size = stride * height;
247 case MM_UTIL_COLOR_RGB16:
249 size = stride * height;
253 case MM_UTIL_COLOR_RGB24:
255 size = stride * height;
259 case MM_UTIL_COLOR_ARGB:
260 case MM_UTIL_COLOR_BGRA:
261 case MM_UTIL_COLOR_RGBA:
262 case MM_UTIL_COLOR_BGRX:
264 size = stride * height;
269 case MM_UTIL_COLOR_NV12:
270 case MM_UTIL_COLOR_NV12_TILED:
273 stride = MM_UTIL_ROUND_UP_4(width);
274 h2 = ROUND_UP_X(height, y_chroma_shift);
276 w2 = 2 * DIV_ROUND_UP_X(width, x_chroma_shift);
277 stride2 = MM_UTIL_ROUND_UP_4(w2);
278 h2 = DIV_ROUND_UP_X(height, y_chroma_shift);
279 size2 = stride2 * h2;
280 *imgsize = size + size2;
284 mm_util_error("Not supported format");
285 return MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
288 mm_util_debug("format: %d, *imgsize: %d", format, *imgsize);
293 static int __mm_set_imgp_info_s(imgp_info_s *_imgp_info_s, mm_util_color_format_e src_format, unsigned int src_width, unsigned int src_height, mm_util_color_format_e dst_format, unsigned int dst_width, unsigned int dst_height, mm_util_img_rotate_type angle)
295 int ret = MM_UTIL_ERROR_NONE;
297 mm_util_retvm_if(_imgp_info_s == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid _imgp_info_s");
299 _imgp_info_s->src_format = src_format;
300 _imgp_info_s->src_width = src_width;
301 _imgp_info_s->src_height = src_height;
303 _imgp_info_s->dst_format = dst_format;
304 _imgp_info_s->dst_width = dst_width;
305 _imgp_info_s->dst_height = dst_height;
306 _imgp_info_s->buffer_size = 0;
307 _imgp_info_s->angle = angle;
309 mm_util_debug("src_w[%u] src_h[%u] dst_w[%u] dst_h[%u] rotation[%d]", _imgp_info_s->src_width, _imgp_info_s->src_height, _imgp_info_s->dst_width, _imgp_info_s->dst_height, _imgp_info_s->angle);
314 static GModule *__mm_util_imgp_initialize(imgp_plugin_type_e _imgp_plugin_type_e)
316 GModule *module = NULL;
319 if (_imgp_plugin_type_e == IMGP_NEON)
320 module = g_module_open(PATH_NEON_LIB, G_MODULE_BIND_LAZY);
321 else if (_imgp_plugin_type_e == IMGP_GSTCS)
322 module = g_module_open(PATH_GSTCS_LIB, G_MODULE_BIND_LAZY);
324 mm_util_retvm_if(module == NULL, NULL, "[%d] %s | %s module open failed", _imgp_plugin_type_e, PATH_NEON_LIB, PATH_GSTCS_LIB);
325 mm_util_debug("module: %p, g_module_name: %s", module, g_module_name(module));
330 static void __mm_util_imgp_finalize(GModule *module, imgp_info_s *_imgp_info_s)
333 g_module_close(module);
335 MMUTIL_SAFE_FREE(_imgp_info_s);
340 static int __mm_util_crop_rgba32(const unsigned char *src, unsigned int src_width, unsigned int src_height,
341 unsigned int crop_start_x, unsigned int crop_start_y, unsigned int crop_dest_width, unsigned int crop_dest_height, unsigned char *dst)
343 int ret = MM_UTIL_ERROR_NONE;
344 unsigned int idx = 0;
345 int src_bytesperline = src_width * 4;
346 int dst_bytesperline = crop_dest_width * 4;
348 src += crop_start_y * src_bytesperline + 4 * crop_start_x;
350 for (idx = 0; idx < crop_dest_height; idx++) {
351 memcpy(dst, src, dst_bytesperline);
352 src += src_bytesperline;
353 dst += dst_bytesperline;
359 static int __mm_util_crop_rgb888(const unsigned char *src, unsigned int src_width, unsigned int src_height,
360 unsigned int crop_start_x, unsigned int crop_start_y, unsigned int crop_dest_width, unsigned int crop_dest_height, unsigned char *dst)
362 int ret = MM_UTIL_ERROR_NONE;
363 unsigned int idx = 0;
364 int src_bytesperline = src_width * 3;
365 int dst_bytesperline = crop_dest_width * 3;
367 src += crop_start_y * src_bytesperline + 3 * crop_start_x;
369 for (idx = 0; idx < crop_dest_height; idx++) {
370 memcpy(dst, src, dst_bytesperline);
371 src += src_bytesperline;
372 dst += dst_bytesperline;
378 static int __mm_util_crop_rgb565(const unsigned char *src, unsigned int src_width, unsigned int src_height,
379 unsigned int crop_start_x, unsigned int crop_start_y, unsigned int crop_dest_width, unsigned int crop_dest_height, unsigned char *dst)
381 int ret = MM_UTIL_ERROR_NONE;
382 unsigned int idx = 0;
383 int src_bytesperline = src_width * 2;
384 int dst_bytesperline = crop_dest_width * 2;
386 src += crop_start_y * src_bytesperline + 2 * crop_start_x;
388 for (idx = 0; idx < crop_dest_height; idx++) {
389 memcpy(dst, src, dst_bytesperline);
390 src += src_bytesperline;
391 dst += dst_bytesperline;
397 static int __mm_util_crop_yuv420(const unsigned char *src, unsigned int src_width, unsigned int src_height,
398 unsigned int crop_start_x, unsigned int crop_start_y, unsigned int crop_dest_width, unsigned int crop_dest_height, unsigned char *dst)
400 int ret = MM_UTIL_ERROR_NONE;
401 unsigned int idx = 0;
402 int start_x = crop_start_x;
403 int start_y = crop_start_y;
405 const unsigned char *_src = src + start_y * src_width + start_x;
408 for (idx = 0; idx < crop_dest_height; idx++) {
409 memcpy(dst, _src, crop_dest_width);
411 dst += crop_dest_width;
415 _src = src + src_height * src_width + (start_y / 2) * src_width / 2 + start_x / 2;
416 for (idx = 0; idx < crop_dest_height / 2; idx++) {
417 memcpy(dst, _src, crop_dest_width / 2);
418 _src += src_width / 2;
419 dst += crop_dest_width / 2;
423 _src = src + src_height * src_width * 5 / 4 + (start_y / 2) * src_width / 2 + start_x / 2;
424 for (idx = 0; idx < crop_dest_height / 2; idx++) {
425 memcpy(dst, _src, crop_dest_width / 2);
426 _src += src_width / 2;
427 dst += crop_dest_width / 2;
433 static int __mm_util_handle_init(mm_util_s *handle)
435 int ret = MM_UTIL_ERROR_NONE;
437 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
439 /* private values init */
441 handle->dst_format = MM_UTIL_COLOR_NUM;
442 handle->rotation = MM_UTIL_ROTATION_NONE;
444 handle->start_x = -1;
445 handle->start_y = -1;
446 handle->dst_width = 0;
447 handle->dst_height = 0;
448 handle->is_completed = FALSE;
449 handle->is_finish = FALSE;
451 handle->set_convert = FALSE;
452 handle->set_crop = FALSE;
453 handle->set_resize = FALSE;
454 handle->set_rotate = FALSE;
456 /*These are a communicator for thread*/
458 handle->queue = g_async_queue_new();
460 if (handle->queue == NULL) {
461 mm_util_error("g_async_queue_new failed");
462 return MM_UTIL_ERROR_INVALID_OPERATION;
468 gpointer _mm_util_thread_repeate(gpointer data)
470 mm_util_s *handle = (mm_util_s *) data;
471 int ret = MM_UTIL_ERROR_NONE;
472 mm_util_color_image_h pop_data = NULL;
474 mm_util_retvm_if(handle == NULL, NULL, "invalid handle");
476 while (!handle->is_finish) {
477 mm_util_debug("waiting...");
478 pop_data = (mm_util_color_image_h)g_async_queue_timeout_pop(handle->queue, 300 * G_TIME_SPAN_MILLISECOND);
479 mm_util_debug("get from data or timeout");
481 if (pop_data == NULL) {
482 mm_util_error("The data is null");
486 ret = __mm_util_transform_exec(handle, (color_image_data_s *)pop_data); /* Need to block */
487 if (ret == MM_UTIL_ERROR_NONE)
488 mm_util_debug("Success - transform_exec");
490 mm_util_error("Error - transform_exec");
492 if (handle->_util_cb->completed_cb) {
493 mm_util_debug("completed_cb is called");
494 handle->_util_cb->completed_cb(handle->dst, ret, handle->_util_cb->user_data);
496 mm_util_destroy_color_image(pop_data);
497 mm_util_destroy_color_image(handle->dst);
498 handle->is_completed = FALSE;
501 mm_util_debug("exit thread");
502 handle->thread = NULL;
507 static int __mm_util_create_thread(mm_util_s *handle)
509 int ret = MM_UTIL_ERROR_NONE;
511 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
512 mm_util_retvm_if(handle->thread != NULL, MM_UTIL_ERROR_NONE, "[NO-ERROR] Thread is already created");
515 handle->thread = g_thread_new("transform_thread", (GThreadFunc)_mm_util_thread_repeate, (gpointer)handle);
516 mm_util_retvm_if(handle->thread == NULL, MM_UTIL_ERROR_INVALID_OPERATION, "ERROR - create thread");
518 mm_util_debug("New thread is created");
523 static int __mm_util_processing(mm_util_s *handle)
525 int ret = MM_UTIL_ERROR_NONE;
526 unsigned char *dst_buf[4] = {NULL,};
527 unsigned int src_width = 0, src_height = 0;
528 mm_util_color_format_e src_format = -1;
529 unsigned int src_index = 0, dst_index = 0;
530 unsigned int res_w = 0;
531 unsigned int res_h = 0;
532 unsigned char *res_buffer = NULL;
533 size_t res_buffer_size = 0;
535 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
537 mm_util_debug("src: %p, dst: %p", handle->src, handle->dst);
539 dst_buf[src_index] = calloc(1, handle->src->size);
540 src_width = handle->src->width;
541 src_height = handle->src->height;
542 src_format = handle->src->color;
543 if (dst_buf[src_index] == NULL) {
544 mm_util_error("[multi func] memory allocation error");
545 return MM_UTIL_ERROR_INVALID_OPERATION;
547 memcpy(dst_buf[src_index], handle->src->data, handle->src->size);
549 if (handle->set_crop) {
552 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);
553 if (ret != MM_UTIL_ERROR_NONE) {
554 __mm_destroy_temp_buffer(dst_buf);
555 mm_util_error("mm_util_crop_image failed");
558 dst_buf[dst_index] = res_buffer;
560 src_index = dst_index;
563 } else if (handle->set_resize) {
566 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);
567 if (ret != MM_UTIL_ERROR_NONE) {
568 __mm_destroy_temp_buffer(dst_buf);
569 mm_util_error("mm_util_resize_image failed");
573 dst_buf[dst_index] = res_buffer;
574 src_index = dst_index;
579 if (handle->set_convert) {
582 mm_util_get_image_size(handle->dst_format, src_width, src_height, &res_buffer_size);
583 dst_buf[dst_index] = calloc(1, res_buffer_size);
584 if (dst_buf[dst_index] == NULL) {
585 mm_util_error("[multi func] memory allocation error");
586 __mm_destroy_temp_buffer(dst_buf);
587 return MM_UTIL_ERROR_INVALID_OPERATION;
589 ret = mm_util_convert_colorspace(dst_buf[src_index], src_width, src_height, src_format, dst_buf[dst_index], handle->dst_format);
590 if (ret != MM_UTIL_ERROR_NONE) {
591 __mm_destroy_temp_buffer(dst_buf);
592 mm_util_error("mm_util_convert_colorspace failed");
595 src_index = dst_index;
596 src_format = handle->dst_format;
599 if (handle->set_rotate) {
601 ret = mm_util_rotate_image(dst_buf[src_index], src_width, src_height, src_format, handle->rotation, &res_buffer, &res_w, &res_h, &res_buffer_size);
602 if (ret != MM_UTIL_ERROR_NONE) {
603 __mm_destroy_temp_buffer(dst_buf);
604 mm_util_error("mm_util_rotate_image failed");
608 dst_buf[dst_index] = res_buffer;
609 src_index = dst_index;
614 if (dst_buf[dst_index] != NULL && res_buffer_size != 0) {
615 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], (size_t)res_buffer_size);
616 if (ret != MM_UTIL_ERROR_NONE)
617 mm_util_error("mm_util_set_color_image failed");
619 __mm_destroy_temp_buffer(dst_buf);
621 mm_util_error("mm_util_processing was finished");
626 static int __mm_util_transform_exec(mm_util_s *handle, color_image_data_s *source_image)
628 int ret = MM_UTIL_ERROR_NONE;
630 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
631 mm_util_retvm_if(source_image == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid source_image");
633 mm_util_debug("orig_image: %p [%zu] %lu X %lu (%u)", source_image->data, source_image->size,
634 source_image->width, source_image->height, source_image->color);
636 handle->src = source_image;
639 ret = __mm_util_processing(handle);
640 if (ret != MM_UTIL_ERROR_NONE) {
641 mm_util_error("__mm_util_processing failed (%d)", ret);
645 mm_util_debug("result_image: %p [%zu] %lu X %lu (%u)", handle->dst->data, handle->dst->size,
646 handle->dst->width, handle->dst->height, handle->dst->color);
652 _mm_util_handle_finalize(mm_util_s *handle)
654 int ret = MM_UTIL_ERROR_NONE;
656 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
658 /* g_thread_exit(handle->thread); */
659 if (handle->thread) {
660 handle->is_finish = TRUE;
661 g_thread_join(handle->thread);
665 g_async_queue_unref(handle->queue);
666 handle->queue = NULL;
669 mm_util_debug("Success - Finalize Handle");
674 int mm_util_create(mm_util_imgp_h *imgp_handle)
676 int ret = MM_UTIL_ERROR_NONE;
678 mm_util_retvm_if(imgp_handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid imgp_handle");
680 mm_util_s *handle = calloc(1, sizeof(mm_util_s));
682 mm_util_error("[ERROR] - _handle");
683 return MM_UTIL_ERROR_INVALID_OPERATION;
686 ret = __mm_util_handle_init(handle);
687 if (ret != MM_UTIL_ERROR_NONE) {
688 mm_util_error("_mm_util_handle_init failed");
689 MMUTIL_SAFE_FREE(handle);
693 *imgp_handle = (mm_util_imgp_h)handle;
698 int mm_util_set_colorspace_convert(mm_util_imgp_h imgp_handle, mm_util_color_format_e colorspace)
700 int ret = MM_UTIL_ERROR_NONE;
701 mm_util_s *handle = (mm_util_s *) imgp_handle;
703 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
705 handle->set_convert = TRUE;
706 handle->dst_format = colorspace;
707 mm_util_debug("imgp fmt: %d", handle->dst_format);
712 int mm_util_set_resolution(mm_util_imgp_h imgp_handle, unsigned int width, unsigned int height)
714 int ret = MM_UTIL_ERROR_NONE;
715 mm_util_s *handle = (mm_util_s *) imgp_handle;
717 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
719 handle->set_resize = TRUE;
720 handle->dst_width = width;
721 handle->dst_height = height;
726 int mm_util_set_rotation(mm_util_imgp_h imgp_handle, mm_util_img_rotate_type rotation)
728 int ret = MM_UTIL_ERROR_NONE;
729 mm_util_s *handle = (mm_util_s *) imgp_handle;
731 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
733 handle->set_rotate = TRUE;
734 handle->rotation = rotation;
739 int mm_util_set_crop_area(mm_util_imgp_h imgp_handle, unsigned int start_x, unsigned int start_y, unsigned int end_x, unsigned int end_y)
741 int ret = MM_UTIL_ERROR_NONE;
742 mm_util_s *handle = (mm_util_s *) imgp_handle;
744 unsigned int dest_width = end_x - start_x;
745 unsigned int dest_height = end_y - start_y;
747 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
749 handle->set_crop = TRUE;
750 handle->start_x = start_x;
751 handle->start_y = start_y;
752 handle->dst_width = dest_width;
753 handle->dst_height = dest_height;
758 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)
760 int ret = MM_UTIL_ERROR_NONE;
761 mm_util_s *handle = (mm_util_s *) imgp_handle;
765 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
766 mm_util_retvm_if(image == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid image");
767 mm_util_retvm_if(completed_callback == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid completed_callback");
769 mm_util_debug("image: %p", image);
771 MMUTIL_SAFE_FREE(handle->_util_cb);
772 handle->_util_cb = (mm_util_cb_s *)calloc(1, sizeof(mm_util_cb_s));
773 if (handle->_util_cb) {
774 handle->_util_cb->completed_cb = completed_callback;
775 handle->_util_cb->user_data = user_data;
777 mm_util_error("[ERROR] _util_cb_s");
781 mm_util_debug("g_async_queue_push");
782 g_async_queue_push(handle->queue, GINT_TO_POINTER(image));
783 ret = __mm_util_create_thread(handle);
784 if (ret != MM_UTIL_ERROR_NONE) {
785 mm_util_error("ERROR - Create thread");
788 mm_util_debug("Success -__mm_util_create_thread");
797 int mm_util_transform_is_completed(mm_util_imgp_h imgp_handle, bool *is_completed)
799 int ret = MM_UTIL_ERROR_NONE;
801 mm_util_s *handle = (mm_util_s *) imgp_handle;
803 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
804 mm_util_retvm_if(!is_completed, MM_UTIL_ERROR_INVALID_PARAMETER, "[ERROR] - is_completed");
806 *is_completed = handle->is_completed;
807 mm_util_debug("[Transform....] %d", *is_completed);
812 int mm_util_destroy(mm_util_imgp_h imgp_handle)
814 int ret = MM_UTIL_ERROR_NONE;
815 mm_util_s *handle = (mm_util_s *) imgp_handle;
819 mm_util_retvm_if(handle == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid handle");
820 mm_util_retvm_if(_mm_util_handle_finalize(handle) != MM_UTIL_ERROR_NONE, MM_UTIL_ERROR_INVALID_PARAMETER, "fail _mm_util_handle_finalize");
822 MMUTIL_SAFE_FREE(handle->_util_cb);
823 MMUTIL_SAFE_FREE(handle);
830 static IMGPInfoFunc __mm_util_initialize(imgp_type_e function, mm_util_color_format_e src_format, mm_util_color_format_e dst_format, GModule **module)
832 imgp_plugin_type_e _imgp_plugin_type_e = IMGP_GSTCS;
833 GModule *_module = NULL;
834 IMGPInfoFunc _func = NULL;
836 if (function == IMGP_CSC) {
837 if (__mm_select_convert_plugin(src_format, dst_format))
838 _imgp_plugin_type_e = IMGP_NEON;
840 } else if (function == IMGP_RSZ) {
841 if (__mm_select_resize_plugin(src_format))
842 _imgp_plugin_type_e = IMGP_NEON;
844 } else if (function == IMGP_ROT) {
845 if (__mm_select_rotate_plugin(src_format))
846 _imgp_plugin_type_e = IMGP_NEON;
849 mm_util_error("invalid function : [%d]", function);
852 mm_util_debug("plugin type: %d", _imgp_plugin_type_e);
854 _module = __mm_util_imgp_initialize(_imgp_plugin_type_e);
856 if (_module == NULL) { /* when IMGP_NEON is NULL */
857 _imgp_plugin_type_e = IMGP_GSTCS;
858 mm_util_debug("You use %s module", PATH_GSTCS_LIB);
859 _module = __mm_util_imgp_initialize(_imgp_plugin_type_e);
862 mm_util_debug("mm_util_imgp_func: %p", _module);
864 if (_module == NULL) {
865 mm_util_error("invalid module");
869 g_module_symbol(_module, IMGP_FUNC_NAME, (gpointer *)&_func);
872 mm_util_error("invalid function");
873 g_module_close(_module);
882 static bool __mm_util_check_format(mm_util_color_format_e color_format)
884 if ((color_format >= MM_UTIL_COLOR_YUV420) && (color_format <= MM_UTIL_COLOR_BGRX))
890 int mm_util_convert_colorspace(const unsigned char *src, unsigned int src_width, unsigned int src_height, mm_util_color_format_e src_format, unsigned char *dst, mm_util_color_format_e dst_format)
892 int ret = MM_UTIL_ERROR_NONE;
893 IMGPInfoFunc _mm_util_imgp_func = NULL;
894 GModule *_module = NULL;
895 unsigned char *output_buffer = NULL;
896 unsigned int res_w = 0;
897 unsigned int res_h = 0;
898 unsigned char *res_buffer = NULL;
899 size_t res_buffer_size = 0;
901 mm_util_retvm_if(src == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src");
902 mm_util_retvm_if(dst == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst");
903 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(src_format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_format [%d]", src_format);
904 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(dst_format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst_format [%d]", dst_format);
905 mm_util_retvm_if((__mm_util_check_format(src_format) == FALSE), MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported src_format [%d]", src_format);
906 mm_util_retvm_if((__mm_util_check_format(dst_format) == FALSE), MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported dst_format [%d]", dst_format);
908 mm_util_debug("src_width [%d] src_height [%d] src_format[%d] dst_format[%d]", src_width, src_height, src_format, dst_format);
910 _mm_util_imgp_func = __mm_util_initialize(IMGP_CSC, src_format, dst_format, &_module);
911 if (_mm_util_imgp_func == NULL) {
912 mm_util_error("ERROR - __mm_util_initialize");
913 return MM_UTIL_ERROR_INVALID_OPERATION;
916 imgp_info_s *_imgp_info_s = (imgp_info_s *) calloc(1, sizeof(imgp_info_s));
917 if (_imgp_info_s == NULL) {
918 mm_util_error("ERROR - alloc handle");
919 ret = MM_UTIL_ERROR_OUT_OF_MEMORY;
923 ret = __mm_set_imgp_info_s(_imgp_info_s, src_format, src_width, src_height, dst_format, src_width, src_height, MM_UTIL_ROTATE_0);
924 if (ret != MM_UTIL_ERROR_NONE) {
925 mm_util_error("__mm_set_imgp_info_s failed");
926 ret = MM_UTIL_ERROR_INVALID_OPERATION;
930 ret = _mm_util_imgp_func(_imgp_info_s, src, &output_buffer, IMGP_CSC);
931 if (ret != MM_UTIL_ERROR_NONE) {
932 mm_util_error("image processing failed");
936 if ((_imgp_info_s->dst_width != _imgp_info_s->output_stride || _imgp_info_s->dst_height != _imgp_info_s->output_elevation)) {
937 ret = mm_util_crop_image(output_buffer, _imgp_info_s->output_stride, _imgp_info_s->output_elevation, dst_format, 0, 0, _imgp_info_s->dst_width, _imgp_info_s->dst_height, &res_buffer, &res_w, &res_h, &res_buffer_size);
938 if (ret != MM_UTIL_ERROR_NONE) {
939 mm_util_error("mm_util_crop_image failed");
940 ret = MM_UTIL_ERROR_INVALID_OPERATION;
943 memcpy(dst, res_buffer, res_buffer_size);
945 memcpy(dst, output_buffer, _imgp_info_s->buffer_size);
949 mm_util_debug("dst[%p] dst_width[%u] dst_height[%u] output_stride[%u] output_elevation[%u]",
950 dst, _imgp_info_s->dst_width, _imgp_info_s->dst_height, _imgp_info_s->output_stride, _imgp_info_s->output_elevation);
954 __mm_util_imgp_finalize(_module, _imgp_info_s);
956 MMUTIL_SAFE_FREE(output_buffer);
957 MMUTIL_SAFE_FREE(res_buffer);
964 int mm_util_resize_image(const unsigned char *src, unsigned int src_width, unsigned int src_height, mm_util_color_format_e src_format, unsigned int dst_width, unsigned int dst_height, unsigned char **dst, unsigned int *result_buf_width, unsigned int *result_buf_height, size_t *result_buf_size)
966 int ret = MM_UTIL_ERROR_NONE;
967 IMGPInfoFunc _mm_util_imgp_func = NULL;
968 GModule *_module = NULL;
969 unsigned char *output_buffer = NULL;
970 unsigned int res_w = 0;
971 unsigned int res_h = 0;
972 unsigned char *res_buffer = NULL;
973 size_t res_buffer_size = 0;
975 mm_util_retvm_if(src == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src");
976 mm_util_retvm_if(src_width == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_width");
977 mm_util_retvm_if(src_height == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_height");
978 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(src_format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_format [%d]", src_format);
979 mm_util_retvm_if((__mm_util_check_format(src_format) == FALSE), MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported src_format [%d]", src_format);
980 mm_util_retvm_if(dst == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst");
981 mm_util_retvm_if(dst_width == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst_width");
982 mm_util_retvm_if(dst_height == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst_height");
984 mm_util_debug("src_width [%d] src_height [%d] src_format[%d]", src_width, src_height, src_format);
986 _mm_util_imgp_func = __mm_util_initialize(IMGP_RSZ, src_format, 0, &_module);
987 mm_util_retvm_if(_mm_util_imgp_func == NULL, MM_UTIL_ERROR_INVALID_OPERATION, "fail __mm_util_initialize");
989 imgp_info_s *_imgp_info_s = (imgp_info_s *) calloc(1, sizeof(imgp_info_s));
990 if (_imgp_info_s == NULL) {
991 mm_util_error("ERROR - alloc handle");
992 ret = MM_UTIL_ERROR_OUT_OF_MEMORY;
999 ret = __mm_set_imgp_info_s(_imgp_info_s, src_format, src_width, src_height, src_format, dst_width, dst_height, MM_UTIL_ROTATE_0);
1000 if (ret != MM_UTIL_ERROR_NONE) {
1001 mm_util_error("__mm_set_imgp_info_s failed [%d]", ret);
1002 ret = MM_UTIL_ERROR_INVALID_OPERATION;
1006 if (g_strrstr(g_module_name(_module), GST)) {
1007 if (__mm_gst_can_resize_format(_imgp_info_s->src_format) == FALSE) {
1008 mm_util_error("#RESIZE ERROR# IMAGE_NOT_SUPPORT_FORMAT");
1009 ret = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1014 ret = _mm_util_imgp_func(_imgp_info_s, src, &output_buffer, IMGP_RSZ);
1015 mm_util_debug("_mm_util_imgp_func, ret: %d", ret);
1016 if (ret != MM_UTIL_ERROR_NONE) {
1017 mm_util_error("image processing failed");
1021 if ((_imgp_info_s->dst_width != _imgp_info_s->output_stride || _imgp_info_s->dst_height != _imgp_info_s->output_elevation)) {
1022 ret = mm_util_crop_image(output_buffer, _imgp_info_s->output_stride, _imgp_info_s->output_elevation, src_format, 0, 0, _imgp_info_s->dst_width, _imgp_info_s->dst_height, &res_buffer, &res_w, &res_h, &res_buffer_size);
1023 if (ret != MM_UTIL_ERROR_NONE) {
1024 mm_util_error("mm_util_crop_image failed");
1025 MMUTIL_SAFE_FREE(output_buffer);
1026 ret = MM_UTIL_ERROR_INVALID_OPERATION;
1030 MMUTIL_SAFE_FREE(output_buffer);
1032 *result_buf_size = res_buffer_size;
1035 *dst = output_buffer;
1036 *result_buf_size = _imgp_info_s->buffer_size;
1039 *result_buf_width = res_w;
1040 *result_buf_height = res_h;
1042 mm_util_debug("dst[%p] result_buf_w[%u] result_buf_h[%u] output_stride[%u] output_elevation[%u]", dst, *result_buf_width, *result_buf_height, _imgp_info_s->output_stride, _imgp_info_s->output_elevation);
1046 __mm_util_imgp_finalize(_module, _imgp_info_s);
1053 int mm_util_rotate_image(const unsigned char *src, unsigned int src_width, unsigned int src_height, mm_util_color_format_e src_format, mm_util_img_rotate_type angle, unsigned char **dst, unsigned int *result_buf_width, unsigned int *result_buf_height, size_t *result_buf_size)
1055 int ret = MM_UTIL_ERROR_NONE;
1056 IMGPInfoFunc _mm_util_imgp_func = NULL;
1057 GModule *_module = NULL;
1058 unsigned char *output_buffer = NULL;
1059 unsigned int res_w = 0;
1060 unsigned int res_h = 0;
1061 unsigned char *res_buffer = NULL;
1062 size_t res_buffer_size = 0;
1064 mm_util_retvm_if(src == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src");
1065 mm_util_retvm_if(src_width == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_width");
1066 mm_util_retvm_if(src_height == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_height");
1067 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(src_format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_format [%d]", src_format);
1068 mm_util_retvm_if((__mm_util_check_format(src_format) == FALSE), MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported src_format [%d]", src_format);
1069 mm_util_retvm_if((angle < MM_UTIL_ROTATE_0) || (angle >= MM_UTIL_ROTATE_NUM), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid angle [%d]", angle);
1070 mm_util_retvm_if(dst == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst");
1071 mm_util_retvm_if(result_buf_width == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_width");
1072 mm_util_retvm_if(result_buf_height == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_height");
1073 mm_util_retvm_if(result_buf_size == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_size");
1075 mm_util_debug("src_w[%u] src_h[%u] src_format[%u] angle[%u]", src_width, src_height, src_format, angle);
1077 _mm_util_imgp_func = __mm_util_initialize(IMGP_ROT, src_format, 0, &_module);
1078 if (_mm_util_imgp_func == NULL) {
1079 mm_util_error("ERROR - __mm_util_initialize");
1080 return MM_UTIL_ERROR_INVALID_OPERATION;
1083 imgp_info_s *_imgp_info_s = (imgp_info_s *) calloc(1, sizeof(imgp_info_s));
1084 if (_imgp_info_s == NULL) {
1085 mm_util_error("ERROR - alloc handle");
1086 ret = MM_UTIL_ERROR_OUT_OF_MEMORY;
1090 if ((angle == MM_UTIL_ROTATE_90) || (angle == MM_UTIL_ROTATE_270)) {
1098 ret = __mm_set_imgp_info_s(_imgp_info_s, src_format, src_width, src_height, src_format, res_w, res_h, angle);
1099 mm_util_debug("__mm_set_imgp_info_s");
1100 if (ret != MM_UTIL_ERROR_NONE) {
1101 mm_util_error("__mm_set_imgp_info_s failed");
1102 ret = MM_UTIL_ERROR_INVALID_OPERATION;
1106 if (g_strrstr(g_module_name(_module), GST)) {
1107 if (__mm_gst_can_rotate_format(_imgp_info_s->src_format) == FALSE) {
1108 mm_util_error("#gstreamer ROTATE ERROR# IMAGE_NOT_SUPPORT_FORMAT");
1109 ret = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1114 ret = _mm_util_imgp_func(_imgp_info_s, src, &output_buffer, IMGP_ROT);
1115 if (ret != MM_UTIL_ERROR_NONE) {
1116 mm_util_error("image processing failed");
1120 if ((_imgp_info_s->dst_width != _imgp_info_s->output_stride || _imgp_info_s->dst_height != _imgp_info_s->output_elevation)) {
1121 unsigned int start_x = 0;
1122 unsigned int start_y = 0;
1123 if (angle == MM_UTIL_ROTATE_90) {
1126 } else if (angle == MM_UTIL_ROTATE_180) {
1127 start_x = _imgp_info_s->output_stride-_imgp_info_s->dst_width;
1129 } else if (angle == MM_UTIL_ROTATE_270) {
1131 start_y = _imgp_info_s->output_elevation - _imgp_info_s->dst_height;
1133 ret = mm_util_crop_image(output_buffer, _imgp_info_s->output_stride, _imgp_info_s->output_elevation, src_format, start_x, start_y, _imgp_info_s->dst_width, _imgp_info_s->dst_height, &res_buffer, &res_w, &res_h, &res_buffer_size);
1134 if (ret != MM_UTIL_ERROR_NONE) {
1135 mm_util_error("mm_util_crop_image failed");
1136 MMUTIL_SAFE_FREE(output_buffer);
1137 ret = MM_UTIL_ERROR_INVALID_OPERATION;
1141 MMUTIL_SAFE_FREE(output_buffer);
1143 *result_buf_size = res_buffer_size;
1145 *dst = output_buffer;
1146 *result_buf_size = _imgp_info_s->buffer_size;
1149 *result_buf_width = res_w;
1150 *result_buf_height = res_h;
1152 mm_util_debug("dst[%p] result_buf_w[%u] result_buf_h[%u] output_stride[%u] output_elevation[%u]", dst, *result_buf_width, *result_buf_height, _imgp_info_s->output_stride, _imgp_info_s->output_elevation);
1156 __mm_util_imgp_finalize(_module, _imgp_info_s);
1163 int mm_util_crop_image(const unsigned char *src, unsigned int src_width, unsigned int src_height, mm_util_color_format_e src_format,
1164 unsigned int crop_start_x, unsigned int crop_start_y, unsigned int crop_dest_width, unsigned int crop_dest_height, unsigned char **dst, unsigned int *result_buf_width, unsigned int *result_buf_height, size_t *result_buf_size)
1166 int ret = MM_UTIL_ERROR_NONE;
1167 unsigned int dst_buf_size = 0;
1168 unsigned char *dst_buffer = NULL;
1169 unsigned int res_w = 0;
1170 unsigned int res_h = 0;
1172 mm_util_retvm_if(src == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src");
1173 mm_util_retvm_if(src_width == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_width");
1174 mm_util_retvm_if(src_height == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_height");
1175 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(src_format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_format [%d]", src_format);
1176 mm_util_retvm_if((__mm_util_check_format(src_format) == FALSE), MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported src_format [%d]", src_format);
1177 mm_util_retvm_if(dst == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst");
1178 mm_util_retvm_if(result_buf_width == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_width");
1179 mm_util_retvm_if(result_buf_height == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_height");
1180 mm_util_retvm_if(result_buf_size == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_size");
1181 mm_util_retvm_if((crop_start_x + crop_dest_width > src_width), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid position [%d]]", crop_start_x);
1182 mm_util_retvm_if((crop_start_y + crop_dest_height > src_height), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid position [%d]", crop_start_y);
1184 mm_util_debug("[Input] src[%p] src_width[%u] src_height[%u] src_format[%d] crop_start_x[%u] crop_start_y[%u] crop_dest_width[%u] crop_dest_height[%u]",
1185 src, src_width, src_height, src_format, crop_start_x, crop_start_y, crop_dest_width, crop_dest_height);
1187 __mm_util_get_crop_image_size(src_format, crop_dest_width, crop_dest_height, &dst_buf_size);
1188 mm_util_retvm_if(dst_buf_size == 0, MM_UTIL_ERROR_INVALID_OPERATION, "fail to get dst_buf_size");
1190 dst_buffer = calloc(1, dst_buf_size);
1191 mm_util_retvm_if(dst_buffer == NULL, MM_UTIL_ERROR_OUT_OF_MEMORY, "memory alloc fail");
1193 res_w = crop_dest_width;
1194 res_h = crop_dest_height;
1196 switch (src_format) {
1197 case MM_UTIL_COLOR_RGB24: {
1198 ret = __mm_util_crop_rgb888(src, src_width, src_height, crop_start_x, crop_start_y, res_w, res_h, dst_buffer);
1201 case MM_UTIL_COLOR_RGB16: {
1202 ret = __mm_util_crop_rgb565(src, src_width, src_height, crop_start_x, crop_start_y, res_w, res_h, dst_buffer);
1205 case MM_UTIL_COLOR_ARGB:
1206 case MM_UTIL_COLOR_BGRA:
1207 case MM_UTIL_COLOR_RGBA:
1208 case MM_UTIL_COLOR_BGRX: {
1209 ret = __mm_util_crop_rgba32(src, src_width, src_height, crop_start_x, crop_start_y, res_w, res_h, dst_buffer);
1212 case MM_UTIL_COLOR_I420:
1213 case MM_UTIL_COLOR_YUV420: {
1214 if ((crop_dest_width % 2) != 0) {
1215 mm_util_warn("#YUV Width value(%d) must be even at least# ", crop_dest_width);
1216 res_w = ((crop_dest_width+1)>>1)<<1;
1217 mm_util_debug("Image isplay is suceeded when YUV crop width value %d", res_w);
1220 if ((crop_dest_height % 2) != 0) { /* height value must be also even when crop yuv image */
1221 mm_util_warn("#YUV Height value(%d) must be even at least# ", crop_dest_height);
1222 res_h = ((crop_dest_height+1)>>1)<<1;
1223 mm_util_debug("Image isplay is suceeded when YUV crop height value %d", res_h);
1226 MMUTIL_SAFE_FREE(dst_buffer);
1227 __mm_util_get_crop_image_size(src_format, res_w, res_h, &dst_buf_size);
1228 mm_util_retvm_if(dst_buf_size == 0, MM_UTIL_ERROR_INVALID_OPERATION, "fail to get dst_buf_size");
1230 dst_buffer = calloc(1, dst_buf_size);
1231 mm_util_retvm_if(dst_buffer == NULL, MM_UTIL_ERROR_OUT_OF_MEMORY, "memory alloc fail");
1233 ret = __mm_util_crop_yuv420(src, src_width, src_height, crop_start_x, crop_start_y, res_w, res_h, dst_buffer);
1237 mm_util_debug("Not supported format");
1238 MMUTIL_SAFE_FREE(dst_buffer);
1239 ret = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1242 *result_buf_size = (size_t)dst_buf_size;
1244 *result_buf_width = res_w;
1245 *result_buf_height = res_h;
1252 int mm_util_get_image_size(mm_util_color_format_e format, unsigned int width, unsigned int height, size_t *imgsize)
1254 int ret = MM_UTIL_ERROR_NONE;
1255 unsigned char x_chroma_shift = 0;
1256 unsigned char y_chroma_shift = 0;
1257 int size, w2, h2, size2;
1258 int stride, stride2;
1262 mm_util_retvm_if((imgsize == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid imgsize");
1263 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid format [%d]", format);
1264 mm_util_retvm_if((check_valid_picture_size(width, height) != MM_UTIL_ERROR_NONE), MM_UTIL_ERROR_INVALID_PARAMETER, "image width & height is too big");
1269 case MM_UTIL_COLOR_I420:
1270 case MM_UTIL_COLOR_YUV420:
1273 stride = MM_UTIL_ROUND_UP_4(width);
1274 h2 = ROUND_UP_X(height, x_chroma_shift);
1276 w2 = DIV_ROUND_UP_X(width, x_chroma_shift);
1277 stride2 = MM_UTIL_ROUND_UP_4(w2);
1278 h2 = DIV_ROUND_UP_X(height, y_chroma_shift);
1279 size2 = stride2 * h2;
1280 *imgsize = size + 2 * size2;
1282 case MM_UTIL_COLOR_YUV422:
1283 case MM_UTIL_COLOR_YUYV:
1284 case MM_UTIL_COLOR_UYVY:
1285 case MM_UTIL_COLOR_NV16:
1286 case MM_UTIL_COLOR_NV61:
1287 stride = MM_UTIL_ROUND_UP_4(width) * 2;
1288 size = stride * height;
1292 case MM_UTIL_COLOR_RGB16:
1293 stride = MM_UTIL_ROUND_UP_4(width) * 2;
1294 size = stride * height;
1298 case MM_UTIL_COLOR_RGB24:
1299 stride = MM_UTIL_ROUND_UP_4(width) * 3;
1300 size = stride * height;
1304 case MM_UTIL_COLOR_ARGB:
1305 case MM_UTIL_COLOR_BGRA:
1306 case MM_UTIL_COLOR_RGBA:
1307 case MM_UTIL_COLOR_BGRX:
1309 size = stride * height;
1313 case MM_UTIL_COLOR_NV12:
1314 case MM_UTIL_COLOR_NV12_TILED:
1315 case MM_UTIL_COLOR_NV21:
1318 stride = MM_UTIL_ROUND_UP_4(width);
1319 h2 = ROUND_UP_X(height, y_chroma_shift);
1321 w2 = 2 * DIV_ROUND_UP_X(width, x_chroma_shift);
1322 stride2 = MM_UTIL_ROUND_UP_4(w2);
1323 h2 = DIV_ROUND_UP_X(height, y_chroma_shift);
1324 size2 = stride2 * h2;
1325 *imgsize = size + size2;
1329 mm_util_error("Not supported format");
1330 return MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1333 mm_util_debug("format: %u, *imgsize: %u", format, *imgsize);