2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <mm_util_imgp.h>
20 #include <mm_util_jpeg.h>
21 #include <image_util.h>
22 #include <image_util_private.h>
26 #define IMAGE_UTIL_STRING_VALID(str) \
27 ((str != NULL && strlen(str) > 0) ? true : false)
29 #define IMAGE_UTIL_SAFE_FREE(src) { if(src) {free(src); src = NULL;}}
31 static int _convert_colorspace_tbl[] = {
32 MM_UTIL_IMG_FMT_YUV420, /* IMAGE_UTIL_COLORSPACE_YUV420 */
33 MM_UTIL_IMG_FMT_YUV422, /* IMAGE_UTIL_COLORSPACE_YUV422 */
34 MM_UTIL_IMG_FMT_I420, /* IMAGE_UTIL_COLORSPACE_I420 */
35 MM_UTIL_IMG_FMT_NV12, /* IMAGE_UTIL_COLORSPACE_NV12 */
36 MM_UTIL_IMG_FMT_UYVY, /* IMAGE_UTIL_COLORSPACE_UYVY */
37 MM_UTIL_IMG_FMT_YUYV, /* IMAGE_UTIL_COLORSPACE_YUYV */
38 MM_UTIL_IMG_FMT_RGB565, /* IMAGE_UTIL_COLORSPACE_RGB565 */
39 MM_UTIL_IMG_FMT_RGB888, /* IMAGE_UTIL_COLORSPACE_RGB888 */
40 MM_UTIL_IMG_FMT_ARGB8888, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
41 MM_UTIL_IMG_FMT_BGRA8888, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
42 MM_UTIL_IMG_FMT_RGBA8888, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
43 MM_UTIL_IMG_FMT_BGRX8888, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
44 MM_UTIL_JPEG_FMT_NV21, /* IMAGE_UTIL_COLORSPACE_NV12 */
45 MM_UTIL_JPEG_FMT_NV16, /* IMAGE_UTIL_COLORSPACE_NV16 */
46 MM_UTIL_JPEG_FMT_NV61, /* IMAGE_UTIL_COLORSPACE_NV61 */
50 static int _convert_encode_colorspace_tbl[] = {
51 MM_UTIL_JPEG_FMT_YUV420 , /* IMAGE_UTIL_COLORSPACE_YUV420 */
52 -1 , /* IMAGE_UTIL_COLORSPACE_YUV422 */
53 MM_UTIL_JPEG_FMT_YUV420 , /* IMAGE_UTIL_COLORSPACE_I420 */
54 MM_UTIL_JPEG_FMT_NV12 , /* IMAGE_UTIL_COLORSPACE_NV12 */
55 -1 , /* IMAGE_UTIL_COLORSPACE_UYVY */
56 -1 , /* IMAGE_UTIL_COLORSPACE_YUYV */
57 -1 , /* IMAGE_UTIL_COLORSPACE_RGB565 */
58 MM_UTIL_JPEG_FMT_RGB888 , /* IMAGE_UTIL_COLORSPACE_RGB888 */
59 MM_UTIL_JPEG_FMT_ARGB8888 , /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
60 MM_UTIL_JPEG_FMT_BGRA8888 , /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
61 MM_UTIL_JPEG_FMT_RGBA8888 , /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
62 -1 , /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
63 -1 , /* IMAGE_UTIL_COLORSPACE_NV21 */
64 -1 , /* IMAGE_UTIL_COLORSPACE_NV16 */
65 -1 , /* IMAGE_UTIL_COLORSPACE_NV61 */
69 static int _convert_decode_scale_tbl[] = {
70 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_1,
71 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_2,
72 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_4,
73 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_8,
76 static int _convert_image_util_error_code(const char *func, int code)
78 int ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
79 char *errorstr = NULL;
81 case MM_UTIL_ERROR_NONE:
82 ret = IMAGE_UTIL_ERROR_NONE;
83 errorstr = strdup("ERROR_NONE");
85 case MM_UTIL_ERROR_NO_SUCH_FILE:
86 ret = IMAGE_UTIL_ERROR_NO_SUCH_FILE;
87 errorstr = strdup("NO_SUCH_FILE");
89 case MM_UTIL_ERROR_INVALID_PARAMETER:
90 ret = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
91 errorstr = strdup("INVALID_PARAMETER");
93 case MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT:
94 ret = IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
95 errorstr = strdup("NOT_SUPPORTED_FORMAT");
97 case MM_UTIL_ERROR_OUT_OF_MEMORY:
98 ret = IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
99 errorstr = strdup("OUT_OF_MEMORY");
101 case MM_UTIL_ERROR_INVALID_OPERATION:
103 ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
104 errorstr = strdup("INVALID_OPERATION");
108 image_util_debug("[%s] %s(0x%08x)", func, errorstr, ret);
109 IMAGE_UTIL_SAFE_FREE(errorstr);
113 static image_util_error_e _image_util_error_convert(int error)
116 case MM_UTIL_ERROR_NONE:
117 image_util_debug("Error None");
118 return IMAGE_UTIL_ERROR_NONE;
119 case MM_UTIL_ERROR_INVALID_PARAMETER:
120 image_util_error("INVALID_PARAMETER(0x%08x)", IMAGE_UTIL_ERROR_INVALID_PARAMETER);
121 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
122 case MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT:
123 image_util_error("NOT_SUPPORTED_FORMAT(0x%08x)", IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT);
124 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
125 case MM_UTIL_ERROR_OUT_OF_MEMORY:
126 image_util_error("OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
127 return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
129 case MM_UTIL_ERROR_INVALID_OPERATION:
131 image_util_error("INVALID_OPERATION(0x%08x)", error);
132 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
136 static void _image_util_transform_completed_cb(media_packet_h *dst, int error, void *user_data)
138 int error_value = IMAGE_UTIL_ERROR_NONE;
139 image_util_cb_s *_util_cb = (image_util_cb_s *)user_data;
141 if ((_util_cb != NULL) && (_util_cb->image_processing_completed_cb != NULL)) {
142 error_value = _image_util_error_convert(error);
143 _util_cb->image_processing_completed_cb(dst, error_value, _util_cb->user_data);
149 static int _image_util_create_transform_handle(transformation_s *handle)
151 int err = MM_UTIL_ERROR_NONE;
152 MMHandleType image_h;
154 err = mm_util_create(&image_h);
155 if (err != MM_UTIL_ERROR_NONE) {
156 image_util_error("Error - mm_util_create");
157 return _convert_image_util_error_code(__func__, err);
160 handle->image_h = image_h;
162 return _convert_image_util_error_code(__func__, err);
165 static bool _image_util_check_resolution(int width, int height)
168 image_util_error("invalid width [%d]", width);
173 image_util_error("invalid height [%d]", height);
180 int image_util_foreach_supported_jpeg_colorspace(image_util_supported_jpeg_colorspace_cb callback, void *user_data)
184 image_util_retvm_if((callback == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "callback is null");
186 /* RGB has higher precedence than YUV */
187 for (i = sizeof(_convert_encode_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
188 if (_convert_encode_colorspace_tbl[i] != -1)
189 if (false == callback(i, user_data))
190 return IMAGE_UTIL_ERROR_NONE;
194 return IMAGE_UTIL_ERROR_NONE;
197 int image_util_transform_create(transformation_h *handle)
199 int err = MM_UTIL_ERROR_NONE;
201 image_util_debug("image_util_create");
203 image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
205 transformation_s *_handle = (transformation_s *)calloc(1, sizeof(transformation_s));
206 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
208 _handle->colorspace = -1;
209 _handle->_util_cb = NULL;
210 _handle->image_h = 0;
211 _handle->hardware_acceleration = false;
212 _handle->set_convert = false;
213 _handle->set_resize = false;
214 _handle->set_rotate = false;
215 _handle->set_crop = false;
217 err = _image_util_create_transform_handle(_handle);
218 if (err != MM_UTIL_ERROR_NONE) {
219 image_util_error("Error - create transform handle");
220 IMAGE_UTIL_SAFE_FREE(_handle);
221 return _convert_image_util_error_code(__func__, err);
224 *handle = (transformation_h)_handle;
226 return _convert_image_util_error_code(__func__, err);
229 int image_util_transform_set_hardware_acceleration(transformation_h handle, bool mode)
231 int err = MM_UTIL_ERROR_NONE;
232 transformation_s *_handle = (transformation_s *)handle;
234 image_util_debug("Set hardware_acceleration %d", mode);
236 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
237 #ifndef ENABLE_HW_ACCELERATION
238 image_util_retvm_if((mode == true), IMAGE_UTIL_ERROR_NOT_SUPPORTED, "hardware acceleration is not supported");
241 err = mm_util_set_hardware_acceleration(_handle->image_h, mode);
242 if (err != MM_UTIL_ERROR_NONE) {
243 image_util_error("Error - Set hardware_acceleration");
244 return _convert_image_util_error_code(__func__, err);
247 image_util_debug("Set hardware_acceleration %d", mode);
248 _handle->hardware_acceleration = mode;
250 return _convert_image_util_error_code(__func__, err);
253 int image_util_transform_set_colorspace(transformation_h handle, image_util_colorspace_e colorspace)
255 int err = MM_UTIL_ERROR_NONE;
256 transformation_s *_handle = (transformation_s *)handle;
258 image_util_debug("Set colorspace_convert_info [%d]", colorspace);
260 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
262 err = mm_util_set_colorspace_convert(_handle->image_h, colorspace);
263 if (err != MM_UTIL_ERROR_NONE) {
264 image_util_error("Error - Set colorspace convert");
265 return _convert_image_util_error_code(__func__, err);
268 _handle->colorspace = colorspace;
269 _handle->set_convert = true;
271 return _convert_image_util_error_code(__func__, err);
274 int image_util_transform_set_resolution(transformation_h handle, unsigned int width, unsigned int height)
276 int err = MM_UTIL_ERROR_NONE;
277 transformation_s *_handle = (transformation_s *)handle;
279 image_util_debug("Set resize_info w[%d] h[%d]", width, height);
281 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
282 image_util_retvm_if((_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
283 image_util_retvm_if((_image_util_check_resolution(width, height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
285 err = mm_util_set_resolution(_handle->image_h, width, height);
286 if (err != MM_UTIL_ERROR_NONE) {
287 image_util_error("Error - Set resolution");
288 return _convert_image_util_error_code(__func__, err);
290 _handle->width = width;
291 _handle->height = height;
292 _handle->set_resize = true;
294 return _convert_image_util_error_code(__func__, err);
297 int image_util_transform_set_rotation(transformation_h handle, image_util_rotation_e rotation)
299 int err = MM_UTIL_ERROR_NONE;
300 transformation_s *_handle = (transformation_s *)handle;
302 image_util_debug("Set rotate_info [%d]", rotation);
304 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
306 err = mm_util_set_rotation(_handle->image_h, rotation);
307 if (err != MM_UTIL_ERROR_NONE) {
308 image_util_error("Error - Set rotation");
309 return _convert_image_util_error_code(__func__, err);
311 _handle->rotation = rotation;
312 _handle->set_rotate = true;
314 return _convert_image_util_error_code(__func__, err);
317 int image_util_transform_set_crop_area(transformation_h handle, unsigned int start_x, unsigned int start_y, unsigned int end_x, unsigned int end_y)
319 int err = MM_UTIL_ERROR_NONE;
320 transformation_s *_handle = (transformation_s *)handle;
324 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
325 image_util_retvm_if((_handle->set_resize), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
327 dest_width = end_x - start_x;
328 dest_height = end_y - start_y;
330 image_util_debug("Set crop_info x[%d] y[%d] w[%d] h[%d]", start_x, start_y, dest_width, dest_height);
332 image_util_retvm_if((_image_util_check_resolution(dest_width, dest_height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dest resolution");
333 err = mm_util_set_crop_area(_handle->image_h, start_x, start_y, end_x, end_y);
334 if (err != MM_UTIL_ERROR_NONE) {
335 image_util_error("Error - Set crop area");
336 return _convert_image_util_error_code(__func__, err);
338 _handle->start_x = start_x;
339 _handle->start_y = start_y;
340 _handle->end_x = end_x;
341 _handle->end_y = end_y;
342 _handle->set_crop = true;
344 return _convert_image_util_error_code(__func__, err);
347 int image_util_transform_get_colorspace(transformation_h handle, image_util_colorspace_e *colorspace)
349 int ret = IMAGE_UTIL_ERROR_NONE;
350 transformation_s *_handle = (transformation_s *)handle;
352 image_util_debug("Get colorspace_convert_info [%d]", colorspace);
354 if (_handle == NULL) {
355 image_util_error("Invalid Handle");
356 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
360 image_util_error("colorspace area parameter error");
361 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
364 if (!_handle->set_convert) {
365 image_util_error("Did not set colorspace before");
366 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
369 *colorspace = _handle->colorspace;
373 int image_util_transform_get_resolution(transformation_h handle, unsigned int *width, unsigned int *height)
375 int ret = IMAGE_UTIL_ERROR_NONE;
376 transformation_s *_handle = (transformation_s *)handle;
378 image_util_debug("Set resize_info w[%d] h[%d]", width, height);
380 if (_handle == NULL) {
381 image_util_error("Invalid Handle");
382 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
385 if (!width || !height) {
386 image_util_error("resolution area parameter error");
387 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
390 if (!_handle->set_resize) {
391 image_util_error("Did not set resolution before");
392 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
395 *width = _handle->width;
396 *height = _handle->height;
401 int image_util_transform_get_rotation(transformation_h handle, image_util_rotation_e *rotation)
403 int ret = IMAGE_UTIL_ERROR_NONE;
404 transformation_s *_handle = (transformation_s *)handle;
406 image_util_debug("Set rotate_info [%d]", rotation);
408 if (_handle == NULL) {
409 image_util_error("Invalid Handle");
410 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
414 image_util_error("rotation area parameter error");
415 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
418 if (!_handle->set_rotate) {
419 image_util_error("Did not set rotation before");
420 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
423 *rotation = _handle->rotation;
428 int image_util_transform_get_crop_area(transformation_h handle, unsigned int *start_x, unsigned int *start_y, unsigned int *end_x, unsigned int *end_y)
430 int ret = IMAGE_UTIL_ERROR_NONE;
431 transformation_s *_handle = (transformation_s *)handle;
433 if (_handle == NULL) {
434 image_util_error("Invalid Handle");
435 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
438 if (!start_x || !start_y || !end_x || !end_y) {
439 image_util_error("crop area parameter error");
440 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
443 if (!_handle->set_crop) {
444 image_util_error("Did not set crop area before");
445 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
448 *start_x = _handle->start_x;
449 *start_y = _handle->start_y;
450 *end_x = _handle->end_x;
451 *end_y = _handle->end_y;
456 int image_util_transform_run(transformation_h handle, media_packet_h src, image_util_transform_completed_cb completed_cb, void *user_data)
458 int err = MM_UTIL_ERROR_NONE;
459 transformation_s *_handle = (transformation_s *)handle;
461 image_util_debug("image_util_transform");
463 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
464 image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
465 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid source");
466 image_util_retvm_if((!_handle->set_convert && !_handle->set_resize && !_handle->set_rotate && !_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid transform");
468 if (_handle->_util_cb != NULL) {
469 IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
470 _handle->_util_cb = NULL;
472 _handle->_util_cb = (image_util_cb_s *)calloc(1, sizeof(image_util_cb_s));
473 image_util_retvm_if((_handle->_util_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
475 _handle->_util_cb->user_data = user_data;
476 _handle->_util_cb->image_processing_completed_cb = completed_cb;
478 if (_handle->_util_cb) {
479 err = mm_util_transform(_handle->image_h, src, (mm_util_completed_callback)_image_util_transform_completed_cb, (void *)_handle->_util_cb);
481 return _convert_image_util_error_code(__func__, err);
484 int image_util_transform_destroy(transformation_h handle)
486 int err = MM_UTIL_ERROR_NONE;
487 transformation_s *_handle = (transformation_s *)handle;
489 image_util_debug("image_util_destroy");
491 if (_handle == NULL) {
492 image_util_error("Invalid Handle");
493 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
496 err = mm_util_destroy(_handle->image_h);
498 IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
499 IMAGE_UTIL_SAFE_FREE(_handle);
501 return _convert_image_util_error_code(__func__, err);
504 int image_util_convert_colorspace(unsigned char *dest, image_util_colorspace_e dest_colorspace, const unsigned char *src, int width, int height, image_util_colorspace_e src_colorspace)
506 int err = MM_UTIL_ERROR_NONE;
508 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
509 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
510 image_util_retvm_if((dest_colorspace < 0 || dest_colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dst_colorspace");
511 image_util_retvm_if((src_colorspace < 0 || src_colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid src_colorspace");
513 err = mm_util_convert_colorspace(src, width, height, _convert_colorspace_tbl[src_colorspace], dest, _convert_colorspace_tbl[dest_colorspace]);
515 return _convert_image_util_error_code(__func__, err);
519 int image_util_calculate_buffer_size(int width, int height, image_util_colorspace_e colorspace , unsigned int *size)
521 int err = MM_UTIL_ERROR_NONE;
523 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
524 image_util_retvm_if((width <= 0 || height <= 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid width or Invalid height");
525 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
527 err = mm_util_get_image_size(_convert_colorspace_tbl[colorspace], width, height, size);
528 return _convert_image_util_error_code(__func__, err);
531 int image_util_resize(unsigned char *dest, int *dest_width, int *dest_height, const unsigned char *src, int src_width, int src_height, image_util_colorspace_e colorspace)
533 int err = MM_UTIL_ERROR_NONE;
535 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
536 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
537 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
538 image_util_retvm_if((dest_width == NULL || dest_height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest_width or dest_height is null");
539 image_util_retvm_if((*dest_width <= 0 || *dest_height <= 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dest_width or Invalid dest_height");
541 unsigned int dest_w, dest_h;
542 dest_w = *dest_width;
543 dest_h = *dest_height;
544 err = mm_util_resize_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], dest, &dest_w, &dest_h);
545 if (err == MM_UTIL_ERROR_NONE) {
546 *dest_width = (int)dest_w;
547 *dest_height = (int)dest_h;
550 return _convert_image_util_error_code(__func__, err);
553 int image_util_rotate(unsigned char *dest, int *dest_width, int *dest_height, image_util_rotation_e dest_rotation, const unsigned char *src, int src_width, int src_height, image_util_colorspace_e colorspace)
555 int err = MM_UTIL_ERROR_NONE;
557 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
558 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
559 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
560 image_util_retvm_if((dest_rotation < 0 || dest_rotation > IMAGE_UTIL_ROTATION_FLIP_VERT), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid rotation");
561 image_util_retvm_if((dest_width == NULL || dest_height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest_width or dest_height is null");
563 unsigned int dest_w, dest_h;
564 err = mm_util_rotate_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], dest, &dest_w, &dest_h, dest_rotation);
565 if (err == MM_UTIL_ERROR_NONE) {
566 *dest_width = (int)dest_w;
567 *dest_height = (int)dest_h;
569 return _convert_image_util_error_code(__func__, err);
572 int image_util_crop(unsigned char *dest, int x, int y, int *width, int *height, const unsigned char *src, int src_width, int src_height, image_util_colorspace_e colorspace)
574 int err = MM_UTIL_ERROR_NONE;
576 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
577 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
578 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
579 image_util_retvm_if((width == NULL || height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "width or height is null");
580 image_util_retvm_if((src_width <= x || src_height <= y || src_width < x + *width || src_height < y + *height), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid crop area");
582 unsigned int dest_w, dest_h;
585 err = mm_util_crop_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], x, y, &dest_w, &dest_h, dest);
586 if (err == MM_UTIL_ERROR_NONE) {
587 *width = (int)dest_w;
588 *height = (int)dest_h;
591 return _convert_image_util_error_code(__func__, err);
594 int image_util_decode_jpeg(const char *path, image_util_colorspace_e colorspace, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
596 int err = MM_UTIL_ERROR_NONE;
598 image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
599 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
600 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
601 image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
602 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
603 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
605 mm_util_jpeg_yuv_data decoded;
606 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
608 err = mm_util_decode_from_jpeg_file(&decoded, path, _convert_encode_colorspace_tbl[colorspace]);
609 if (err == MM_UTIL_ERROR_NONE) {
610 *image_buffer = decoded.data;
612 *width = decoded.width;
614 *height = decoded.height;
616 *size = (unsigned int)decoded.size;
618 return _convert_image_util_error_code(__func__, err);
621 int image_util_decode_jpeg_from_memory(const unsigned char *jpeg_buffer, int jpeg_size, image_util_colorspace_e colorspace, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
623 int err = MM_UTIL_ERROR_NONE;
625 image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
626 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
627 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
628 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
629 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
631 mm_util_jpeg_yuv_data decoded;
632 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
634 err = mm_util_decode_from_jpeg_memory(&decoded, (void *)jpeg_buffer, jpeg_size, _convert_encode_colorspace_tbl[colorspace]);
636 if (err == MM_UTIL_ERROR_NONE) {
637 *image_buffer = decoded.data;
639 *width = decoded.width;
641 *height = decoded.height;
643 *size = (unsigned int)decoded.size;
646 return _convert_image_util_error_code(__func__, err);
649 int image_util_decode_jpeg_with_downscale(const char *path, image_util_colorspace_e colorspace, image_util_scale_e downscale, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
651 int err = MM_UTIL_ERROR_NONE;
653 image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
654 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
655 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
656 image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
657 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
658 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
659 image_util_retvm_if((downscale < 0 || downscale >= sizeof(_convert_decode_scale_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downsacle is invalid");
661 mm_util_jpeg_yuv_data decoded;
662 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
664 err = mm_util_decode_from_jpeg_file_with_downscale(&decoded, path, _convert_encode_colorspace_tbl[colorspace], _convert_decode_scale_tbl[downscale]);
665 if (err == MM_UTIL_ERROR_NONE) {
666 *image_buffer = decoded.data;
668 *width = decoded.width;
670 *height = decoded.height;
672 *size = (unsigned int)decoded.size;
674 return _convert_image_util_error_code(__func__, err);
677 int image_util_decode_jpeg_from_memory_with_downscale(const unsigned char *jpeg_buffer, int jpeg_size, image_util_colorspace_e colorspace, image_util_scale_e downscale, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
679 int err = MM_UTIL_ERROR_NONE;
681 image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
682 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
683 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
684 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
685 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
686 image_util_retvm_if((downscale < 0 || downscale >= sizeof(_convert_decode_scale_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downsacle is invalid");
688 mm_util_jpeg_yuv_data decoded;
689 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
691 err = mm_util_decode_from_jpeg_memory_with_downscale(&decoded, (void *)jpeg_buffer, jpeg_size, _convert_encode_colorspace_tbl[colorspace], _convert_decode_scale_tbl[downscale]);
693 if (err == MM_UTIL_ERROR_NONE) {
694 *image_buffer = decoded.data;
696 *width = decoded.width;
698 *height = decoded.height;
700 *size = (unsigned int)decoded.size;
703 return _convert_image_util_error_code(__func__, err);
706 int image_util_encode_jpeg(const unsigned char *buffer, int width, int height, image_util_colorspace_e colorspace, int quality, const char *path)
708 int err = MM_UTIL_ERROR_NONE;
710 image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
711 image_util_retvm_if((buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "buffer is null");
712 image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
713 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
714 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
716 err = mm_util_jpeg_encode_to_file(path, (void *)buffer, width, height, _convert_encode_colorspace_tbl[colorspace], quality);
717 return _convert_image_util_error_code(__func__, err);
720 int image_util_encode_jpeg_to_memory(const unsigned char *image_buffer, int width, int height, image_util_colorspace_e colorspace, int quality, unsigned char **jpeg_buffer, unsigned int *jpeg_size)
722 int err = MM_UTIL_ERROR_NONE;
725 image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
726 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
727 image_util_retvm_if((jpeg_size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_size is null");
728 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
729 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
731 err = mm_util_jpeg_encode_to_memory((void **)jpeg_buffer, &isize, (void *)image_buffer, width, height, _convert_encode_colorspace_tbl[colorspace], quality);
732 if (err == MM_UTIL_ERROR_NONE)
733 *jpeg_size = (unsigned int)isize;
735 return _convert_image_util_error_code(__func__, err);