Apply new coding rule, add macro for logs & remove build warnings
[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 #include <mm_error.h>
26
27 #define IMAGE_UTIL_STRING_VALID(str)    \
28         ((str != NULL && strlen(str) > 0) ? true : false)
29
30 #define IMAGE_UTIL_SAFE_FREE(src)      { if(src) {free(src); src = NULL;}}
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
51 static int _convert_encode_colorspace_tbl[] = {
52         MM_UTIL_JPEG_FMT_YUV420                                         ,       /* IMAGE_UTIL_COLORSPACE_YUV420 */
53         -1                                                                                      ,       /* IMAGE_UTIL_COLORSPACE_YUV422 */
54         MM_UTIL_JPEG_FMT_YUV420                                         ,       /* IMAGE_UTIL_COLORSPACE_I420 */
55         MM_UTIL_JPEG_FMT_NV12                                           ,       /* IMAGE_UTIL_COLORSPACE_NV12 */
56         -1                                                                                      ,       /* IMAGE_UTIL_COLORSPACE_UYVY */
57         -1                                                                                      ,       /* IMAGE_UTIL_COLORSPACE_YUYV */
58         -1                                                                                      ,       /* IMAGE_UTIL_COLORSPACE_RGB565 */
59         MM_UTIL_JPEG_FMT_RGB888                                         ,       /* IMAGE_UTIL_COLORSPACE_RGB888 */
60         MM_UTIL_JPEG_FMT_ARGB8888                                       ,       /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
61         MM_UTIL_JPEG_FMT_BGRA8888                                       ,       /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
62         MM_UTIL_JPEG_FMT_RGBA8888                                       ,       /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
63         -1                                                                                      ,       /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
64         -1                                                                                      ,       /* IMAGE_UTIL_COLORSPACE_NV21 */
65         -1                                                                                      ,       /* IMAGE_UTIL_COLORSPACE_NV16 */
66         -1                                                                                      ,       /* IMAGE_UTIL_COLORSPACE_NV61 */
67 };
68
69
70 static int _convert_decode_scale_tbl[] = {
71         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_1,
72         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_2,
73         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_4,
74         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_8,
75 };
76
77 static int _convert_image_util_error_code(const char *func, int code)
78 {
79         int ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
80         char *errorstr = NULL;
81         switch (code) {
82                 case MM_ERROR_NONE:
83                         ret = IMAGE_UTIL_ERROR_NONE;
84                         errorstr = strdup("ERROR_NONE");
85                         break;
86                 case MM_ERROR_IMAGE_FILEOPEN:
87                 case IMAGE_UTIL_ERROR_NO_SUCH_FILE:
88                         ret = IMAGE_UTIL_ERROR_NO_SUCH_FILE;
89                         errorstr = strdup("NO_SUCH_FILE");
90                         break;
91
92                 case MM_ERROR_IMAGE_INTERNAL:
93                         ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
94                         errorstr = strdup("INVALID_OPERATION");
95                         break;
96                 case IMAGE_UTIL_ERROR_INVALID_PARAMETER:
97                 case MM_ERROR_IMAGEHANDLE_NOT_INITIALIZED:
98                 case MM_ERROR_NO_DECODED_DATA:
99                 case MM_ERROR_IMAGE_INVALID_VALUE:
100                         ret = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
101                         errorstr = strdup("INVALID_PARAMETER");
102                         break;
103                 case MM_ERROR_IMAGE_NOT_SUPPORT_FORMAT:
104                 case MM_ERROR_IMAGE_DEVICE_NOT_SUPPORT:
105                         ret = IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
106                         errorstr = strdup("NOT_SUPPORTED_FORMAT");
107                         break;
108                 case MM_ERROR_IMAGE_NO_FREE_SPACE:
109                         ret = IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
110                         errorstr = strdup("OUT_OF_MEMORY");
111                         break;
112                 default:
113                         ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
114                         errorstr = strdup("INVALID_OPERATION");
115
116         }
117
118         image_util_debug("[%s] %s(0x%08x)", func, errorstr, ret);
119         IMAGE_UTIL_SAFE_FREE(errorstr);
120         return ret;
121 }
122
123 static image_util_error_e _image_util_error_convert(int error)
124 {
125         switch (error) {
126                 case MM_ERROR_NONE:
127                         image_util_debug("Error None");
128                         return IMAGE_UTIL_ERROR_NONE;
129                 case MM_ERROR_IMAGE_INVALID_VALUE:
130                         image_util_error("INVALID_PARAMETER(0x%08x)", IMAGE_UTIL_ERROR_INVALID_PARAMETER);
131                         return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
132                 case MM_ERROR_IMAGE_NOT_SUPPORT_FORMAT:
133                         image_util_error("NOT_SUPPORTED_FORMAT(0x%08x)", IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT);
134                         return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
135                 default:
136                         image_util_error("INVALID_OPERATION(0x%08x)", error);
137                         return IMAGE_UTIL_ERROR_INVALID_OPERATION;
138         }
139 }
140
141 static void _image_util_transform_completed_cb(media_packet_h *dst, int error, void *user_data)
142 {
143         int error_value = IMAGE_UTIL_ERROR_NONE;
144         image_util_cb_s *_util_cb = (image_util_cb_s *)user_data;
145
146         if ((_util_cb != NULL) && (_util_cb->image_processing_completed_cb != NULL)) {
147                 error_value = _image_util_error_convert(error);
148                 _util_cb->image_processing_completed_cb(dst, error_value, _util_cb->user_data);
149         }
150
151         return;
152 }
153
154 static int _image_util_create_transform_handle(transformation_s *handle)
155 {
156         int ret = MM_ERROR_NONE;
157         MMHandleType image_h;
158
159         ret = mm_util_create(&image_h);
160
161         image_util_retvm_if((ret != MM_ERROR_NONE), ret, "Error in mm_util_create");
162
163         handle->image_h = image_h;
164
165         return ret;
166 }
167
168 static bool _image_util_check_resolution(int width, int height)
169 {
170         if (width <= 0) {
171                 image_util_error("invalid width [%d]", width);
172                 return false;
173         }
174
175         if (height <= 0) {
176                 image_util_error("invalid height [%d]", height);
177                 return false;
178         }
179
180         return true;
181 }
182
183 int image_util_foreach_supported_jpeg_colorspace(image_util_supported_jpeg_colorspace_cb callback, void *user_data)
184 {
185         int i = 0;
186
187         if (callback == NULL)
188                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
189         /* RGB has higher precedence than YUV */
190         for (i = sizeof(_convert_encode_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
191                 if (_convert_encode_colorspace_tbl[i] != -1)
192                         if (false == callback(i, user_data))
193                                 return IMAGE_UTIL_ERROR_NONE;
194
195         }
196
197         return IMAGE_UTIL_ERROR_NONE;
198 }
199
200 int image_util_transform_create(transformation_h *handle)
201 {
202         int ret = IMAGE_UTIL_ERROR_NONE;
203
204         image_util_debug("image_util_create");
205
206         image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
207
208         transformation_s *_handle = (transformation_s *)calloc(1, sizeof(transformation_s));
209         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
210
211         _handle->colorspace = -1;
212         _handle->_util_cb = NULL;
213         _handle->image_h = 0;
214         _handle->hardware_acceleration = false;
215         _handle->set_convert = false;
216         _handle->set_resize  = false;
217         _handle->set_rotate = false;
218         _handle->set_crop  = false;
219
220         ret = _image_util_create_transform_handle(_handle);
221         if (ret != MM_ERROR_NONE) {
222                 image_util_error("INVALID_OPERATION");
223                 IMAGE_UTIL_SAFE_FREE(_handle);
224                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
225         }
226
227         *handle = (transformation_h)_handle;
228
229         return _convert_image_util_error_code(__func__, ret);
230 }
231
232 int  image_util_transform_set_hardware_acceleration(transformation_h handle, bool mode)
233 {
234         int ret = IMAGE_UTIL_ERROR_NONE;
235         transformation_s *_handle = (transformation_s *)handle;
236
237         image_util_debug("Set hardware_acceleration %d", mode);
238
239         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
240 #ifndef ENABLE_HW_ACCELERATION
241         image_util_retvm_if((mode == true), IMAGE_UTIL_ERROR_NOT_SUPPORTED, "hardware acceleration is not supported");
242 #endif
243
244         ret = mm_util_set_hardware_acceleration(_handle->image_h, mode);
245         image_util_retvm_if((ret != MM_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Error - Set hardware_acceleration");
246
247         image_util_debug("Set hardware_acceleration %d", mode);
248         _handle->hardware_acceleration = mode;
249
250         return IMAGE_UTIL_ERROR_NONE;
251 }
252
253 int image_util_transform_set_colorspace(transformation_h handle, image_util_colorspace_e colorspace)
254 {
255         int ret = IMAGE_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         ret = mm_util_set_colorspace_convert(_handle->image_h, colorspace);
263         image_util_retvm_if((ret != MM_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_OPERATION, "IMAGE_UTIL_ERROR_INVALID_OPERATION(0x%08x)", IMAGE_UTIL_ERROR_INVALID_OPERATION);
264
265         _handle->colorspace = colorspace;
266         _handle->set_convert = true;
267
268         return _convert_image_util_error_code(__func__, ret);
269 }
270
271 int image_util_transform_set_resolution(transformation_h handle, unsigned int width, unsigned int height)
272 {
273         int ret = IMAGE_UTIL_ERROR_NONE;
274         transformation_s *_handle = (transformation_s *)handle;
275
276         image_util_debug("Set resize_info w[%d] h[%d]", width, height);
277
278         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
279         image_util_retvm_if((_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
280
281         if (_image_util_check_resolution(width, height)) {
282                 ret = mm_util_set_resolution(_handle->image_h, width, height);
283                 image_util_retvm_if((ret != MM_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_OPERATION, "IMAGE_UTIL_ERROR_INVALID_OPERATION(0x%08x)", IMAGE_UTIL_ERROR_INVALID_OPERATION);
284                 _handle->width = width;
285                 _handle->height = height;
286                 _handle->set_resize  = true;
287         } else {
288                 image_util_error("INVALID_PARAMETER");
289                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
290         }
291
292         return _convert_image_util_error_code(__func__, ret);
293 }
294
295 int image_util_transform_set_rotation(transformation_h handle, image_util_rotation_e rotation)
296 {
297         int ret = IMAGE_UTIL_ERROR_NONE;
298         transformation_s *_handle = (transformation_s *)handle;
299
300         image_util_debug("Set rotate_info [%d]", rotation);
301
302         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
303
304         ret = mm_util_set_rotation(_handle->image_h, rotation);
305         image_util_retvm_if((ret != MM_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_OPERATION, "IMAGE_UTIL_ERROR_INVALID_OPERATION(0x%08x)", IMAGE_UTIL_ERROR_INVALID_OPERATION);
306         _handle->rotation = rotation;
307         _handle->set_rotate = true;
308
309         return _convert_image_util_error_code(__func__, ret);
310 }
311
312 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)
313 {
314         int ret = IMAGE_UTIL_ERROR_NONE;
315         transformation_s *_handle = (transformation_s *)handle;
316         int dest_width;
317         int dest_height;
318
319         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
320         image_util_retvm_if((_handle->set_resize), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
321
322         dest_width = end_x - start_x;
323         dest_height = end_y - start_y;
324
325         image_util_debug("Set crop_info x[%d] y[%d] w[%d] h[%d]", start_x, start_y, dest_width, dest_height);
326
327         if (_image_util_check_resolution(dest_width, dest_height)) {
328                 ret = mm_util_set_crop_area(_handle->image_h, start_x, start_y, end_x, end_y);
329                 image_util_retvm_if((ret != MM_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_OPERATION, "IMAGE_UTIL_ERROR_INVALID_OPERATION(0x%08x)", IMAGE_UTIL_ERROR_INVALID_OPERATION);
330                 _handle->start_x = start_x;
331                 _handle->start_y = start_y;
332                 _handle->end_x = end_x;
333                 _handle->end_y = end_y;
334                 _handle->set_crop  = true;
335         } else {
336                 image_util_error("INVALID_PARAMETER");
337                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
338         }
339
340         return _convert_image_util_error_code(__func__, ret);
341 }
342
343 int image_util_transform_get_colorspace(transformation_h handle, image_util_colorspace_e *colorspace)
344 {
345         int ret = IMAGE_UTIL_ERROR_NONE;
346         transformation_s *_handle = (transformation_s *)handle;
347
348         image_util_debug("Get colorspace_convert_info [%d]", colorspace);
349
350         if (_handle == NULL) {
351                 image_util_error("Invalid Handle");
352                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
353         }
354
355         if (!colorspace) {
356                 image_util_error("colorspace area parameter error");
357                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
358         }
359
360         if (!_handle->set_convert) {
361                 image_util_error("Did not set colorspace before");
362                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
363         }
364
365         *colorspace = _handle->colorspace;
366         return ret;
367 }
368
369 int image_util_transform_get_resolution(transformation_h handle, unsigned int *width, unsigned int *height)
370 {
371         int ret = IMAGE_UTIL_ERROR_NONE;
372         transformation_s *_handle = (transformation_s *)handle;
373
374         image_util_debug("Set resize_info w[%d] h[%d]", width, height);
375
376         if (_handle == NULL) {
377                 image_util_error("Invalid Handle");
378                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
379         }
380
381         if (!width || !height) {
382                 image_util_error("resolution area parameter error");
383                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
384         }
385
386         if (!_handle->set_resize) {
387                 image_util_error("Did not set resolution before");
388                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
389         }
390
391         *width = _handle->width;
392         *height = _handle->height;
393
394         return ret;
395 }
396
397 int image_util_transform_get_rotation(transformation_h handle, image_util_rotation_e *rotation)
398 {
399         int ret = IMAGE_UTIL_ERROR_NONE;
400         transformation_s *_handle = (transformation_s *)handle;
401
402         image_util_debug("Set rotate_info [%d]", rotation);
403
404         if (_handle == NULL) {
405                 image_util_error("Invalid Handle");
406                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
407         }
408
409         if (!rotation) {
410                 image_util_error("rotation area parameter error");
411                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
412         }
413
414         if (!_handle->set_rotate) {
415                 image_util_error("Did not set rotation before");
416                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
417         }
418
419         *rotation = _handle->rotation;
420
421         return ret;
422 }
423
424 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)
425 {
426         int ret = IMAGE_UTIL_ERROR_NONE;
427         transformation_s *_handle = (transformation_s *)handle;
428
429         if (_handle == NULL) {
430                 image_util_error("Invalid Handle");
431                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
432         }
433
434         if (!start_x || !start_y || !end_x || !end_y) {
435                 image_util_error("crop area parameter error");
436                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
437         }
438
439         if (!_handle->set_crop) {
440                 image_util_error("Did not set crop area before");
441                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
442         }
443
444         *start_x = _handle->start_x;
445         *start_y = _handle->start_y;
446         *end_x = _handle->end_x;
447         *end_y = _handle->end_y;
448
449         return ret;
450 }
451
452 int image_util_transform_run(transformation_h handle, media_packet_h src, image_util_transform_completed_cb completed_cb, void *user_data)
453 {
454         int ret = IMAGE_UTIL_ERROR_NONE;
455         transformation_s *_handle = (transformation_s *)handle;
456
457         image_util_debug("image_util_transform");
458
459         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
460
461         if (completed_cb) {
462                 if (_handle->_util_cb != NULL) {
463                         IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
464                         _handle->_util_cb = NULL;
465                 }
466                 _handle->_util_cb = (image_util_cb_s *)calloc(1, sizeof(image_util_cb_s));
467                 image_util_retvm_if((_handle->_util_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
468
469                 _handle->_util_cb->user_data = user_data;
470                 _handle->_util_cb->image_processing_completed_cb = completed_cb;
471         } else {
472                 image_util_error("INVALID_PARAMETER[completed_cb](0x%08x)", IMAGE_UTIL_ERROR_INVALID_PARAMETER);
473                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
474         }
475
476         if (_handle->_util_cb && src && (_handle->set_convert || _handle->set_resize || _handle->set_rotate || _handle->set_crop)) {
477                 ret = mm_util_transform(_handle->image_h, src, (mm_util_completed_callback)_image_util_transform_completed_cb, (void *)_handle->_util_cb);
478         } else {
479                 image_util_error("INVALID_PARAMETER[transform] (0x%08x)", IMAGE_UTIL_ERROR_INVALID_PARAMETER);
480                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
481         }
482         return _convert_image_util_error_code(__func__, ret);
483 }
484
485 int image_util_transform_destroy(transformation_h handle)
486 {
487         int ret = IMAGE_UTIL_ERROR_NONE;
488         transformation_s *_handle = (transformation_s *)handle;
489
490         image_util_debug("image_util_destroy");
491
492         if (_handle == NULL) {
493                 image_util_error("Invalid Handle");
494                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
495         }
496
497         ret = mm_util_destroy(_handle->image_h);
498
499         IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
500         IMAGE_UTIL_SAFE_FREE(_handle);
501
502         return _convert_image_util_error_code(__func__, ret);
503 }
504
505 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 {
507         int ret = IMAGE_UTIL_ERROR_NONE;
508
509         if (dest == NULL || src == NULL)
510                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
511         if (dest_colorspace < 0 || dest_colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
512                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
513         if (src_colorspace < 0 || src_colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
514                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
515
516
517         ret = mm_util_convert_colorspace(src, width, height, _convert_colorspace_tbl[src_colorspace], dest, _convert_colorspace_tbl[dest_colorspace]);
518
519         return _convert_image_util_error_code(__func__, ret);
520 }
521
522
523 int image_util_calculate_buffer_size(int width, int height, image_util_colorspace_e colorspace , unsigned int *size)
524 {
525         int ret = IMAGE_UTIL_ERROR_NONE;
526
527         if (colorspace < 0 || width <= 0 || height <= 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int) || size == NULL)
528                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
529
530         ret = mm_util_get_image_size(_convert_colorspace_tbl[colorspace], width, height, size);
531         return _convert_image_util_error_code(__func__, ret);
532 }
533
534 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)
535 {
536         int ret = IMAGE_UTIL_ERROR_NONE;
537
538         if (dest == NULL || src == NULL)
539                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
540         if (colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
541                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
542         if (dest_width == NULL || dest_height == NULL)
543                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
544
545         if (*dest_width <= 0 || *dest_height <= 0)
546                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
547
548         unsigned int dest_w, dest_h;
549         dest_w = *dest_width;
550         dest_h = *dest_height;
551         ret = mm_util_resize_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], dest, &dest_w, &dest_h);
552         if (ret == 0) {
553                 *dest_width = dest_w;
554                 *dest_height = dest_h;
555         }
556
557         return _convert_image_util_error_code(__func__, ret);
558 }
559
560 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)
561 {
562         int ret = IMAGE_UTIL_ERROR_NONE;
563
564         if (dest == NULL || src == NULL)
565                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
566         if (colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
567                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
568         if (dest_rotation < 0 || dest_rotation > IMAGE_UTIL_ROTATION_FLIP_VERT)
569                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
570         if (dest_width == NULL || dest_height == NULL)
571                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
572
573         unsigned int dest_w, dest_h;
574         ret = mm_util_rotate_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], dest, &dest_w, &dest_h, dest_rotation);
575         if (ret == 0) {
576                 *dest_width = dest_w;
577                 *dest_height = dest_h;
578         }
579         return _convert_image_util_error_code(__func__, ret);
580 }
581
582 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)
583 {
584         int ret = IMAGE_UTIL_ERROR_NONE;
585
586         if (dest == NULL || src == NULL)
587                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
588         if (colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
589                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
590         if (width == NULL)
591                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
592         if (src_width <= x  || src_height <= y || src_width < x + *width || src_height < y + *height)
593                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
594
595         unsigned int dest_w, dest_h;
596         dest_w = *width;
597         dest_h = *height;
598         ret = mm_util_crop_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], x, y, &dest_w, &dest_h, dest);
599         if (ret == 0) {
600                 *width = dest_w;
601                 *height = dest_h;
602         }
603
604         return _convert_image_util_error_code(__func__, ret);
605 }
606
607 int image_util_decode_jpeg(const char *path, image_util_colorspace_e colorspace, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
608 {
609         int ret = IMAGE_UTIL_ERROR_NONE;
610
611         if (path == NULL || image_buffer == NULL || size == NULL)
612                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
613         if (strlen(path) == 0)
614                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_NO_SUCH_FILE);
615         if (colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
616                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
617         if (_convert_encode_colorspace_tbl[colorspace] == -1)
618                 return _convert_image_util_error_code(__func__, MM_ERROR_IMAGE_NOT_SUPPORT_FORMAT);
619
620         mm_util_jpeg_yuv_data decoded;
621         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
622
623         ret = mm_util_decode_from_jpeg_file(&decoded, path, _convert_encode_colorspace_tbl[colorspace]);
624         if (ret == 0) {
625                 *image_buffer = decoded.data;
626                 if (width)
627                         *width = decoded.width;
628                 if (height)
629                         *height = decoded.height;
630                 if (size)
631                         *size = decoded.size;
632         }
633         return _convert_image_util_error_code(__func__, ret);
634 }
635
636 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)
637 {
638         int ret = IMAGE_UTIL_ERROR_NONE;
639
640         if (jpeg_buffer == NULL || image_buffer == NULL || size == NULL)
641                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
642         if (colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
643                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
644         if (_convert_encode_colorspace_tbl[colorspace] == -1)
645                 return _convert_image_util_error_code(__func__, MM_ERROR_IMAGE_NOT_SUPPORT_FORMAT);
646
647         mm_util_jpeg_yuv_data decoded;
648         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
649
650         ret = mm_util_decode_from_jpeg_memory(&decoded, (void *)jpeg_buffer, jpeg_size, _convert_encode_colorspace_tbl[colorspace]);
651
652         if (ret == 0) {
653                 *image_buffer = decoded.data;
654                 if (width)
655                         *width = decoded.width;
656                 if (height)
657                         *height = decoded.height;
658                 if (size)
659                         *size = decoded.size;
660         }
661
662         return _convert_image_util_error_code(__func__, ret);
663 }
664
665 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)
666 {
667         int ret = IMAGE_UTIL_ERROR_NONE;
668
669         if (path == NULL || image_buffer == NULL || size == NULL)
670                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
671         if (strlen(path) == 0)
672                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_NO_SUCH_FILE);
673         if (colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
674                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
675         if (_convert_encode_colorspace_tbl[colorspace] == -1)
676                 return _convert_image_util_error_code(__func__, MM_ERROR_IMAGE_NOT_SUPPORT_FORMAT);
677         if (downscale < 0 || downscale >= sizeof(_convert_decode_scale_tbl) / sizeof(int))
678                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
679
680         mm_util_jpeg_yuv_data decoded;
681         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
682
683         ret = mm_util_decode_from_jpeg_file_with_downscale(&decoded, path, _convert_encode_colorspace_tbl[colorspace], _convert_decode_scale_tbl[downscale]);
684         if (ret == 0) {
685                 *image_buffer = decoded.data;
686                 if (width)
687                         *width = decoded.width;
688                 if (height)
689                         *height = decoded.height;
690                 if (size)
691                         *size = decoded.size;
692         }
693         return _convert_image_util_error_code(__func__, ret);
694 }
695
696 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)
697 {
698         int ret = IMAGE_UTIL_ERROR_NONE;
699
700         if (jpeg_buffer == NULL || image_buffer == NULL || size == NULL)
701                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
702         if (colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
703                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
704         if (_convert_encode_colorspace_tbl[colorspace] == -1)
705                 return _convert_image_util_error_code(__func__, MM_ERROR_IMAGE_NOT_SUPPORT_FORMAT);
706         if (downscale < 0 || downscale >= sizeof(_convert_decode_scale_tbl) / sizeof(int))
707                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
708
709         mm_util_jpeg_yuv_data decoded;
710         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
711
712         ret = mm_util_decode_from_jpeg_memory_with_downscale(&decoded, (void *)jpeg_buffer, jpeg_size, _convert_encode_colorspace_tbl[colorspace], _convert_decode_scale_tbl[downscale]);
713
714         if (ret == 0) {
715                 *image_buffer = decoded.data;
716                 if (width)
717                         *width = decoded.width;
718                 if (height)
719                         *height = decoded.height;
720                 if (size)
721                         *size = decoded.size;
722         }
723
724         return _convert_image_util_error_code(__func__, ret);
725 }
726
727 int image_util_encode_jpeg(const unsigned char *buffer, int width, int height, image_util_colorspace_e colorspace,  int quality, const char *path)
728 {
729         int ret = IMAGE_UTIL_ERROR_NONE;
730
731         if (path == NULL || buffer == NULL)
732                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
733         if (strlen(path) == 0)
734                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_NO_SUCH_FILE);
735         if (colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
736                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
737         if (_convert_encode_colorspace_tbl[colorspace] == -1)
738                 return _convert_image_util_error_code(__func__, MM_ERROR_IMAGE_NOT_SUPPORT_FORMAT);
739
740         ret = mm_util_jpeg_encode_to_file(path, (void *)buffer, width, height, _convert_encode_colorspace_tbl[colorspace], quality);
741         return _convert_image_util_error_code(__func__, ret);
742 }
743
744 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)
745 {
746         int ret = IMAGE_UTIL_ERROR_NONE;
747         int isize;
748
749         if (jpeg_buffer == NULL || image_buffer == NULL || jpeg_size == NULL)
750                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
751         if (colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int))
752                 return _convert_image_util_error_code(__func__, IMAGE_UTIL_ERROR_INVALID_PARAMETER);
753         if (_convert_encode_colorspace_tbl[colorspace] == -1)
754                 return _convert_image_util_error_code(__func__, MM_ERROR_IMAGE_NOT_SUPPORT_FORMAT);
755
756         ret = mm_util_jpeg_encode_to_memory((void **)jpeg_buffer, &isize, (void *)image_buffer, width, height, _convert_encode_colorspace_tbl[colorspace], quality);
757         if (ret == 0)
758                 *jpeg_size = isize;
759
760         return _convert_image_util_error_code(__func__, ret);
761 }