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"
28 #define GEN_MASK(x) ((1<<(x))-1)
29 #define ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) & ~GEN_MASK(x))
30 #define DIV_ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) >> (x))
33 typedef gboolean(*IMGPInfoFunc) (imgp_info_s *, const unsigned char *, unsigned char **, imgp_plugin_type_e);
35 static int check_valid_picture_size(int width, int height)
37 if ((int)width > 0 && (int)height > 0 &&
38 ((width + 128) * (unsigned long long)(height + 128)) < INT_MAX/4)
39 return MM_UTIL_ERROR_NONE;
41 return MM_UTIL_ERROR_INVALID_PARAMETER;
44 static gboolean __mm_gst_can_resize_format(mm_util_color_format_e color_format)
46 gboolean _bool = FALSE;
48 mm_util_debug("color_format [%d]", color_format);
50 switch (color_format) {
51 case MM_UTIL_COLOR_YUV420:
52 case MM_UTIL_COLOR_YUV422:
53 case MM_UTIL_COLOR_I420:
54 case MM_UTIL_COLOR_UYVY:
55 case MM_UTIL_COLOR_YUYV:
56 case MM_UTIL_COLOR_RGB16:
57 case MM_UTIL_COLOR_RGB24:
58 case MM_UTIL_COLOR_ARGB:
59 case MM_UTIL_COLOR_BGRA:
60 case MM_UTIL_COLOR_RGBA:
61 case MM_UTIL_COLOR_BGRX:
65 mm_util_error("Not supported format"); //only not support NV12
71 static gboolean __mm_gst_can_rotate_format(mm_util_color_format_e color_format)
73 gboolean _bool = FALSE;
75 mm_util_debug("color_format [%d]", color_format);
77 switch (color_format) {
78 case MM_UTIL_COLOR_YUV420:
79 case MM_UTIL_COLOR_I420:
80 case MM_UTIL_COLOR_RGB24:
81 case MM_UTIL_COLOR_ARGB:
82 case MM_UTIL_COLOR_BGRA:
83 case MM_UTIL_COLOR_RGBA:
87 mm_util_error("Not supported format");
93 static gboolean __mm_select_convert_plugin(mm_util_color_format_e src_format, mm_util_color_format_e dst_format)
95 gboolean _bool = FALSE;
97 mm_util_debug("src_format: %d, dst_format:%d", src_format, dst_format);
99 if (((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_NV12)) ||
100 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
101 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
102 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_ARGB)) ||
103 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_BGRA)) ||
104 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_RGBA)) ||
105 ((src_format == MM_UTIL_COLOR_YUV420) && (dst_format == MM_UTIL_COLOR_NV12_TILED)) ||
107 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_NV12)) ||
108 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
109 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
110 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_ARGB)) ||
111 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_BGRA)) ||
112 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_RGBA)) ||
113 ((src_format == MM_UTIL_COLOR_I420) && (dst_format == MM_UTIL_COLOR_NV12_TILED)) ||
115 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
116 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_I420)) ||
117 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
118 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
119 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_ARGB)) ||
120 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_BGRA)) ||
121 ((src_format == MM_UTIL_COLOR_NV12) && (dst_format == MM_UTIL_COLOR_RGBA)) ||
123 ((src_format == MM_UTIL_COLOR_UYVY) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
124 ((src_format == MM_UTIL_COLOR_UYVY) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
126 ((src_format == MM_UTIL_COLOR_YUYV) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
127 ((src_format == MM_UTIL_COLOR_YUYV) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
128 ((src_format == MM_UTIL_COLOR_YUYV) && (dst_format == MM_UTIL_COLOR_ARGB)) ||
129 ((src_format == MM_UTIL_COLOR_YUYV) && (dst_format == MM_UTIL_COLOR_BGRA)) ||
130 ((src_format == MM_UTIL_COLOR_YUYV) && (dst_format == MM_UTIL_COLOR_RGBA)) ||
132 ((src_format == MM_UTIL_COLOR_RGB16) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
133 ((src_format == MM_UTIL_COLOR_RGB16) && (dst_format == MM_UTIL_COLOR_I420)) ||
134 ((src_format == MM_UTIL_COLOR_RGB16) && (dst_format == MM_UTIL_COLOR_NV12)) ||
136 ((src_format == MM_UTIL_COLOR_RGB24) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
137 ((src_format == MM_UTIL_COLOR_RGB24) && (dst_format == MM_UTIL_COLOR_I420)) ||
138 ((src_format == MM_UTIL_COLOR_RGB24) && (dst_format == MM_UTIL_COLOR_NV12)) ||
140 ((src_format == MM_UTIL_COLOR_ARGB) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
141 ((src_format == MM_UTIL_COLOR_ARGB) && (dst_format == MM_UTIL_COLOR_I420)) ||
142 ((src_format == MM_UTIL_COLOR_ARGB) && (dst_format == MM_UTIL_COLOR_NV12)) ||
144 ((src_format == MM_UTIL_COLOR_BGRA) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
145 ((src_format == MM_UTIL_COLOR_BGRA) && (dst_format == MM_UTIL_COLOR_I420)) ||
146 ((src_format == MM_UTIL_COLOR_BGRA) && (dst_format == MM_UTIL_COLOR_NV12)) ||
147 ((src_format == MM_UTIL_COLOR_RGBA) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
148 ((src_format == MM_UTIL_COLOR_RGBA) && (dst_format == MM_UTIL_COLOR_I420)) ||
149 ((src_format == MM_UTIL_COLOR_RGBA) && (dst_format == MM_UTIL_COLOR_NV12)) ||
150 ((src_format == MM_UTIL_COLOR_RGBA) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
152 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_YUV420)) ||
153 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_I420)) ||
154 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_NV12)) ||
155 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_RGB16)) ||
156 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_RGB24)) ||
157 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_ARGB)) ||
158 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_BGRA)) ||
159 ((src_format == MM_UTIL_COLOR_NV12_TILED) && (dst_format == MM_UTIL_COLOR_RGBA))) {
167 static gboolean __mm_select_resize_plugin(mm_util_color_format_e _format)
169 gboolean _bool = FALSE;
171 mm_util_debug("_format: %d", _format);
173 if ((_format == MM_UTIL_COLOR_UYVY) || (_format == MM_UTIL_COLOR_YUYV) ||
174 (_format == MM_UTIL_COLOR_RGBA) || (_format == MM_UTIL_COLOR_BGRX))
182 static gboolean __mm_select_rotate_plugin(mm_util_color_format_e _format)
184 mm_util_debug("_format: %d", _format);
186 if ((_format == MM_UTIL_COLOR_YUV420) || (_format == MM_UTIL_COLOR_I420) || (_format == MM_UTIL_COLOR_NV12)
187 || (_format == MM_UTIL_COLOR_RGB24 || _format == MM_UTIL_COLOR_RGB16)) {
194 static int __mm_util_get_crop_image_size(mm_util_color_format_e format, unsigned int width, unsigned int height, size_t *imgsize)
196 int ret = MM_UTIL_ERROR_NONE;
197 unsigned char x_chroma_shift = 0;
198 unsigned char y_chroma_shift = 0;
199 int size, w2, h2, size2;
204 mm_util_retvm_if(imgsize == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid imgsize");
205 mm_util_retvm_if(check_valid_picture_size(width, height) != MM_UTIL_ERROR_NONE, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid width and height");
210 case MM_UTIL_COLOR_I420:
211 case MM_UTIL_COLOR_YUV420:
214 stride = MM_UTIL_ROUND_UP_4(width);
215 h2 = ROUND_UP_X(height, x_chroma_shift);
217 w2 = DIV_ROUND_UP_X(width, x_chroma_shift);
218 stride2 = MM_UTIL_ROUND_UP_4(w2);
219 h2 = DIV_ROUND_UP_X(height, y_chroma_shift);
220 size2 = stride2 * h2;
221 *imgsize = size + 2 * size2;
223 case MM_UTIL_COLOR_YUV422:
224 case MM_UTIL_COLOR_YUYV:
225 case MM_UTIL_COLOR_UYVY:
226 case MM_UTIL_COLOR_NV16:
227 case MM_UTIL_COLOR_NV61:
228 stride = MM_UTIL_ROUND_UP_4(width) * 2;
229 size = stride * height;
233 case MM_UTIL_COLOR_RGB16:
235 size = stride * height;
239 case MM_UTIL_COLOR_RGB24:
241 size = stride * height;
245 case MM_UTIL_COLOR_ARGB:
246 case MM_UTIL_COLOR_BGRA:
247 case MM_UTIL_COLOR_RGBA:
248 case MM_UTIL_COLOR_BGRX:
250 size = stride * height;
255 case MM_UTIL_COLOR_NV12:
256 case MM_UTIL_COLOR_NV12_TILED:
259 stride = MM_UTIL_ROUND_UP_4(width);
260 h2 = ROUND_UP_X(height, y_chroma_shift);
262 w2 = 2 * DIV_ROUND_UP_X(width, x_chroma_shift);
263 stride2 = MM_UTIL_ROUND_UP_4(w2);
264 h2 = DIV_ROUND_UP_X(height, y_chroma_shift);
265 size2 = stride2 * h2;
266 *imgsize = size + size2;
270 mm_util_error("Not supported format");
271 return MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
274 mm_util_debug("format: %d, *imgsize: %d", format, *imgsize);
279 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)
281 int ret = MM_UTIL_ERROR_NONE;
283 mm_util_retvm_if(_imgp_info_s == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid _imgp_info_s");
285 _imgp_info_s->src_format = src_format;
286 _imgp_info_s->src_width = src_width;
287 _imgp_info_s->src_height = src_height;
289 _imgp_info_s->dst_format = dst_format;
290 _imgp_info_s->dst_width = dst_width;
291 _imgp_info_s->dst_height = dst_height;
292 _imgp_info_s->buffer_size = 0;
293 _imgp_info_s->angle = angle;
295 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);
300 static GModule *__mm_util_imgp_initialize(imgp_plugin_type_e _imgp_plugin_type_e)
302 GModule *module = NULL;
305 if (_imgp_plugin_type_e == IMGP_NEON)
306 module = g_module_open(PATH_NEON_LIB, G_MODULE_BIND_LAZY);
307 else if (_imgp_plugin_type_e == IMGP_GSTCS)
308 module = g_module_open(PATH_GSTCS_LIB, G_MODULE_BIND_LAZY);
310 mm_util_retvm_if(module == NULL, NULL, "[%d] %s | %s module open failed", _imgp_plugin_type_e, PATH_NEON_LIB, PATH_GSTCS_LIB);
311 mm_util_debug("module: %p, g_module_name: %s", module, g_module_name(module));
316 static void __mm_util_imgp_finalize(GModule *module, imgp_info_s *_imgp_info_s)
319 g_module_close(module);
321 MMUTIL_SAFE_FREE(_imgp_info_s);
326 static int __mm_util_crop_rgba32(const unsigned char *src, unsigned int src_width, unsigned int src_height,
327 unsigned int crop_start_x, unsigned int crop_start_y, unsigned int crop_dest_width, unsigned int crop_dest_height, unsigned char *dst)
329 int ret = MM_UTIL_ERROR_NONE;
330 unsigned int idx = 0;
331 int src_bytesperline = src_width * 4;
332 int dst_bytesperline = crop_dest_width * 4;
334 src += crop_start_y * src_bytesperline + 4 * crop_start_x;
336 for (idx = 0; idx < crop_dest_height; idx++) {
337 memcpy(dst, src, dst_bytesperline);
338 src += src_bytesperline;
339 dst += dst_bytesperline;
345 static int __mm_util_crop_rgb888(const unsigned char *src, unsigned int src_width, unsigned int src_height,
346 unsigned int crop_start_x, unsigned int crop_start_y, unsigned int crop_dest_width, unsigned int crop_dest_height, unsigned char *dst)
348 int ret = MM_UTIL_ERROR_NONE;
349 unsigned int idx = 0;
350 int src_bytesperline = src_width * 3;
351 int dst_bytesperline = crop_dest_width * 3;
353 src += crop_start_y * src_bytesperline + 3 * crop_start_x;
355 for (idx = 0; idx < crop_dest_height; idx++) {
356 memcpy(dst, src, dst_bytesperline);
357 src += src_bytesperline;
358 dst += dst_bytesperline;
364 static int __mm_util_crop_rgb565(const unsigned char *src, unsigned int src_width, unsigned int src_height,
365 unsigned int crop_start_x, unsigned int crop_start_y, unsigned int crop_dest_width, unsigned int crop_dest_height, unsigned char *dst)
367 int ret = MM_UTIL_ERROR_NONE;
368 unsigned int idx = 0;
369 int src_bytesperline = src_width * 2;
370 int dst_bytesperline = crop_dest_width * 2;
372 src += crop_start_y * src_bytesperline + 2 * crop_start_x;
374 for (idx = 0; idx < crop_dest_height; idx++) {
375 memcpy(dst, src, dst_bytesperline);
376 src += src_bytesperline;
377 dst += dst_bytesperline;
383 static int __mm_util_crop_yuv420(const unsigned char *src, unsigned int src_width, unsigned int src_height,
384 unsigned int crop_start_x, unsigned int crop_start_y, unsigned int crop_dest_width, unsigned int crop_dest_height, unsigned char *dst)
386 int ret = MM_UTIL_ERROR_NONE;
387 unsigned int idx = 0;
388 int start_x = crop_start_x;
389 int start_y = crop_start_y;
391 const unsigned char *_src = src + start_y * src_width + start_x;
394 for (idx = 0; idx < crop_dest_height; idx++) {
395 memcpy(dst, _src, crop_dest_width);
397 dst += crop_dest_width;
401 _src = src + src_height * src_width + (start_y / 2) * src_width / 2 + start_x / 2;
402 for (idx = 0; idx < crop_dest_height / 2; idx++) {
403 memcpy(dst, _src, crop_dest_width / 2);
404 _src += src_width / 2;
405 dst += crop_dest_width / 2;
409 _src = src + src_height * src_width * 5 / 4 + (start_y / 2) * src_width / 2 + start_x / 2;
410 for (idx = 0; idx < crop_dest_height / 2; idx++) {
411 memcpy(dst, _src, crop_dest_width / 2);
412 _src += src_width / 2;
413 dst += crop_dest_width / 2;
419 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)
421 imgp_plugin_type_e _imgp_plugin_type_e = IMGP_GSTCS;
422 GModule *_module = NULL;
423 IMGPInfoFunc _func = NULL;
425 if (function == IMGP_CSC) {
426 if (__mm_select_convert_plugin(src_format, dst_format))
427 _imgp_plugin_type_e = IMGP_NEON;
429 } else if (function == IMGP_RSZ) {
430 if (__mm_select_resize_plugin(src_format))
431 _imgp_plugin_type_e = IMGP_NEON;
433 } else if (function == IMGP_ROT) {
434 if (__mm_select_rotate_plugin(src_format))
435 _imgp_plugin_type_e = IMGP_NEON;
438 mm_util_error("invalid function : [%d]", function);
441 mm_util_debug("plugin type: %d", _imgp_plugin_type_e);
443 _module = __mm_util_imgp_initialize(_imgp_plugin_type_e);
445 if (_module == NULL) { /* when IMGP_NEON is NULL */
446 _imgp_plugin_type_e = IMGP_GSTCS;
447 mm_util_debug("You use %s module", PATH_GSTCS_LIB);
448 _module = __mm_util_imgp_initialize(_imgp_plugin_type_e);
451 mm_util_debug("mm_util_imgp_func: %p", _module);
453 if (_module == NULL) {
454 mm_util_error("invalid module");
458 g_module_symbol(_module, IMGP_FUNC_NAME, (gpointer *)&_func);
461 mm_util_error("invalid function");
462 g_module_close(_module);
471 static bool __mm_util_check_format(mm_util_color_format_e color_format)
473 if ((color_format >= MM_UTIL_COLOR_YUV420) && (color_format <= MM_UTIL_COLOR_BGRX))
479 int mm_util_convert_colorspace(const unsigned char *src, unsigned int src_width, unsigned int src_height, mm_util_color_format_e src_format, mm_util_color_format_e dst_format, unsigned char **dst, unsigned int *result_buf_width, unsigned int *result_buf_height, size_t *result_buf_size)
481 int ret = MM_UTIL_ERROR_NONE;
482 IMGPInfoFunc _mm_util_imgp_func = NULL;
483 GModule *_module = NULL;
484 unsigned char *output_buffer = NULL;
485 unsigned int res_w = 0;
486 unsigned int res_h = 0;
487 unsigned char *res_buffer = NULL;
488 size_t res_buffer_size = 0;
490 mm_util_retvm_if(src == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src");
491 mm_util_retvm_if(dst == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst");
492 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(src_format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_format [%d]", src_format);
493 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(dst_format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst_format [%d]", dst_format);
494 mm_util_retvm_if((__mm_util_check_format(src_format) == FALSE), MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported src_format [%d]", src_format);
495 mm_util_retvm_if((__mm_util_check_format(dst_format) == FALSE), MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported dst_format [%d]", dst_format);
496 mm_util_retvm_if(dst == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst");
497 mm_util_retvm_if(result_buf_width == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_width");
498 mm_util_retvm_if(result_buf_height == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_height");
499 mm_util_retvm_if(result_buf_size == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_size");
501 mm_util_debug("src_width [%d] src_height [%d] src_format[%d] dst_format[%d]", src_width, src_height, src_format, dst_format);
503 _mm_util_imgp_func = __mm_util_initialize(IMGP_CSC, src_format, dst_format, &_module);
504 if (_mm_util_imgp_func == NULL) {
505 mm_util_error("ERROR - __mm_util_initialize");
506 return MM_UTIL_ERROR_INVALID_OPERATION;
509 imgp_info_s *_imgp_info_s = (imgp_info_s *) calloc(1, sizeof(imgp_info_s));
510 if (_imgp_info_s == NULL) {
511 mm_util_error("ERROR - alloc handle");
512 ret = MM_UTIL_ERROR_OUT_OF_MEMORY;
519 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);
520 if (ret != MM_UTIL_ERROR_NONE) {
521 mm_util_error("__mm_set_imgp_info_s failed");
522 ret = MM_UTIL_ERROR_INVALID_OPERATION;
526 ret = _mm_util_imgp_func(_imgp_info_s, src, &output_buffer, IMGP_CSC);
527 if (ret != MM_UTIL_ERROR_NONE) {
528 mm_util_error("image processing failed");
532 if ((_imgp_info_s->dst_width != _imgp_info_s->output_stride || _imgp_info_s->dst_height != _imgp_info_s->output_elevation)) {
533 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);
534 if (ret != MM_UTIL_ERROR_NONE) {
535 mm_util_error("mm_util_crop_image failed");
536 MMUTIL_SAFE_FREE(output_buffer);
537 ret = MM_UTIL_ERROR_INVALID_OPERATION;
541 MMUTIL_SAFE_FREE(output_buffer);
543 *result_buf_size = res_buffer_size;
545 *dst = output_buffer;
546 *result_buf_size = _imgp_info_s->buffer_size;
549 *result_buf_width = res_w;
550 *result_buf_height = res_h;
552 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);
556 __mm_util_imgp_finalize(_module, _imgp_info_s);
563 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)
565 int ret = MM_UTIL_ERROR_NONE;
566 IMGPInfoFunc _mm_util_imgp_func = NULL;
567 GModule *_module = NULL;
568 unsigned char *output_buffer = NULL;
569 unsigned int res_w = 0;
570 unsigned int res_h = 0;
571 unsigned char *res_buffer = NULL;
572 size_t res_buffer_size = 0;
574 mm_util_retvm_if(src == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src");
575 mm_util_retvm_if(src_width == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_width");
576 mm_util_retvm_if(src_height == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_height");
577 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(src_format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_format [%d]", src_format);
578 mm_util_retvm_if((__mm_util_check_format(src_format) == FALSE), MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported src_format [%d]", src_format);
579 mm_util_retvm_if(dst == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst");
580 mm_util_retvm_if(dst_width == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst_width");
581 mm_util_retvm_if(dst_height == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst_height");
582 mm_util_retvm_if(result_buf_size == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_size");
584 mm_util_debug("src_width [%d] src_height [%d] src_format[%d]", src_width, src_height, src_format);
586 _mm_util_imgp_func = __mm_util_initialize(IMGP_RSZ, src_format, 0, &_module);
587 mm_util_retvm_if(_mm_util_imgp_func == NULL, MM_UTIL_ERROR_INVALID_OPERATION, "fail __mm_util_initialize");
589 imgp_info_s *_imgp_info_s = (imgp_info_s *) calloc(1, sizeof(imgp_info_s));
590 if (_imgp_info_s == NULL) {
591 mm_util_error("ERROR - alloc handle");
592 ret = MM_UTIL_ERROR_OUT_OF_MEMORY;
599 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);
600 if (ret != MM_UTIL_ERROR_NONE) {
601 mm_util_error("__mm_set_imgp_info_s failed [%d]", ret);
602 ret = MM_UTIL_ERROR_INVALID_OPERATION;
606 if (g_strrstr(g_module_name(_module), GST)) {
607 if (__mm_gst_can_resize_format(_imgp_info_s->src_format) == FALSE) {
608 mm_util_error("#RESIZE ERROR# IMAGE_NOT_SUPPORT_FORMAT");
609 ret = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
614 ret = _mm_util_imgp_func(_imgp_info_s, src, &output_buffer, IMGP_RSZ);
615 mm_util_debug("_mm_util_imgp_func, ret: %d", ret);
616 if (ret != MM_UTIL_ERROR_NONE) {
617 mm_util_error("image processing failed");
621 if ((_imgp_info_s->dst_width != _imgp_info_s->output_stride || _imgp_info_s->dst_height != _imgp_info_s->output_elevation)) {
622 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);
623 if (ret != MM_UTIL_ERROR_NONE) {
624 mm_util_error("mm_util_crop_image failed");
625 MMUTIL_SAFE_FREE(output_buffer);
626 ret = MM_UTIL_ERROR_INVALID_OPERATION;
630 MMUTIL_SAFE_FREE(output_buffer);
632 *result_buf_size = res_buffer_size;
635 *dst = output_buffer;
636 *result_buf_size = _imgp_info_s->buffer_size;
639 *result_buf_width = res_w;
640 *result_buf_height = res_h;
642 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);
646 __mm_util_imgp_finalize(_module, _imgp_info_s);
653 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)
655 int ret = MM_UTIL_ERROR_NONE;
656 IMGPInfoFunc _mm_util_imgp_func = NULL;
657 GModule *_module = NULL;
658 unsigned char *output_buffer = NULL;
659 unsigned int res_w = 0;
660 unsigned int res_h = 0;
661 unsigned char *res_buffer = NULL;
662 size_t res_buffer_size = 0;
664 mm_util_retvm_if(src == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src");
665 mm_util_retvm_if(src_width == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_width");
666 mm_util_retvm_if(src_height == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_height");
667 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(src_format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_format [%d]", src_format);
668 mm_util_retvm_if((__mm_util_check_format(src_format) == FALSE), MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported src_format [%d]", src_format);
669 mm_util_retvm_if((angle < MM_UTIL_ROTATE_0) || (angle >= MM_UTIL_ROTATE_NUM), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid angle [%d]", angle);
670 mm_util_retvm_if(dst == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst");
671 mm_util_retvm_if(result_buf_width == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_width");
672 mm_util_retvm_if(result_buf_height == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_height");
673 mm_util_retvm_if(result_buf_size == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_size");
675 mm_util_debug("src_w[%u] src_h[%u] src_format[%u] angle[%u]", src_width, src_height, src_format, angle);
677 _mm_util_imgp_func = __mm_util_initialize(IMGP_ROT, src_format, 0, &_module);
678 if (_mm_util_imgp_func == NULL) {
679 mm_util_error("ERROR - __mm_util_initialize");
680 return MM_UTIL_ERROR_INVALID_OPERATION;
683 imgp_info_s *_imgp_info_s = (imgp_info_s *) calloc(1, sizeof(imgp_info_s));
684 if (_imgp_info_s == NULL) {
685 mm_util_error("ERROR - alloc handle");
686 ret = MM_UTIL_ERROR_OUT_OF_MEMORY;
690 if ((angle == MM_UTIL_ROTATE_90) || (angle == MM_UTIL_ROTATE_270)) {
698 ret = __mm_set_imgp_info_s(_imgp_info_s, src_format, src_width, src_height, src_format, res_w, res_h, angle);
699 mm_util_debug("__mm_set_imgp_info_s");
700 if (ret != MM_UTIL_ERROR_NONE) {
701 mm_util_error("__mm_set_imgp_info_s failed");
702 ret = MM_UTIL_ERROR_INVALID_OPERATION;
706 if (g_strrstr(g_module_name(_module), GST)) {
707 if (__mm_gst_can_rotate_format(_imgp_info_s->src_format) == FALSE) {
708 mm_util_error("#gstreamer ROTATE ERROR# IMAGE_NOT_SUPPORT_FORMAT");
709 ret = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
714 ret = _mm_util_imgp_func(_imgp_info_s, src, &output_buffer, IMGP_ROT);
715 if (ret != MM_UTIL_ERROR_NONE) {
716 mm_util_error("image processing failed");
720 if ((_imgp_info_s->dst_width != _imgp_info_s->output_stride || _imgp_info_s->dst_height != _imgp_info_s->output_elevation)) {
721 unsigned int start_x = 0;
722 unsigned int start_y = 0;
723 if (angle == MM_UTIL_ROTATE_90) {
726 } else if (angle == MM_UTIL_ROTATE_180) {
727 start_x = _imgp_info_s->output_stride-_imgp_info_s->dst_width;
729 } else if (angle == MM_UTIL_ROTATE_270) {
731 start_y = _imgp_info_s->output_elevation - _imgp_info_s->dst_height;
733 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);
734 if (ret != MM_UTIL_ERROR_NONE) {
735 mm_util_error("mm_util_crop_image failed");
736 MMUTIL_SAFE_FREE(output_buffer);
737 ret = MM_UTIL_ERROR_INVALID_OPERATION;
741 MMUTIL_SAFE_FREE(output_buffer);
743 *result_buf_size = res_buffer_size;
745 *dst = output_buffer;
746 *result_buf_size = _imgp_info_s->buffer_size;
749 *result_buf_width = res_w;
750 *result_buf_height = res_h;
752 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);
756 __mm_util_imgp_finalize(_module, _imgp_info_s);
763 int mm_util_crop_image(const unsigned char *src, unsigned int src_width, unsigned int src_height, mm_util_color_format_e src_format,
764 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)
766 int ret = MM_UTIL_ERROR_NONE;
767 size_t dst_buf_size = 0;
768 unsigned char *dst_buffer = NULL;
769 unsigned int res_w = 0;
770 unsigned int res_h = 0;
772 mm_util_retvm_if(src == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src");
773 mm_util_retvm_if(src_width == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_width");
774 mm_util_retvm_if(src_height == 0, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_height");
775 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(src_format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src_format [%d]", src_format);
776 mm_util_retvm_if((__mm_util_check_format(src_format) == FALSE), MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported src_format [%d]", src_format);
777 mm_util_retvm_if(dst == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid dst");
778 mm_util_retvm_if(result_buf_width == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_width");
779 mm_util_retvm_if(result_buf_height == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_height");
780 mm_util_retvm_if(result_buf_size == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid result_buf_size");
781 mm_util_retvm_if((crop_start_x + crop_dest_width > src_width), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid position [%d]]", crop_start_x);
782 mm_util_retvm_if((crop_start_y + crop_dest_height > src_height), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid position [%d]", crop_start_y);
784 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]",
785 src, src_width, src_height, src_format, crop_start_x, crop_start_y, crop_dest_width, crop_dest_height);
787 __mm_util_get_crop_image_size(src_format, crop_dest_width, crop_dest_height, &dst_buf_size);
788 mm_util_retvm_if(dst_buf_size == 0, MM_UTIL_ERROR_INVALID_OPERATION, "fail to get dst_buf_size");
790 dst_buffer = calloc(1, dst_buf_size);
791 mm_util_retvm_if(dst_buffer == NULL, MM_UTIL_ERROR_OUT_OF_MEMORY, "memory alloc fail");
793 res_w = crop_dest_width;
794 res_h = crop_dest_height;
796 switch (src_format) {
797 case MM_UTIL_COLOR_RGB24: {
798 ret = __mm_util_crop_rgb888(src, src_width, src_height, crop_start_x, crop_start_y, res_w, res_h, dst_buffer);
801 case MM_UTIL_COLOR_RGB16: {
802 ret = __mm_util_crop_rgb565(src, src_width, src_height, crop_start_x, crop_start_y, res_w, res_h, dst_buffer);
805 case MM_UTIL_COLOR_ARGB:
806 case MM_UTIL_COLOR_BGRA:
807 case MM_UTIL_COLOR_RGBA:
808 case MM_UTIL_COLOR_BGRX: {
809 ret = __mm_util_crop_rgba32(src, src_width, src_height, crop_start_x, crop_start_y, res_w, res_h, dst_buffer);
812 case MM_UTIL_COLOR_I420:
813 case MM_UTIL_COLOR_YUV420: {
814 if ((crop_dest_width % 2) != 0) {
815 mm_util_warn("#YUV Width value(%d) must be even at least# ", crop_dest_width);
816 res_w = ((crop_dest_width+1)>>1)<<1;
817 mm_util_debug("Image isplay is suceeded when YUV crop width value %d", res_w);
820 if ((crop_dest_height % 2) != 0) { /* height value must be also even when crop yuv image */
821 mm_util_warn("#YUV Height value(%d) must be even at least# ", crop_dest_height);
822 res_h = ((crop_dest_height+1)>>1)<<1;
823 mm_util_debug("Image isplay is suceeded when YUV crop height value %d", res_h);
826 MMUTIL_SAFE_FREE(dst_buffer);
827 __mm_util_get_crop_image_size(src_format, res_w, res_h, &dst_buf_size);
828 mm_util_retvm_if(dst_buf_size == 0, MM_UTIL_ERROR_INVALID_OPERATION, "fail to get dst_buf_size");
830 dst_buffer = calloc(1, dst_buf_size);
831 mm_util_retvm_if(dst_buffer == NULL, MM_UTIL_ERROR_OUT_OF_MEMORY, "memory alloc fail");
833 ret = __mm_util_crop_yuv420(src, src_width, src_height, crop_start_x, crop_start_y, res_w, res_h, dst_buffer);
837 mm_util_debug("Not supported format");
838 MMUTIL_SAFE_FREE(dst_buffer);
839 ret = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
842 *result_buf_size = dst_buf_size;
844 *result_buf_width = res_w;
845 *result_buf_height = res_h;
852 int mm_util_get_image_size(mm_util_color_format_e format, unsigned int width, unsigned int height, size_t *imgsize)
854 int ret = MM_UTIL_ERROR_NONE;
855 unsigned char x_chroma_shift = 0;
856 unsigned char y_chroma_shift = 0;
857 int size, w2, h2, size2;
862 mm_util_retvm_if((imgsize == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid imgsize");
863 mm_util_retvm_if((IS_MM_UTIL_COLOR_FORMAT(format) == FALSE), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid format [%d]", format);
864 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");
869 case MM_UTIL_COLOR_I420:
870 case MM_UTIL_COLOR_YUV420:
873 stride = MM_UTIL_ROUND_UP_4(width);
874 h2 = ROUND_UP_X(height, x_chroma_shift);
876 w2 = DIV_ROUND_UP_X(width, x_chroma_shift);
877 stride2 = MM_UTIL_ROUND_UP_4(w2);
878 h2 = DIV_ROUND_UP_X(height, y_chroma_shift);
879 size2 = stride2 * h2;
880 *imgsize = size + 2 * size2;
882 case MM_UTIL_COLOR_YUV422:
883 case MM_UTIL_COLOR_YUYV:
884 case MM_UTIL_COLOR_UYVY:
885 case MM_UTIL_COLOR_NV16:
886 case MM_UTIL_COLOR_NV61:
887 stride = MM_UTIL_ROUND_UP_4(width) * 2;
888 size = stride * height;
892 case MM_UTIL_COLOR_RGB16:
893 stride = MM_UTIL_ROUND_UP_4(width) * 2;
894 size = stride * height;
898 case MM_UTIL_COLOR_RGB24:
899 stride = MM_UTIL_ROUND_UP_4(width) * 3;
900 size = stride * height;
904 case MM_UTIL_COLOR_ARGB:
905 case MM_UTIL_COLOR_BGRA:
906 case MM_UTIL_COLOR_RGBA:
907 case MM_UTIL_COLOR_BGRX:
909 size = stride * height;
913 case MM_UTIL_COLOR_NV12:
914 case MM_UTIL_COLOR_NV12_TILED:
915 case MM_UTIL_COLOR_NV21:
918 stride = MM_UTIL_ROUND_UP_4(width);
919 h2 = ROUND_UP_X(height, y_chroma_shift);
921 w2 = 2 * DIV_ROUND_UP_X(width, x_chroma_shift);
922 stride2 = MM_UTIL_ROUND_UP_4(w2);
923 h2 = DIV_ROUND_UP_X(height, y_chroma_shift);
924 size2 = stride2 * h2;
925 *imgsize = size + size2;
929 mm_util_error("Not supported format");
930 return MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
933 mm_util_debug("format: %u, *imgsize: %u", format, *imgsize);