Apply tizen coding rule
[platform/core/api/image-util.git] / src / image_util.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 #include <dlog.h>
18
19 #include <mm_util_imgp.h>
20 #include <mm_util_jpeg.h>
21 #include <image_util.h>
22 #include <image_util_private.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #define IMAGE_UTIL_STRING_VALID(str)    \
27         ((str != NULL && strlen(str) > 0) ? true : false)
28
29 #define IMAGE_UTIL_SAFE_FREE(src)       { if (src) {free(src); src = NULL; } }
30
31
32 static int _convert_colorspace_tbl[] = {
33         MM_UTIL_IMG_FMT_YUV420,         /* IMAGE_UTIL_COLORSPACE_YUV420 */
34         MM_UTIL_IMG_FMT_YUV422,         /* IMAGE_UTIL_COLORSPACE_YUV422 */
35         MM_UTIL_IMG_FMT_I420,                   /* IMAGE_UTIL_COLORSPACE_I420 */
36         MM_UTIL_IMG_FMT_NV12,                   /* IMAGE_UTIL_COLORSPACE_NV12 */
37         MM_UTIL_IMG_FMT_UYVY,                   /* IMAGE_UTIL_COLORSPACE_UYVY */
38         MM_UTIL_IMG_FMT_YUYV,                   /* IMAGE_UTIL_COLORSPACE_YUYV */
39         MM_UTIL_IMG_FMT_RGB565,         /* IMAGE_UTIL_COLORSPACE_RGB565 */
40         MM_UTIL_IMG_FMT_RGB888,         /* IMAGE_UTIL_COLORSPACE_RGB888 */
41         MM_UTIL_IMG_FMT_ARGB8888,               /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
42         MM_UTIL_IMG_FMT_BGRA8888,               /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
43         MM_UTIL_IMG_FMT_RGBA8888,               /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
44         MM_UTIL_IMG_FMT_BGRX8888,               /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
45         MM_UTIL_JPEG_FMT_NV21,                  /* IMAGE_UTIL_COLORSPACE_NV12 */
46         MM_UTIL_JPEG_FMT_NV16,                  /* IMAGE_UTIL_COLORSPACE_NV16 */
47         MM_UTIL_JPEG_FMT_NV61,                  /* IMAGE_UTIL_COLORSPACE_NV61 */
48 };
49
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 */
66 };
67
68
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,
74 };
75
76 static int _convert_image_util_error_code(const char *func, int code)
77 {
78         int ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
79         char *errorstr = NULL;
80         switch (code) {
81                 case MM_UTIL_ERROR_NONE:
82                         ret = IMAGE_UTIL_ERROR_NONE;
83                         errorstr = strdup("ERROR_NONE");
84                         break;
85                 case MM_UTIL_ERROR_NO_SUCH_FILE:
86                         ret = IMAGE_UTIL_ERROR_NO_SUCH_FILE;
87                         errorstr = strdup("NO_SUCH_FILE");
88                         break;
89                 case MM_UTIL_ERROR_INVALID_PARAMETER:
90                         ret = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
91                         errorstr = strdup("INVALID_PARAMETER");
92                         break;
93                 case MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT:
94                         ret = IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
95                         errorstr = strdup("NOT_SUPPORTED_FORMAT");
96                         break;
97                 case MM_UTIL_ERROR_OUT_OF_MEMORY:
98                         ret = IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
99                         errorstr = strdup("OUT_OF_MEMORY");
100                         break;
101                 case MM_UTIL_ERROR_INVALID_OPERATION:
102                 default:
103                         ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
104                         errorstr = strdup("INVALID_OPERATION");
105
106         }
107
108         image_util_debug("[%s] %s(0x%08x)", func, errorstr, ret);
109         IMAGE_UTIL_SAFE_FREE(errorstr);
110         return ret;
111 }
112
113 static image_util_error_e _image_util_error_convert(int error)
114 {
115         switch (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;
128                         break;
129                 case MM_UTIL_ERROR_INVALID_OPERATION:
130                 default:
131                         image_util_error("INVALID_OPERATION(0x%08x)", error);
132                         return IMAGE_UTIL_ERROR_INVALID_OPERATION;
133         }
134 }
135
136 static void _image_util_transform_completed_cb(media_packet_h *dst, int error, void *user_data)
137 {
138         int error_value = IMAGE_UTIL_ERROR_NONE;
139         image_util_cb_s *_util_cb = (image_util_cb_s *)user_data;
140
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);
144         }
145
146         return;
147 }
148
149 static int _image_util_create_transform_handle(transformation_s *handle)
150 {
151         int err = MM_UTIL_ERROR_NONE;
152         MMHandleType image_h;
153
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);
158         }
159
160         handle->image_h = image_h;
161
162         return _convert_image_util_error_code(__func__, err);
163 }
164
165 static bool _image_util_check_resolution(int width, int height)
166 {
167         if (width <= 0) {
168                 image_util_error("invalid width [%d]", width);
169                 return false;
170         }
171
172         if (height <= 0) {
173                 image_util_error("invalid height [%d]", height);
174                 return false;
175         }
176
177         return true;
178 }
179
180 int image_util_foreach_supported_jpeg_colorspace(image_util_supported_jpeg_colorspace_cb callback, void *user_data)
181 {
182         int i = 0;
183
184         image_util_retvm_if((callback == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "callback is null");
185
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;
191
192         }
193
194         return IMAGE_UTIL_ERROR_NONE;
195 }
196
197 int image_util_transform_create(transformation_h *handle)
198 {
199         int err = MM_UTIL_ERROR_NONE;
200
201         image_util_debug("image_util_create");
202
203         image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
204
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);
207
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;
216
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);
222         }
223
224         *handle = (transformation_h)_handle;
225
226         return _convert_image_util_error_code(__func__, err);
227 }
228
229 int  image_util_transform_set_hardware_acceleration(transformation_h handle, bool mode)
230 {
231         int err = MM_UTIL_ERROR_NONE;
232         transformation_s *_handle = (transformation_s *)handle;
233
234         image_util_debug("Set hardware_acceleration %d", mode);
235
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");
239 #endif
240
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);
245         }
246
247         image_util_debug("Set hardware_acceleration %d", mode);
248         _handle->hardware_acceleration = mode;
249
250         return _convert_image_util_error_code(__func__, err);
251 }
252
253 int image_util_transform_set_colorspace(transformation_h handle, image_util_colorspace_e colorspace)
254 {
255         int err = MM_UTIL_ERROR_NONE;
256         transformation_s *_handle = (transformation_s *)handle;
257
258         image_util_debug("Set colorspace_convert_info [%d]", colorspace);
259
260         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
261
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);
266         }
267
268         _handle->colorspace = colorspace;
269         _handle->set_convert = true;
270
271         return _convert_image_util_error_code(__func__, err);
272 }
273
274 int image_util_transform_set_resolution(transformation_h handle, unsigned int width, unsigned int height)
275 {
276         int err = MM_UTIL_ERROR_NONE;
277         transformation_s *_handle = (transformation_s *)handle;
278
279         image_util_debug("Set resize_info w[%d] h[%d]", width, height);
280
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");
284
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);
289         }
290         _handle->width = width;
291         _handle->height = height;
292         _handle->set_resize  = true;
293
294         return _convert_image_util_error_code(__func__, err);
295 }
296
297 int image_util_transform_set_rotation(transformation_h handle, image_util_rotation_e rotation)
298 {
299         int err = MM_UTIL_ERROR_NONE;
300         transformation_s *_handle = (transformation_s *)handle;
301
302         image_util_debug("Set rotate_info [%d]", rotation);
303
304         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
305
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);
310         }
311         _handle->rotation = rotation;
312         _handle->set_rotate = true;
313
314         return _convert_image_util_error_code(__func__, err);
315 }
316
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)
318 {
319         int err = MM_UTIL_ERROR_NONE;
320         transformation_s *_handle = (transformation_s *)handle;
321         int dest_width;
322         int dest_height;
323
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");
326
327         dest_width = end_x - start_x;
328         dest_height = end_y - start_y;
329
330         image_util_debug("Set crop_info x[%d] y[%d] w[%d] h[%d]", start_x, start_y, dest_width, dest_height);
331
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);
337         }
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;
343
344         return _convert_image_util_error_code(__func__, err);
345 }
346
347 int image_util_transform_get_colorspace(transformation_h handle, image_util_colorspace_e *colorspace)
348 {
349         int ret = IMAGE_UTIL_ERROR_NONE;
350         transformation_s *_handle = (transformation_s *)handle;
351
352         image_util_debug("Get colorspace_convert_info [%d]", colorspace);
353
354         if (_handle == NULL) {
355                 image_util_error("Invalid Handle");
356                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
357         }
358
359         if (!colorspace) {
360                 image_util_error("colorspace area parameter error");
361                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
362         }
363
364         if (!_handle->set_convert) {
365                 image_util_error("Did not set colorspace before");
366                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
367         }
368
369         *colorspace = _handle->colorspace;
370         return ret;
371 }
372
373 int image_util_transform_get_resolution(transformation_h handle, unsigned int *width, unsigned int *height)
374 {
375         int ret = IMAGE_UTIL_ERROR_NONE;
376         transformation_s *_handle = (transformation_s *)handle;
377
378         image_util_debug("Set resize_info w[%d] h[%d]", width, height);
379
380         if (_handle == NULL) {
381                 image_util_error("Invalid Handle");
382                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
383         }
384
385         if (!width || !height) {
386                 image_util_error("resolution area parameter error");
387                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
388         }
389
390         if (!_handle->set_resize) {
391                 image_util_error("Did not set resolution before");
392                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
393         }
394
395         *width = _handle->width;
396         *height = _handle->height;
397
398         return ret;
399 }
400
401 int image_util_transform_get_rotation(transformation_h handle, image_util_rotation_e *rotation)
402 {
403         int ret = IMAGE_UTIL_ERROR_NONE;
404         transformation_s *_handle = (transformation_s *)handle;
405
406         image_util_debug("Set rotate_info [%d]", rotation);
407
408         if (_handle == NULL) {
409                 image_util_error("Invalid Handle");
410                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
411         }
412
413         if (!rotation) {
414                 image_util_error("rotation area parameter error");
415                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
416         }
417
418         if (!_handle->set_rotate) {
419                 image_util_error("Did not set rotation before");
420                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
421         }
422
423         *rotation = _handle->rotation;
424
425         return ret;
426 }
427
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)
429 {
430         int ret = IMAGE_UTIL_ERROR_NONE;
431         transformation_s *_handle = (transformation_s *)handle;
432
433         if (_handle == NULL) {
434                 image_util_error("Invalid Handle");
435                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
436         }
437
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;
441         }
442
443         if (!_handle->set_crop) {
444                 image_util_error("Did not set crop area before");
445                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
446         }
447
448         *start_x = _handle->start_x;
449         *start_y = _handle->start_y;
450         *end_x = _handle->end_x;
451         *end_y = _handle->end_y;
452
453         return ret;
454 }
455
456 int image_util_transform_run(transformation_h handle, media_packet_h src, image_util_transform_completed_cb completed_cb, void *user_data)
457 {
458         int err = MM_UTIL_ERROR_NONE;
459         transformation_s *_handle = (transformation_s *)handle;
460
461         image_util_debug("image_util_transform");
462
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");
467
468         if (_handle->_util_cb != NULL) {
469                 IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
470                 _handle->_util_cb = NULL;
471         }
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");
474
475         _handle->_util_cb->user_data = user_data;
476         _handle->_util_cb->image_processing_completed_cb = completed_cb;
477
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);
480
481         return _convert_image_util_error_code(__func__, err);
482 }
483
484 int image_util_transform_destroy(transformation_h handle)
485 {
486         int err = MM_UTIL_ERROR_NONE;
487         transformation_s *_handle = (transformation_s *)handle;
488
489         image_util_debug("image_util_destroy");
490
491         if (_handle == NULL) {
492                 image_util_error("Invalid Handle");
493                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
494         }
495
496         err = mm_util_destroy(_handle->image_h);
497
498         IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
499         IMAGE_UTIL_SAFE_FREE(_handle);
500
501         return _convert_image_util_error_code(__func__, err);
502 }
503
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)
505 {
506         int err = MM_UTIL_ERROR_NONE;
507
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");
512
513         err = mm_util_convert_colorspace(src, width, height, _convert_colorspace_tbl[src_colorspace], dest, _convert_colorspace_tbl[dest_colorspace]);
514
515         return _convert_image_util_error_code(__func__, err);
516 }
517
518
519 int image_util_calculate_buffer_size(int width, int height, image_util_colorspace_e colorspace , unsigned int *size)
520 {
521         int err = MM_UTIL_ERROR_NONE;
522
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");
526
527         err = mm_util_get_image_size(_convert_colorspace_tbl[colorspace], width, height, size);
528         return _convert_image_util_error_code(__func__, err);
529 }
530
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)
532 {
533         int err = MM_UTIL_ERROR_NONE;
534
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");
540
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;
548         }
549
550         return _convert_image_util_error_code(__func__, err);
551 }
552
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)
554 {
555         int err = MM_UTIL_ERROR_NONE;
556
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");
562
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;
568         }
569         return _convert_image_util_error_code(__func__, err);
570 }
571
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)
573 {
574         int err = MM_UTIL_ERROR_NONE;
575
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");
581
582         unsigned int dest_w, dest_h;
583         dest_w = *width;
584         dest_h = *height;
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;
589         }
590
591         return _convert_image_util_error_code(__func__, err);
592 }
593
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)
595 {
596         int err = MM_UTIL_ERROR_NONE;
597
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");
604
605         mm_util_jpeg_yuv_data decoded;
606         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
607
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;
611                 if (width)
612                         *width = decoded.width;
613                 if (height)
614                         *height = decoded.height;
615                 if (size)
616                         *size = (unsigned int)decoded.size;
617         }
618         return _convert_image_util_error_code(__func__, err);
619 }
620
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)
622 {
623         int err = MM_UTIL_ERROR_NONE;
624
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");
630
631         mm_util_jpeg_yuv_data decoded;
632         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
633
634         err = mm_util_decode_from_jpeg_memory(&decoded, (void *)jpeg_buffer, jpeg_size, _convert_encode_colorspace_tbl[colorspace]);
635
636         if (err == MM_UTIL_ERROR_NONE) {
637                 *image_buffer = decoded.data;
638                 if (width)
639                         *width = decoded.width;
640                 if (height)
641                         *height = decoded.height;
642                 if (size)
643                         *size = (unsigned int)decoded.size;
644         }
645
646         return _convert_image_util_error_code(__func__, err);
647 }
648
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)
650 {
651         int err = MM_UTIL_ERROR_NONE;
652
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");
660
661         mm_util_jpeg_yuv_data decoded;
662         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
663
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;
667                 if (width)
668                         *width = decoded.width;
669                 if (height)
670                         *height = decoded.height;
671                 if (size)
672                         *size = (unsigned int)decoded.size;
673         }
674         return _convert_image_util_error_code(__func__, err);
675 }
676
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)
678 {
679         int err = MM_UTIL_ERROR_NONE;
680
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");
687
688         mm_util_jpeg_yuv_data decoded;
689         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
690
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]);
692
693         if (err == MM_UTIL_ERROR_NONE) {
694                 *image_buffer = decoded.data;
695                 if (width)
696                         *width = decoded.width;
697                 if (height)
698                         *height = decoded.height;
699                 if (size)
700                         *size = (unsigned int)decoded.size;
701         }
702
703         return _convert_image_util_error_code(__func__, err);
704 }
705
706 int image_util_encode_jpeg(const unsigned char *buffer, int width, int height, image_util_colorspace_e colorspace,  int quality, const char *path)
707 {
708         int err = MM_UTIL_ERROR_NONE;
709
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");
715
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);
718 }
719
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)
721 {
722         int err = MM_UTIL_ERROR_NONE;
723         int isize = 0;
724
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");
730
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;
734
735         return _convert_image_util_error_code(__func__, err);
736 }