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 <mm_util_png.h>
22 #include <mm_util_gif.h>
23 #include <mm_util_bmp.h>
24 #include <image_util.h>
25 #include <image_util_private.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 #define IMAGE_UTIL_STRING_VALID(str)    \
30         ((str != NULL && strlen(str) > 0) ? true : false)
31
32 #define IMAGE_UTIL_SAFE_FREE(src)       { if (src) {free(src); src = NULL; } }
33
34 static int _convert_colorspace_tbl[] = {
35         MM_UTIL_IMG_FMT_YUV420,         /* IMAGE_UTIL_COLORSPACE_YUV420 */
36         MM_UTIL_IMG_FMT_YUV422,         /* IMAGE_UTIL_COLORSPACE_YUV422 */
37         MM_UTIL_IMG_FMT_I420,           /* IMAGE_UTIL_COLORSPACE_I420 */
38         MM_UTIL_IMG_FMT_NV12,           /* IMAGE_UTIL_COLORSPACE_NV12 */
39         MM_UTIL_IMG_FMT_UYVY,           /* IMAGE_UTIL_COLORSPACE_UYVY */
40         MM_UTIL_IMG_FMT_YUYV,           /* IMAGE_UTIL_COLORSPACE_YUYV */
41         MM_UTIL_IMG_FMT_RGB565,         /* IMAGE_UTIL_COLORSPACE_RGB565 */
42         MM_UTIL_IMG_FMT_RGB888,         /* IMAGE_UTIL_COLORSPACE_RGB888 */
43         MM_UTIL_IMG_FMT_ARGB8888,       /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
44         MM_UTIL_IMG_FMT_BGRA8888,       /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
45         MM_UTIL_IMG_FMT_RGBA8888,       /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
46         MM_UTIL_IMG_FMT_BGRX8888,       /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
47         MM_UTIL_JPEG_FMT_NV21,          /* IMAGE_UTIL_COLORSPACE_NV12 */
48         MM_UTIL_JPEG_FMT_NV16,          /* IMAGE_UTIL_COLORSPACE_NV16 */
49         MM_UTIL_JPEG_FMT_NV61,          /* IMAGE_UTIL_COLORSPACE_NV61 */
50 };
51
52 static int _convert_encode_colorspace_tbl[] = {
53         MM_UTIL_JPEG_FMT_YUV420,        /* IMAGE_UTIL_COLORSPACE_YUV420 */
54         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUV422 */
55         MM_UTIL_JPEG_FMT_YUV420,        /* IMAGE_UTIL_COLORSPACE_I420 */
56         MM_UTIL_JPEG_FMT_NV12,          /* IMAGE_UTIL_COLORSPACE_NV12 */
57         -1,                                                     /* IMAGE_UTIL_COLORSPACE_UYVY */
58         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUYV */
59         -1,                                                     /* IMAGE_UTIL_COLORSPACE_RGB565 */
60         MM_UTIL_JPEG_FMT_RGB888,        /* IMAGE_UTIL_COLORSPACE_RGB888 */
61         MM_UTIL_JPEG_FMT_ARGB8888,      /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
62         MM_UTIL_JPEG_FMT_BGRA8888,      /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
63         MM_UTIL_JPEG_FMT_RGBA8888,      /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
64         -1,                                                     /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
65         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV21 */
66         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV16 */
67         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV61 */
68 };
69
70 static int _convert_jpeg_colorspace_tbl[] = {
71         MM_UTIL_JPEG_FMT_YUV420,        /* IMAGE_UTIL_COLORSPACE_YUV420 */
72         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUV422 */
73         MM_UTIL_JPEG_FMT_YUV420,        /* IMAGE_UTIL_COLORSPACE_I420 */
74         MM_UTIL_JPEG_FMT_NV12,          /* IMAGE_UTIL_COLORSPACE_NV12 */
75         -1,                                                     /* IMAGE_UTIL_COLORSPACE_UYVY */
76         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUYV */
77         -1,                                                     /* IMAGE_UTIL_COLORSPACE_RGB565 */
78         MM_UTIL_JPEG_FMT_RGB888,        /* IMAGE_UTIL_COLORSPACE_RGB888 */
79         MM_UTIL_JPEG_FMT_ARGB8888,      /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
80         MM_UTIL_JPEG_FMT_BGRA8888,      /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
81         MM_UTIL_JPEG_FMT_RGBA8888,      /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
82         -1,                                                     /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
83         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV21 */
84         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV16 */
85         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV61 */
86 };
87
88 static int _convert_png_colorspace_tbl[] = {
89         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUV420 */
90         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUV422 */
91         -1,                                                     /* IMAGE_UTIL_COLORSPACE_I420 */
92         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV12 */
93         -1,                                                     /* IMAGE_UTIL_COLORSPACE_UYVY */
94         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUYV */
95         -1,                                                     /* IMAGE_UTIL_COLORSPACE_RGB565 */
96         -1,                                                     /* IMAGE_UTIL_COLORSPACE_RGB888 */
97         -1,                                                     /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
98         -1,                                                     /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
99         MM_UTIL_PNG_COLOR_TYPE_RGB_ALPHA,       /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
100         -1,                                                     /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
101         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV21 */
102         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV16 */
103         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV61 */
104 };
105
106 static int _convert_gif_colorspace_tbl[] = {
107         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUV420 */
108         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUV422 */
109         -1,                                                     /* IMAGE_UTIL_COLORSPACE_I420 */
110         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV12 */
111         -1,                                                     /* IMAGE_UTIL_COLORSPACE_UYVY */
112         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUYV */
113         -1,                                                     /* IMAGE_UTIL_COLORSPACE_RGB565 */
114         -1,                                                     /* IMAGE_UTIL_COLORSPACE_RGB888 */
115         -1,                                                     /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
116         -1,                                                     /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
117         MM_UTIL_GIF_FMT_RGBA8888,       /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
118         -1,                                                     /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
119         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV21 */
120         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV16 */
121         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV61 */
122 };
123
124 static int _convert_bmp_colorspace_tbl[] = {
125         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUV420 */
126         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUV422 */
127         -1,                                                     /* IMAGE_UTIL_COLORSPACE_I420 */
128         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV12 */
129         -1,                                                     /* IMAGE_UTIL_COLORSPACE_UYVY */
130         -1,                                                     /* IMAGE_UTIL_COLORSPACE_YUYV */
131         -1,                                                     /* IMAGE_UTIL_COLORSPACE_RGB565 */
132         -1,                                                     /* IMAGE_UTIL_COLORSPACE_RGB888 */
133         -1,                                                     /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
134         -1,                                                     /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
135         MM_UTIL_BMP_FMT_RGBA8888,       /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
136         -1,                                                     /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
137         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV21 */
138         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV16 */
139         -1,                                                     /* IMAGE_UTIL_COLORSPACE_NV61 */
140 };
141
142 static int _convert_decode_scale_tbl[] = {
143         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_1,
144         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_2,
145         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_4,
146         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_8,
147 };
148
149 static int _convert_image_util_error_code(const char *func, int code)
150 {
151         int ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
152         char *errorstr = NULL;
153         switch (code) {
154         case MM_UTIL_ERROR_NONE:
155                 ret = IMAGE_UTIL_ERROR_NONE;
156                 errorstr = strdup("ERROR_NONE");
157                 break;
158         case MM_UTIL_ERROR_NO_SUCH_FILE:
159                 ret = IMAGE_UTIL_ERROR_NO_SUCH_FILE;
160                 errorstr = strdup("NO_SUCH_FILE");
161                 break;
162         case MM_UTIL_ERROR_INVALID_PARAMETER:
163                 ret = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
164                 errorstr = strdup("INVALID_PARAMETER");
165                 break;
166         case MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT:
167                 ret = IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
168                 errorstr = strdup("NOT_SUPPORTED_FORMAT");
169                 break;
170         case MM_UTIL_ERROR_OUT_OF_MEMORY:
171                 ret = IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
172                 errorstr = strdup("OUT_OF_MEMORY");
173                 break;
174         case MM_UTIL_ERROR_INVALID_OPERATION:
175         default:
176                 ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
177                 errorstr = strdup("INVALID_OPERATION");
178
179         }
180
181         image_util_debug("[%s] %s(0x%08x)", func, errorstr, ret);
182         IMAGE_UTIL_SAFE_FREE(errorstr);
183         return ret;
184 }
185
186 static image_util_error_e _image_util_error_convert(int error)
187 {
188         switch (error) {
189         case MM_UTIL_ERROR_NONE:
190                 image_util_debug("Error None");
191                 return IMAGE_UTIL_ERROR_NONE;
192         case MM_UTIL_ERROR_INVALID_PARAMETER:
193                 image_util_error("INVALID_PARAMETER(0x%08x)", IMAGE_UTIL_ERROR_INVALID_PARAMETER);
194                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
195         case MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT:
196                 image_util_error("NOT_SUPPORTED_FORMAT(0x%08x)", IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT);
197                 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
198         case MM_UTIL_ERROR_OUT_OF_MEMORY:
199                 image_util_error("OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
200                 return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
201                 break;
202         case MM_UTIL_ERROR_INVALID_OPERATION:
203         default:
204                 image_util_error("INVALID_OPERATION(0x%08x)", error);
205                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
206         }
207 }
208
209 static void _image_util_transform_completed_cb(media_packet_h * dst, int error, void *user_data)
210 {
211         int error_value = IMAGE_UTIL_ERROR_NONE;
212         image_util_cb_s *_util_cb = (image_util_cb_s *) user_data;
213
214         if ((_util_cb != NULL) && (_util_cb->image_processing_completed_cb != NULL)) {
215                 error_value = _image_util_error_convert(error);
216                 _util_cb->image_processing_completed_cb(dst, error_value, _util_cb->user_data);
217         }
218
219         return;
220 }
221
222 static int _image_util_create_transform_handle(transformation_s * handle)
223 {
224         int err = MM_UTIL_ERROR_NONE;
225         mm_util_imgp_h image_h;
226
227         err = mm_util_create(&image_h);
228         if (err != MM_UTIL_ERROR_NONE) {
229                 image_util_error("Error - mm_util_create");
230                 return _convert_image_util_error_code(__func__, err);
231         }
232
233         handle->image_h = image_h;
234
235         return _convert_image_util_error_code(__func__, err);
236 }
237
238 static bool _image_util_check_resolution(int width, int height)
239 {
240         if (width <= 0) {
241                 image_util_error("invalid width [%d]", width);
242                 return false;
243         }
244
245         if (height <= 0) {
246                 image_util_error("invalid height [%d]", height);
247                 return false;
248         }
249
250         return true;
251 }
252
253 int image_util_foreach_supported_jpeg_colorspace(image_util_supported_jpeg_colorspace_cb callback, void *user_data)
254 {
255         int i = 0;
256
257         image_util_retvm_if((callback == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "callback is null");
258
259         /* RGB has higher precedence than YUV */
260         for (i = sizeof(_convert_encode_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
261                 if (_convert_encode_colorspace_tbl[i] != -1)
262                         if (false == callback(i, user_data))
263                                 return IMAGE_UTIL_ERROR_NONE;
264
265         }
266
267         return IMAGE_UTIL_ERROR_NONE;
268 }
269
270 int image_util_transform_create(transformation_h * handle)
271 {
272         int err = MM_UTIL_ERROR_NONE;
273
274         image_util_debug("image_util_create");
275
276         image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
277
278         transformation_s *_handle = (transformation_s *) calloc(1, sizeof(transformation_s));
279         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
280
281         _handle->colorspace = -1;
282         _handle->_util_cb = NULL;
283         _handle->image_h = 0;
284         _handle->hardware_acceleration = false;
285         _handle->set_convert = false;
286         _handle->set_resize = false;
287         _handle->set_rotate = false;
288         _handle->set_crop = false;
289
290         err = _image_util_create_transform_handle(_handle);
291         if (err != MM_UTIL_ERROR_NONE) {
292                 image_util_error("Error - create transform handle");
293                 IMAGE_UTIL_SAFE_FREE(_handle);
294                 return _convert_image_util_error_code(__func__, err);
295         }
296
297         *handle = (transformation_h) _handle;
298
299         return _convert_image_util_error_code(__func__, err);
300 }
301
302 int image_util_transform_set_hardware_acceleration(transformation_h handle, bool mode)
303 {
304         int err = MM_UTIL_ERROR_NONE;
305         transformation_s *_handle = (transformation_s *) handle;
306
307         image_util_debug("Set hardware_acceleration %d", mode);
308
309         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
310 #ifndef ENABLE_HW_ACCELERATION
311         image_util_retvm_if((mode == true), IMAGE_UTIL_ERROR_NOT_SUPPORTED, "hardware acceleration is not supported");
312 #endif
313
314         err = mm_util_set_hardware_acceleration(_handle->image_h, mode);
315         if (err != MM_UTIL_ERROR_NONE) {
316                 image_util_error("Error - Set hardware_acceleration");
317                 return _convert_image_util_error_code(__func__, err);
318         }
319
320         image_util_debug("Set hardware_acceleration %d", mode);
321         _handle->hardware_acceleration = mode;
322
323         return _convert_image_util_error_code(__func__, err);
324 }
325
326 int image_util_transform_set_colorspace(transformation_h handle, image_util_colorspace_e colorspace)
327 {
328         int err = MM_UTIL_ERROR_NONE;
329         transformation_s *_handle = (transformation_s *) handle;
330
331         image_util_debug("Set colorspace_convert_info [%d]", colorspace);
332
333         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
334
335         err = mm_util_set_colorspace_convert(_handle->image_h, colorspace);
336         if (err != MM_UTIL_ERROR_NONE) {
337                 image_util_error("Error - Set colorspace convert");
338                 return _convert_image_util_error_code(__func__, err);
339         }
340
341         _handle->colorspace = colorspace;
342         _handle->set_convert = true;
343
344         return _convert_image_util_error_code(__func__, err);
345 }
346
347 int image_util_transform_set_resolution(transformation_h handle, unsigned int width, unsigned int height)
348 {
349         int err = MM_UTIL_ERROR_NONE;
350         transformation_s *_handle = (transformation_s *) handle;
351
352         image_util_debug("Set resize_info w[%d] h[%d]", width, height);
353
354         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
355         image_util_retvm_if((_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
356         image_util_retvm_if((_image_util_check_resolution(width, height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
357
358         err = mm_util_set_resolution(_handle->image_h, width, height);
359         if (err != MM_UTIL_ERROR_NONE) {
360                 image_util_error("Error - Set resolution");
361                 return _convert_image_util_error_code(__func__, err);
362         }
363         _handle->width = width;
364         _handle->height = height;
365         _handle->set_resize = true;
366
367         return _convert_image_util_error_code(__func__, err);
368 }
369
370 int image_util_transform_set_rotation(transformation_h handle, image_util_rotation_e rotation)
371 {
372         int err = MM_UTIL_ERROR_NONE;
373         transformation_s *_handle = (transformation_s *) handle;
374
375         image_util_debug("Set rotate_info [%d]", rotation);
376
377         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
378
379         err = mm_util_set_rotation(_handle->image_h, rotation);
380         if (err != MM_UTIL_ERROR_NONE) {
381                 image_util_error("Error - Set rotation");
382                 return _convert_image_util_error_code(__func__, err);
383         }
384         _handle->rotation = rotation;
385         _handle->set_rotate = true;
386
387         return _convert_image_util_error_code(__func__, err);
388 }
389
390 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)
391 {
392         int err = MM_UTIL_ERROR_NONE;
393         transformation_s *_handle = (transformation_s *) handle;
394         int dest_width;
395         int dest_height;
396
397         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
398         image_util_retvm_if((_handle->set_resize), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
399
400         dest_width = end_x - start_x;
401         dest_height = end_y - start_y;
402
403         image_util_debug("Set crop_info x[%d] y[%d] w[%d] h[%d]", start_x, start_y, dest_width, dest_height);
404
405         image_util_retvm_if((_image_util_check_resolution(dest_width, dest_height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dest resolution");
406         err = mm_util_set_crop_area(_handle->image_h, start_x, start_y, end_x, end_y);
407         if (err != MM_UTIL_ERROR_NONE) {
408                 image_util_error("Error - Set crop area");
409                 return _convert_image_util_error_code(__func__, err);
410         }
411         _handle->start_x = start_x;
412         _handle->start_y = start_y;
413         _handle->end_x = end_x;
414         _handle->end_y = end_y;
415         _handle->set_crop = true;
416
417         return _convert_image_util_error_code(__func__, err);
418 }
419
420 int image_util_transform_get_colorspace(transformation_h handle, image_util_colorspace_e * colorspace)
421 {
422         int ret = IMAGE_UTIL_ERROR_NONE;
423         transformation_s *_handle = (transformation_s *) handle;
424
425         image_util_debug("Get colorspace_convert_info [%d]", colorspace);
426
427         if (_handle == NULL) {
428                 image_util_error("Invalid Handle");
429                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
430         }
431
432         if (!colorspace) {
433                 image_util_error("colorspace area parameter error");
434                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
435         }
436
437         if (!_handle->set_convert) {
438                 image_util_error("Did not set colorspace before");
439                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
440         }
441
442         *colorspace = _handle->colorspace;
443         return ret;
444 }
445
446 int image_util_transform_get_resolution(transformation_h handle, unsigned int *width, unsigned int *height)
447 {
448         int ret = IMAGE_UTIL_ERROR_NONE;
449         transformation_s *_handle = (transformation_s *) handle;
450
451         image_util_debug("Set resize_info w[%d] h[%d]", width, height);
452
453         if (_handle == NULL) {
454                 image_util_error("Invalid Handle");
455                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
456         }
457
458         if (!width || !height) {
459                 image_util_error("resolution area parameter error");
460                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
461         }
462
463         if (!_handle->set_resize) {
464                 image_util_error("Did not set resolution before");
465                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
466         }
467
468         *width = _handle->width;
469         *height = _handle->height;
470
471         return ret;
472 }
473
474 int image_util_transform_get_rotation(transformation_h handle, image_util_rotation_e * rotation)
475 {
476         int ret = IMAGE_UTIL_ERROR_NONE;
477         transformation_s *_handle = (transformation_s *) handle;
478
479         image_util_debug("Set rotate_info [%d]", rotation);
480
481         if (_handle == NULL) {
482                 image_util_error("Invalid Handle");
483                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
484         }
485
486         if (!rotation) {
487                 image_util_error("rotation area parameter error");
488                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
489         }
490
491         if (!_handle->set_rotate) {
492                 image_util_error("Did not set rotation before");
493                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
494         }
495
496         *rotation = _handle->rotation;
497
498         return ret;
499 }
500
501 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)
502 {
503         int ret = IMAGE_UTIL_ERROR_NONE;
504         transformation_s *_handle = (transformation_s *) handle;
505
506         if (_handle == NULL) {
507                 image_util_error("Invalid Handle");
508                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
509         }
510
511         if (!start_x || !start_y || !end_x || !end_y) {
512                 image_util_error("crop area parameter error");
513                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
514         }
515
516         if (!_handle->set_crop) {
517                 image_util_error("Did not set crop area before");
518                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
519         }
520
521         *start_x = _handle->start_x;
522         *start_y = _handle->start_y;
523         *end_x = _handle->end_x;
524         *end_y = _handle->end_y;
525
526         return ret;
527 }
528
529 int image_util_transform_run(transformation_h handle, media_packet_h src, image_util_transform_completed_cb completed_cb, void *user_data)
530 {
531         int err = MM_UTIL_ERROR_NONE;
532         transformation_s *_handle = (transformation_s *) handle;
533
534         image_util_debug("image_util_transform");
535
536         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
537         image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
538         image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid source");
539         image_util_retvm_if((!_handle->set_convert && !_handle->set_resize && !_handle->set_rotate && !_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid transform");
540
541         if (_handle->_util_cb != NULL) {
542                 IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
543                 _handle->_util_cb = NULL;
544         }
545         _handle->_util_cb = (image_util_cb_s *) calloc(1, sizeof(image_util_cb_s));
546         image_util_retvm_if((_handle->_util_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
547
548         _handle->_util_cb->user_data = user_data;
549         _handle->_util_cb->image_processing_completed_cb = completed_cb;
550
551         if (_handle->_util_cb)
552                 err = mm_util_transform(_handle->image_h, src, (mm_util_completed_callback) _image_util_transform_completed_cb, (void *)_handle->_util_cb);
553
554         return _convert_image_util_error_code(__func__, err);
555 }
556
557 int image_util_transform_destroy(transformation_h handle)
558 {
559         int err = MM_UTIL_ERROR_NONE;
560         transformation_s *_handle = (transformation_s *) handle;
561
562         image_util_debug("image_util_destroy");
563
564         if (_handle == NULL) {
565                 image_util_error("Invalid Handle");
566                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
567         }
568
569         err = mm_util_destroy(_handle->image_h);
570
571         IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
572         IMAGE_UTIL_SAFE_FREE(_handle);
573
574         return _convert_image_util_error_code(__func__, err);
575 }
576
577 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)
578 {
579         int err = MM_UTIL_ERROR_NONE;
580
581         image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
582         image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
583         image_util_retvm_if((dest_colorspace < 0 || dest_colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dst_colorspace");
584         image_util_retvm_if((src_colorspace < 0 || src_colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid src_colorspace");
585
586         err = mm_util_convert_colorspace(src, width, height, _convert_colorspace_tbl[src_colorspace], dest, _convert_colorspace_tbl[dest_colorspace]);
587
588         return _convert_image_util_error_code(__func__, err);
589 }
590
591 int image_util_calculate_buffer_size(int width, int height, image_util_colorspace_e colorspace, unsigned int *size)
592 {
593         int err = MM_UTIL_ERROR_NONE;
594
595         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
596         image_util_retvm_if((width <= 0 || height <= 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid width or Invalid height");
597         image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
598
599         err = mm_util_get_image_size(_convert_colorspace_tbl[colorspace], width, height, size);
600         return _convert_image_util_error_code(__func__, err);
601 }
602
603 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)
604 {
605         int err = MM_UTIL_ERROR_NONE;
606
607         image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
608         image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
609         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
610         image_util_retvm_if((dest_width == NULL || dest_height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest_width or dest_height is null");
611         image_util_retvm_if((*dest_width <= 0 || *dest_height <= 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dest_width or Invalid dest_height");
612
613         unsigned int dest_w, dest_h;
614         dest_w = *dest_width;
615         dest_h = *dest_height;
616         err = mm_util_resize_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], dest, &dest_w, &dest_h);
617         if (err == MM_UTIL_ERROR_NONE) {
618                 *dest_width = (int)dest_w;
619                 *dest_height = (int)dest_h;
620         }
621
622         return _convert_image_util_error_code(__func__, err);
623 }
624
625 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)
626 {
627         int err = MM_UTIL_ERROR_NONE;
628
629         image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
630         image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
631         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
632         image_util_retvm_if((dest_rotation < 0 || dest_rotation > IMAGE_UTIL_ROTATION_FLIP_VERT), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid rotation");
633         image_util_retvm_if((dest_width == NULL || dest_height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest_width or dest_height is null");
634
635         unsigned int dest_w, dest_h;
636         err = mm_util_rotate_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], dest, &dest_w, &dest_h, dest_rotation);
637         if (err == MM_UTIL_ERROR_NONE) {
638                 *dest_width = (int)dest_w;
639                 *dest_height = (int)dest_h;
640         }
641         return _convert_image_util_error_code(__func__, err);
642 }
643
644 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)
645 {
646         int err = MM_UTIL_ERROR_NONE;
647
648         image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
649         image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
650         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
651         image_util_retvm_if((width == NULL || height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "width or height is null");
652         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");
653
654         unsigned int dest_w, dest_h;
655         dest_w = *width;
656         dest_h = *height;
657         err = mm_util_crop_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], x, y, &dest_w, &dest_h, dest);
658         if (err == MM_UTIL_ERROR_NONE) {
659                 *width = (int)dest_w;
660                 *height = (int)dest_h;
661         }
662
663         return _convert_image_util_error_code(__func__, err);
664 }
665
666 int image_util_decode_jpeg(const char *path, image_util_colorspace_e colorspace, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
667 {
668         int err = MM_UTIL_ERROR_NONE;
669
670         image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
671         image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
672         image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
673         image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
674         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
675         image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
676
677         mm_util_jpeg_yuv_data decoded;
678         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
679
680         err = mm_util_decode_from_jpeg_file(&decoded, path, _convert_encode_colorspace_tbl[colorspace]);
681         if (err == MM_UTIL_ERROR_NONE) {
682                 *image_buffer = decoded.data;
683                 if (width)
684                         *width = decoded.width;
685                 if (height)
686                         *height = decoded.height;
687                 if (size)
688                         *size = (unsigned int)decoded.size;
689         }
690         return _convert_image_util_error_code(__func__, err);
691 }
692
693 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)
694 {
695         int err = MM_UTIL_ERROR_NONE;
696
697         image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
698         image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
699         image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
700         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
701         image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
702
703         mm_util_jpeg_yuv_data decoded;
704         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
705
706         err = mm_util_decode_from_jpeg_memory(&decoded, (void *)jpeg_buffer, jpeg_size, _convert_encode_colorspace_tbl[colorspace]);
707
708         if (err == MM_UTIL_ERROR_NONE) {
709                 *image_buffer = decoded.data;
710                 if (width)
711                         *width = decoded.width;
712                 if (height)
713                         *height = decoded.height;
714                 if (size)
715                         *size = (unsigned int)decoded.size;
716         }
717
718         return _convert_image_util_error_code(__func__, err);
719 }
720
721 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)
722 {
723         int err = MM_UTIL_ERROR_NONE;
724
725         image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
726         image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
727         image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
728         image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
729         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
730         image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
731         image_util_retvm_if((downscale < 0 || downscale >= sizeof(_convert_decode_scale_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downsacle is invalid");
732
733         mm_util_jpeg_yuv_data decoded;
734         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
735
736         err = mm_util_decode_from_jpeg_file_with_downscale(&decoded, path, _convert_encode_colorspace_tbl[colorspace], _convert_decode_scale_tbl[downscale]);
737         if (err == MM_UTIL_ERROR_NONE) {
738                 *image_buffer = decoded.data;
739                 if (width)
740                         *width = decoded.width;
741                 if (height)
742                         *height = decoded.height;
743                 if (size)
744                         *size = (unsigned int)decoded.size;
745         }
746         return _convert_image_util_error_code(__func__, err);
747 }
748
749 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)
750 {
751         int err = MM_UTIL_ERROR_NONE;
752
753         image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
754         image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
755         image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
756         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
757         image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
758         image_util_retvm_if((downscale < 0 || downscale >= sizeof(_convert_decode_scale_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downsacle is invalid");
759
760         mm_util_jpeg_yuv_data decoded;
761         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
762
763         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]);
764
765         if (err == MM_UTIL_ERROR_NONE) {
766                 *image_buffer = decoded.data;
767                 if (width)
768                         *width = decoded.width;
769                 if (height)
770                         *height = decoded.height;
771                 if (size)
772                         *size = (unsigned int)decoded.size;
773         }
774
775         return _convert_image_util_error_code(__func__, err);
776 }
777
778 int image_util_encode_jpeg(const unsigned char *buffer, int width, int height, image_util_colorspace_e colorspace, int quality, const char *path)
779 {
780         int err = MM_UTIL_ERROR_NONE;
781
782         image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
783         image_util_retvm_if((buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "buffer is null");
784         image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
785         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
786         image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
787
788         err = mm_util_jpeg_encode_to_file(path, (void *)buffer, width, height, _convert_encode_colorspace_tbl[colorspace], quality);
789         return _convert_image_util_error_code(__func__, err);
790 }
791
792 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)
793 {
794         int err = MM_UTIL_ERROR_NONE;
795         int isize = 0;
796
797         image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
798         image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
799         image_util_retvm_if((jpeg_size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_size is null");
800         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
801         image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
802
803         err = mm_util_jpeg_encode_to_memory((void **)jpeg_buffer, &isize, (void *)image_buffer, width, height, _convert_encode_colorspace_tbl[colorspace], quality);
804         if (err == MM_UTIL_ERROR_NONE)
805                 *jpeg_size = (unsigned int)isize;
806
807         return _convert_image_util_error_code(__func__, err);
808 }
809
810 int image_util_extract_color_from_memory(const unsigned char *image_buffer, int width, int height, unsigned char *rgb_r, unsigned char *rgb_g, unsigned char *rgb_b)
811 {
812         int ret = MM_UTIL_ERROR_NONE;
813
814         image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer     is null");
815
816         GModule *module = NULL;
817         ModuleFunc mmutil_imgcv_module_func = NULL;
818         module = g_module_open(PATH_MMUTIL_IMGCV_LIB, G_MODULE_BIND_LAZY);
819         image_util_retvm_if((module == NULL), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "fail to open module");
820
821         g_module_symbol(module, IMGCV_FUNC_NAME, (gpointer *)&mmutil_imgcv_module_func);
822         if (!mmutil_imgcv_module_func)
823                 g_module_close(module);
824
825         image_util_retvm_if((mmutil_imgcv_module_func == NULL), IMAGE_UTIL_ERROR_INVALID_OPERATION, "fail to get symbol");
826
827         unsigned char r_color, g_color, b_color;
828         ret = mmutil_imgcv_module_func((void *)image_buffer, width, height, &r_color, &g_color, &b_color);
829
830         *rgb_r = r_color;
831         *rgb_g = g_color;
832         *rgb_b = b_color;
833
834         if (module) {
835                 g_module_close(module);
836                 module = NULL;
837         }
838
839         return _convert_image_util_error_code(__func__, ret);
840 }
841
842 int image_util_foreach_supported_colorspace(image_util_type_e image_type, image_util_supported_colorspace_cb callback, void *user_data)
843 {
844         int i = 0;
845
846         image_util_retvm_if((callback == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "callback is null");
847
848         switch (image_type) {
849         case IMAGE_UTIL_JPEG:
850                 /* RGB has higher precedence than YUV */
851                 for (i = sizeof(_convert_jpeg_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
852                         if (_convert_jpeg_colorspace_tbl[i] != -1)
853                                 if (false == callback(i, user_data))
854                                         return IMAGE_UTIL_ERROR_NONE;
855
856                 }
857                 break;
858         case IMAGE_UTIL_PNG:
859                 for (i = sizeof(_convert_png_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
860                         if (_convert_png_colorspace_tbl[i] != -1)
861                                 if (false == callback(i, user_data))
862                                         return IMAGE_UTIL_ERROR_NONE;
863
864                 }
865                 break;
866         case IMAGE_UTIL_GIF:
867                 for (i = sizeof(_convert_gif_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
868                         if (_convert_gif_colorspace_tbl[i] != -1)
869                                 if (false == callback(i, user_data))
870                                         return IMAGE_UTIL_ERROR_NONE;
871
872                 }
873                 break;
874         case IMAGE_UTIL_BMP:
875                 for (i = sizeof(_convert_bmp_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
876                         if (_convert_bmp_colorspace_tbl[i] != -1)
877                                 if (false == callback(i, user_data))
878                                         return IMAGE_UTIL_ERROR_NONE;
879
880                 }
881                 break;
882         default:
883                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
884         }
885
886         return IMAGE_UTIL_ERROR_NONE;
887 }
888
889 static int _image_util_decode_create_jpeg_handle(decode_encode_s * handle)
890 {
891         int err = MM_UTIL_ERROR_NONE;
892
893         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
894
895         mm_util_jpeg_yuv_data *_handle = (mm_util_jpeg_yuv_data *) calloc(1, sizeof(mm_util_jpeg_yuv_data));
896         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
897
898         handle->image_h = (mm_util_imgp_h) _handle;
899         handle->colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888;
900         handle->down_scale = sizeof(image_util_scale_e);
901
902         return err;
903 }
904
905 static int _image_util_decode_create_png_handle(decode_encode_s * handle)
906 {
907         int err = MM_UTIL_ERROR_NONE;
908
909         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
910
911         mm_util_png_data *_handle = (mm_util_png_data *) calloc(1, sizeof(mm_util_png_data));
912         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
913
914         mm_util_init_decode_png(_handle);
915
916         handle->image_h = (mm_util_imgp_h) _handle;
917
918         return err;
919 }
920
921 static int _image_util_decode_create_gif_handle(decode_encode_s * handle)
922 {
923         int err = MM_UTIL_ERROR_NONE;
924
925         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
926
927         mm_util_gif_data *_handle = (mm_util_gif_data *) calloc(1, sizeof(mm_util_gif_data));
928         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
929
930         handle->image_h = (mm_util_imgp_h) _handle;
931
932         return err;
933 }
934
935 static int _image_util_decode_create_bmp_handle(decode_encode_s * handle)
936 {
937         int err = MM_UTIL_ERROR_NONE;
938
939         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
940
941         mm_util_bmp_data *_handle = (mm_util_bmp_data *) calloc(1, sizeof(mm_util_bmp_data));
942         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
943
944         handle->image_h = (mm_util_imgp_h) _handle;
945
946         return err;
947 }
948
949 int image_util_decode_create(image_util_decode_h * handle)
950 {
951         int err = MM_UTIL_ERROR_NONE;
952
953         image_util_debug("image_util_decode_create");
954
955         image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
956
957         decode_encode_s *_handle = (decode_encode_s *) calloc(1, sizeof(decode_encode_s));
958         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
959
960         _handle->src_buffer = NULL;
961         _handle->dst_buffer = NULL;
962         _handle->path = NULL;
963         _handle->image_h = 0;
964         _handle->is_decode = TRUE;
965         _handle->image_type = -1;
966
967         *handle = (image_util_decode_h) _handle;
968
969         return _convert_image_util_error_code(__func__, err);
970 }
971
972 static char _JPEG_HEADER[] = { 0xFF, 0xD8 };
973 static char _PNG_HEADER[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
974 static char _GIF_HEADER[] = { 'G', 'I', 'F' };
975 static char _BMP_HEADER[] = { 'B', 'M' };
976
977 static int _image_util_decode_create_image_handle(image_util_decode_h handle, const unsigned char *src_buffer)
978 {
979         image_util_type_e image_type = -1;
980         static struct {
981                 char *header;
982                 int size;
983                 image_util_type_e image_type;
984         } image_header[] = {
985                 {
986                 _JPEG_HEADER, sizeof(_JPEG_HEADER), IMAGE_UTIL_JPEG}
987                 , {
988                 _PNG_HEADER, sizeof(_PNG_HEADER), IMAGE_UTIL_PNG}
989                 , {
990                 _GIF_HEADER, sizeof(_GIF_HEADER), IMAGE_UTIL_GIF}
991                 , {
992                 _BMP_HEADER, sizeof(_BMP_HEADER), IMAGE_UTIL_BMP}
993         ,};
994         unsigned int i = 0;
995         int err = MM_UTIL_ERROR_NONE;
996         decode_encode_s *_handle = (decode_encode_s *) handle;
997
998         if (_handle == NULL || _handle->is_decode == FALSE) {
999                 image_util_error("Invalid Handle");
1000                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1001         }
1002         if (src_buffer == NULL) {
1003                 image_util_error("Invalid input buffer");
1004                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1005         }
1006
1007         for (i = 0; i < sizeof(image_header) / sizeof(image_header[0]); i++) {
1008                 if (strncmp((const char *)src_buffer, image_header[i].header, image_header[i].size) == 0) {
1009                         image_type = image_header[i].image_type;
1010                         break;
1011                 }
1012         }
1013
1014         _handle->image_type = image_type;
1015
1016         switch (image_type) {
1017         case IMAGE_UTIL_JPEG:
1018                 err = _image_util_decode_create_jpeg_handle(_handle);
1019                 break;
1020         case IMAGE_UTIL_PNG:
1021                 err = _image_util_decode_create_png_handle(_handle);
1022                 break;
1023         case IMAGE_UTIL_GIF:
1024                 err = _image_util_decode_create_gif_handle(_handle);
1025                 break;
1026         case IMAGE_UTIL_BMP:
1027                 err = _image_util_decode_create_bmp_handle(_handle);
1028                 break;
1029         default:
1030                 err = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1031                 break;
1032         }
1033
1034         if (err != MM_UTIL_ERROR_NONE) {
1035                 image_util_error("Error - create image handle");
1036                 IMAGE_UTIL_SAFE_FREE(_handle);
1037                 return _convert_image_util_error_code(__func__, err);
1038         }
1039
1040         return _convert_image_util_error_code(__func__, err);
1041 }
1042
1043 int image_util_decode_set_input_path(image_util_decode_h handle, const char *path)
1044 {
1045         int err = IMAGE_UTIL_ERROR_NONE;
1046         decode_encode_s *_handle = (decode_encode_s *) handle;
1047         FILE *fp = NULL;
1048         unsigned char *src_buffer = NULL;
1049
1050         if (_handle == NULL || _handle->is_decode == FALSE) {
1051                 image_util_error("Invalid Handle");
1052                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1053         }
1054         image_util_retvm_if((path == NULL || strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
1055
1056         if (_handle->src_buffer)
1057                 _handle->src_buffer = NULL;
1058
1059         fp = fopen(path, "r");
1060         if (fp == NULL) {
1061                 image_util_error("File open failed");
1062                 return IMAGE_UTIL_ERROR_NO_SUCH_FILE;
1063         }
1064         src_buffer = (void *)malloc(sizeof(_PNG_HEADER));
1065         if (!fread(src_buffer, 1, sizeof(_PNG_HEADER), fp)) {
1066                 image_util_error("File read failed");
1067                 fclose(fp);
1068                 fp = NULL;
1069                 free(src_buffer);
1070                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
1071         }
1072
1073         err = _image_util_decode_create_image_handle(_handle, src_buffer);
1074
1075         fclose(fp);
1076         fp = NULL;
1077         free(src_buffer);
1078
1079         _handle->path = path;
1080
1081         return err;
1082 }
1083
1084 int image_util_decode_set_input_buffer(image_util_decode_h handle, const unsigned char *src_buffer, unsigned long long src_size)
1085 {
1086         int err = IMAGE_UTIL_ERROR_NONE;
1087         decode_encode_s *_handle = (decode_encode_s *) handle;
1088
1089         if (_handle == NULL || _handle->is_decode == FALSE) {
1090                 image_util_error("Invalid Handle");
1091                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1092         }
1093         if (src_buffer == NULL || src_size == 0) {
1094                 image_util_error("Invalid input buffer");
1095                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1096         }
1097
1098         if (_handle->path)
1099                 _handle->path = NULL;
1100
1101         err = _image_util_decode_create_image_handle(_handle, src_buffer);
1102
1103         _handle->src_buffer = (void *)src_buffer;
1104         _handle->src_size = src_size;
1105
1106         return err;
1107 }
1108
1109 int image_util_decode_set_output_buffer(image_util_decode_h handle, unsigned char **dst_buffer)
1110 {
1111         int err = IMAGE_UTIL_ERROR_NONE;
1112         decode_encode_s *_handle = (decode_encode_s *) handle;
1113
1114         if (_handle == NULL || _handle->is_decode == FALSE) {
1115                 image_util_error("Invalid Handle");
1116                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1117         }
1118         if (dst_buffer == NULL) {
1119                 image_util_error("Invalid output buffer");
1120                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1121         }
1122
1123         _handle->dst_buffer = (void **)dst_buffer;
1124
1125         return err;
1126 }
1127
1128 int image_util_decode_set_colorspace(image_util_encode_h handle, image_util_colorspace_e colorspace)
1129 {
1130         int err = IMAGE_UTIL_ERROR_NONE;
1131         decode_encode_s *_handle = (decode_encode_s *) handle;
1132
1133         if (_handle == NULL || _handle->is_decode == FALSE) {
1134                 image_util_error("Invalid Handle");
1135                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1136         }
1137
1138         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_jpeg_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
1139         switch (_handle->image_type) {
1140         case IMAGE_UTIL_JPEG:
1141                 image_util_retvm_if((_convert_jpeg_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1142                 break;
1143         case IMAGE_UTIL_PNG:
1144                 image_util_retvm_if((_convert_png_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1145                 break;
1146         case IMAGE_UTIL_GIF:
1147                 image_util_retvm_if((_convert_gif_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1148                 break;
1149         case IMAGE_UTIL_BMP:
1150                 image_util_retvm_if((_convert_bmp_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1151                 break;
1152         default:
1153                 image_util_error("Invalid image type");
1154                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1155         }
1156
1157         _handle->colorspace = colorspace;
1158
1159         return err;
1160 }
1161
1162 int image_util_decode_set_jpeg_downscale(image_util_encode_h handle, image_util_scale_e down_scale)
1163 {
1164         int err = IMAGE_UTIL_ERROR_NONE;
1165         decode_encode_s *_handle = (decode_encode_s *) handle;
1166
1167         if (_handle == NULL || _handle->is_decode == FALSE) {
1168                 image_util_error("Invalid Handle");
1169                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1170         }
1171         if (_handle->image_type != IMAGE_UTIL_JPEG) {
1172                 image_util_error("Wrong image format");
1173                 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1174         }
1175         image_util_retvm_if((down_scale < 0 || down_scale >= sizeof(image_util_scale_e)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downscale is invalid");
1176
1177         _handle->down_scale = down_scale;
1178
1179         return err;
1180 }
1181
1182 static int _image_util_decode_internal(decode_encode_s * _handle)
1183 {
1184         int err = MM_UTIL_ERROR_NONE;
1185
1186         switch (_handle->image_type) {
1187         case IMAGE_UTIL_JPEG:
1188                 {
1189                         mm_util_jpeg_yuv_data *jpeg_data;
1190
1191                         jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
1192                         if (jpeg_data == NULL) {
1193                                 image_util_error("Invalid jpeg data");
1194                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1195                         }
1196
1197                         if (_handle->path) {
1198                                 if (_handle->down_scale < sizeof(image_util_scale_e))
1199                                         err = mm_util_decode_from_jpeg_file_with_downscale(jpeg_data, _handle->path, _convert_jpeg_colorspace_tbl[_handle->colorspace], _convert_decode_scale_tbl[_handle->down_scale]);
1200                                 else
1201                                         err = mm_util_decode_from_jpeg_file(jpeg_data, _handle->path, _convert_jpeg_colorspace_tbl[_handle->colorspace]);
1202                         } else {
1203                                 if (_handle->down_scale < sizeof(image_util_scale_e))
1204                                         err = mm_util_decode_from_jpeg_memory_with_downscale(jpeg_data, _handle->src_buffer, _handle->src_size, _convert_jpeg_colorspace_tbl[_handle->colorspace], _convert_decode_scale_tbl[_handle->down_scale]);
1205                                 else
1206                                         err = mm_util_decode_from_jpeg_memory(jpeg_data, _handle->src_buffer, _handle->src_size, _convert_jpeg_colorspace_tbl[_handle->colorspace]);
1207                         }
1208
1209                         if (err == MM_UTIL_ERROR_NONE) {
1210                                 *(_handle->dst_buffer) = jpeg_data->data;
1211                                 _handle->dst_size = (unsigned long long)jpeg_data->size;
1212                                 _handle->width = jpeg_data->width;
1213                                 _handle->height = jpeg_data->height;
1214                         }
1215                 }
1216                 break;
1217         case IMAGE_UTIL_PNG:
1218                 {
1219                         mm_util_png_data *png_data;
1220
1221                         png_data = (mm_util_png_data *) _handle->image_h;
1222                         if (png_data == NULL) {
1223                                 image_util_error("Invalid png data");
1224                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1225                         }
1226
1227                         if (_handle->path)
1228                                 err = mm_util_decode_from_png_file(png_data, _handle->path);
1229                         else
1230                                 err = mm_util_decode_from_png_memory(png_data, &_handle->src_buffer, _handle->src_size);
1231
1232                         if (err == MM_UTIL_ERROR_NONE) {
1233                                 *(_handle->dst_buffer) = png_data->data;
1234                                 _handle->dst_size = png_data->size;
1235                                 _handle->width = png_data->width;
1236                                 _handle->height = png_data->height;
1237                         }
1238                 }
1239                 break;
1240         case IMAGE_UTIL_GIF:
1241                 {
1242                         mm_util_gif_data *gif_data;
1243
1244                         gif_data = (mm_util_gif_data *) _handle->image_h;
1245                         if (gif_data == NULL) {
1246                                 image_util_error("Invalid gif data");
1247                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1248                         }
1249
1250                         if (_handle->path)
1251                                 err = mm_util_decode_from_gif_file(gif_data, _handle->path);
1252                         else
1253                                 err = mm_util_decode_from_gif_memory(gif_data, &_handle->src_buffer);
1254
1255                         if (err == MM_UTIL_ERROR_NONE) {
1256                                 *(_handle->dst_buffer) = gif_data->frames[0].data;
1257                                 _handle->dst_size = gif_data->size;
1258                                 _handle->width = gif_data->width;
1259                                 _handle->height = gif_data->height;
1260                         }
1261                 }
1262                 break;
1263         case IMAGE_UTIL_BMP:
1264                 {
1265                         mm_util_bmp_data *bmp_data;
1266
1267                         bmp_data = (mm_util_bmp_data *) _handle->image_h;
1268                         if (bmp_data == NULL) {
1269                                 image_util_error("Invalid bmp data");
1270                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1271                         }
1272
1273                         if (_handle->path)
1274                                 err = mm_util_decode_from_bmp_file(bmp_data, _handle->path);
1275                         else
1276                                 err = mm_util_decode_from_bmp_memory(bmp_data, &_handle->src_buffer, _handle->src_size);
1277
1278                         if (err == MM_UTIL_ERROR_NONE) {
1279                                 *(_handle->dst_buffer) = bmp_data->data;
1280                                 _handle->dst_size = bmp_data->size;
1281                                 _handle->width = bmp_data->width;
1282                                 _handle->height = bmp_data->height;
1283                         }
1284                 }
1285                 break;
1286         default:
1287                 err = MM_UTIL_ERROR_INVALID_PARAMETER;
1288                 break;
1289         }
1290
1291         return err;
1292 }
1293
1294 int image_util_decode_run(image_util_decode_h handle, unsigned long *width, unsigned long *height, unsigned long long *size)
1295 {
1296         int err = MM_UTIL_ERROR_NONE;
1297         decode_encode_s *_handle = (decode_encode_s *) handle;
1298
1299         if (_handle == NULL || _handle->is_decode == FALSE) {
1300                 image_util_error("Invalid Handle");
1301                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1302         }
1303         if ((_handle->path == NULL && _handle->src_buffer == NULL) || _handle->dst_buffer == NULL) {
1304                 image_util_error("Invalid input/output");
1305                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1306         }
1307
1308         err = _image_util_decode_internal(_handle);
1309
1310         if (err != MM_UTIL_ERROR_NONE) {
1311                 image_util_error("Error - decode run");
1312                 return _convert_image_util_error_code(__func__, err);
1313         }
1314
1315         if (width)
1316                 *width = _handle->width;
1317         if (height)
1318                 *height = _handle->height;
1319         if (size)
1320                 *size = _handle->dst_size;
1321
1322         return _convert_image_util_error_code(__func__, err);
1323 }
1324
1325 gpointer _image_util_decode_thread(gpointer data)
1326 {
1327         decode_encode_s *_handle = (decode_encode_s *) data;
1328         int err = MM_UTIL_ERROR_NONE;
1329         gint64 end_time = 0;
1330
1331         if (!_handle) {
1332                 image_util_error("[ERROR] - handle");
1333                 return NULL;
1334         }
1335
1336         while (!_handle->is_finish) {
1337                 end_time = g_get_monotonic_time() + 1 * G_TIME_SPAN_SECOND;
1338                 image_util_debug("waiting...");
1339                 g_mutex_lock(&(_handle->thread_mutex));
1340                 g_cond_wait_until(&(_handle->thread_cond), &(_handle->thread_mutex), end_time);
1341                 image_util_debug("<=== get run decode thread signal");
1342                 g_mutex_unlock(&(_handle->thread_mutex));
1343
1344                 if (_handle->is_finish) {
1345                         image_util_debug("exit loop");
1346                         break;
1347                 }
1348
1349                 err = _image_util_decode_internal(_handle);
1350                 if (err == MM_UTIL_ERROR_NONE)
1351                         image_util_debug("Success - decode_internal");
1352                 else
1353                         image_util_error("Error - decode_internal");
1354
1355                 if (_handle->_decode_cb) {
1356                         image_util_debug("completed_cb");
1357                         _handle->is_finish = TRUE;
1358                         _handle->_decode_cb->image_decode_completed_cb(_convert_image_util_error_code(__func__, err), _handle->_decode_cb->user_data, _handle->width, _handle->height, _handle->dst_size);
1359                 }
1360         }
1361
1362         image_util_debug("exit thread");
1363
1364         return NULL;
1365 }
1366
1367 static int _image_util_decode_create_thread(decode_encode_s * handle)
1368 {
1369         int err = MM_UTIL_ERROR_NONE;
1370
1371         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1372
1373         g_mutex_init(&(handle->thread_mutex));
1374
1375         g_cond_init(&(handle->thread_cond));
1376
1377         /*create threads */
1378         handle->thread = g_thread_new("decode_thread", (GThreadFunc) _image_util_decode_thread, (gpointer) handle);
1379         if (!handle->thread) {
1380                 image_util_error("ERROR - create thread");
1381                 g_mutex_clear(&(handle->thread_mutex));
1382
1383                 g_cond_clear(&(handle->thread_cond));
1384                 return MM_UTIL_ERROR_INVALID_OPERATION;
1385         }
1386
1387         return err;
1388 }
1389
1390 int image_util_decode_run_async(image_util_decode_h handle, image_util_decode_completed_cb completed_cb, void *user_data)
1391 {
1392         int err = MM_UTIL_ERROR_NONE;
1393         decode_encode_s *_handle = (decode_encode_s *) handle;
1394
1395         if (_handle == NULL || _handle->is_decode == FALSE) {
1396                 image_util_error("Invalid Handle");
1397                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1398         }
1399         if ((_handle->path == NULL && _handle->src_buffer == NULL) || _handle->dst_buffer == NULL) {
1400                 image_util_error("Invalid input/output");
1401                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1402         }
1403         image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
1404
1405         if (_handle->_decode_cb != NULL) {
1406                 IMAGE_UTIL_SAFE_FREE(_handle->_decode_cb);
1407                 _handle->_decode_cb = NULL;
1408         }
1409         _handle->_decode_cb = (decode_cb_s *) calloc(1, sizeof(decode_cb_s));
1410         image_util_retvm_if((_handle->_decode_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
1411
1412         _handle->_decode_cb->user_data = user_data;
1413         _handle->_decode_cb->image_decode_completed_cb = completed_cb;
1414
1415         err = _image_util_decode_create_thread(_handle);
1416
1417         return _convert_image_util_error_code(__func__, err);
1418 }
1419
1420 int image_util_decode_destroy(image_util_decode_h handle)
1421 {
1422         int err = IMAGE_UTIL_ERROR_NONE;
1423         decode_encode_s *_handle = (decode_encode_s *) handle;
1424
1425         image_util_debug("image_util_encode_png_destroy");
1426
1427         if (_handle == NULL || _handle->is_decode == FALSE) {
1428                 image_util_error("Invalid Handle");
1429                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1430         }
1431
1432         switch (_handle->image_type) {
1433         case IMAGE_UTIL_JPEG:
1434                 {
1435                         mm_util_jpeg_yuv_data *jpeg_data;
1436
1437                         jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
1438                         if (jpeg_data == NULL) {
1439                                 image_util_error("Invalid jpeg data");
1440                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1441                         }
1442                         IMAGE_UTIL_SAFE_FREE(jpeg_data);
1443                 }
1444                 break;
1445         case IMAGE_UTIL_PNG:
1446                 {
1447                         mm_util_png_data *png_data;
1448
1449                         png_data = (mm_util_png_data *) _handle->image_h;
1450                         if (png_data == NULL) {
1451                                 image_util_error("Invalid png data");
1452                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1453                         }
1454                         IMAGE_UTIL_SAFE_FREE(png_data);
1455                 }
1456                 break;
1457         case IMAGE_UTIL_GIF:
1458                 {
1459                         mm_util_gif_data *gif_data;
1460
1461                         gif_data = (mm_util_gif_data *) _handle->image_h;
1462                         if (gif_data == NULL) {
1463                                 image_util_error("Invalid gif data");
1464                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1465                         }
1466                         IMAGE_UTIL_SAFE_FREE(gif_data);
1467                 }
1468                 break;
1469         case IMAGE_UTIL_BMP:
1470                 {
1471                         mm_util_bmp_data *bmp_data;
1472
1473                         bmp_data = (mm_util_bmp_data *) _handle->image_h;
1474                         if (bmp_data == NULL) {
1475                                 image_util_error("Invalid bmp data");
1476                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1477                         }
1478                         IMAGE_UTIL_SAFE_FREE(bmp_data);
1479                 }
1480                 break;
1481         default:
1482                 break;
1483         }
1484
1485         /* g_thread_exit(handle->thread); */
1486         if (_handle->thread) {
1487                 _handle->is_finish = TRUE;
1488                 g_mutex_lock(&(_handle->thread_mutex));
1489                 g_cond_signal(&(_handle->thread_cond));
1490                 image_util_debug("===> send signal(finish) to decode_thread");
1491                 g_mutex_unlock(&(_handle->thread_mutex));
1492
1493                 g_thread_join(_handle->thread);
1494
1495                 g_mutex_clear(&(_handle->thread_mutex));
1496
1497                 g_cond_clear(&(_handle->thread_cond));
1498         }
1499
1500         IMAGE_UTIL_SAFE_FREE(_handle);
1501
1502         return err;
1503 }
1504
1505 static int _image_util_encode_create_jpeg_handle(decode_encode_s * handle)
1506 {
1507         int err = MM_UTIL_ERROR_NONE;
1508
1509         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1510
1511         mm_util_jpeg_yuv_data *_handle = (mm_util_jpeg_yuv_data *) calloc(1, sizeof(mm_util_jpeg_yuv_data));
1512         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1513
1514         handle->image_h = (mm_util_imgp_h) _handle;
1515         handle->colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888;
1516         handle->quality = 75;
1517
1518         return err;
1519 }
1520
1521 static int _image_util_encode_create_png_handle(decode_encode_s * handle)
1522 {
1523         int err = MM_UTIL_ERROR_NONE;
1524
1525         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1526
1527         mm_util_png_data *_handle = (mm_util_png_data *) calloc(1, sizeof(mm_util_png_data));
1528         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1529
1530         mm_util_init_encode_png(_handle);
1531
1532         handle->image_h = (mm_util_imgp_h) _handle;
1533
1534         return err;
1535 }
1536
1537 static int _image_util_encode_create_gif_handle(decode_encode_s * handle)
1538 {
1539         int err = MM_UTIL_ERROR_NONE;
1540
1541         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1542
1543         mm_util_gif_data *_handle = (mm_util_gif_data *) calloc(1, sizeof(mm_util_gif_data));
1544         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1545
1546         _handle->frames = (mm_util_gif_frame_data *) calloc(1, sizeof(mm_util_gif_frame_data));
1547         if (_handle->frames == NULL) {
1548                 image_util_error("Error - OUT_OF_MEMORY");
1549                 IMAGE_UTIL_SAFE_FREE(_handle);
1550                 return MM_UTIL_ERROR_OUT_OF_MEMORY;
1551         }
1552
1553         mm_util_gif_encode_set_image_count(_handle, 1);
1554         handle->image_h = (mm_util_imgp_h) _handle;
1555
1556         return err;
1557 }
1558
1559 static int _image_util_encode_create_bmp_handle(decode_encode_s * handle)
1560 {
1561         int err = MM_UTIL_ERROR_NONE;
1562
1563         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1564
1565         mm_util_bmp_data *_handle = (mm_util_bmp_data *) calloc(1, sizeof(mm_util_bmp_data));
1566         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1567
1568         handle->image_h = (mm_util_imgp_h) _handle;
1569
1570         return err;
1571 }
1572
1573 int image_util_encode_create(image_util_type_e image_type, image_util_encode_h * handle)
1574 {
1575         int err = MM_UTIL_ERROR_NONE;
1576
1577         image_util_debug("image_util_encode_create");
1578
1579         image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1580
1581         decode_encode_s *_handle = (decode_encode_s *) calloc(1, sizeof(decode_encode_s));
1582         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
1583
1584         _handle->image_type = image_type;
1585         _handle->src_buffer = NULL;
1586         _handle->dst_buffer = NULL;
1587         _handle->path = NULL;
1588         _handle->image_h = 0;
1589         _handle->is_decode = FALSE;
1590
1591         switch (image_type) {
1592         case IMAGE_UTIL_JPEG:
1593                 err = _image_util_encode_create_jpeg_handle(_handle);
1594                 break;
1595         case IMAGE_UTIL_PNG:
1596                 err = _image_util_encode_create_png_handle(_handle);
1597                 break;
1598         case IMAGE_UTIL_GIF:
1599                 err = _image_util_encode_create_gif_handle(_handle);
1600                 break;
1601         case IMAGE_UTIL_BMP:
1602                 err = _image_util_encode_create_bmp_handle(_handle);
1603                 break;
1604         default:
1605                 err = MM_UTIL_ERROR_INVALID_PARAMETER;
1606                 break;
1607         }
1608
1609         if (err != MM_UTIL_ERROR_NONE) {
1610                 image_util_error("Error - create image handle");
1611                 IMAGE_UTIL_SAFE_FREE(_handle);
1612                 return _convert_image_util_error_code(__func__, err);
1613         }
1614
1615         *handle = (image_util_encode_h) _handle;
1616
1617         return _convert_image_util_error_code(__func__, err);
1618 }
1619
1620 int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long width, unsigned long height)
1621 {
1622         int err = IMAGE_UTIL_ERROR_NONE;
1623         decode_encode_s *_handle = (decode_encode_s *) handle;
1624
1625         if (_handle == NULL || _handle->is_decode == TRUE) {
1626                 image_util_error("Invalid Handle");
1627                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1628         }
1629         image_util_retvm_if((_image_util_check_resolution(width, height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
1630
1631         switch (_handle->image_type) {
1632         case IMAGE_UTIL_JPEG:
1633                 {
1634                         mm_util_jpeg_yuv_data *jpeg_data;
1635
1636                         jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
1637                         if (jpeg_data == NULL) {
1638                                 image_util_error("Invalid jpeg data");
1639                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1640                         }
1641                         jpeg_data->width = width;
1642                         jpeg_data->height = height;
1643                 }
1644                 break;
1645         case IMAGE_UTIL_PNG:
1646                 {
1647                         mm_util_png_data *png_data;
1648
1649                         png_data = (mm_util_png_data *) _handle->image_h;
1650                         if (png_data == NULL) {
1651                                 image_util_error("Invalid png data");
1652                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1653                         }
1654                         mm_util_png_encode_set_width(png_data, width);
1655                         mm_util_png_encode_set_height(png_data, height);
1656                 }
1657                 break;
1658         case IMAGE_UTIL_GIF:
1659                 {
1660                         mm_util_gif_data *gif_data;
1661
1662                         gif_data = (mm_util_gif_data *) _handle->image_h;
1663                         if (gif_data == NULL) {
1664                                 image_util_error("Invalid gif data");
1665                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1666                         }
1667                         mm_util_gif_encode_set_width(gif_data, width);
1668                         mm_util_gif_encode_set_height(gif_data, height);
1669                 }
1670                 break;
1671         case IMAGE_UTIL_BMP:
1672                 {
1673                         mm_util_bmp_data *bmp_data;
1674
1675                         bmp_data = (mm_util_bmp_data *) _handle->image_h;
1676                         if (bmp_data == NULL) {
1677                                 image_util_error("Invalid bmp data");
1678                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1679                         }
1680                         mm_util_bmp_encode_set_width(bmp_data, width);
1681                         mm_util_bmp_encode_set_height(bmp_data, height);
1682                 }
1683                 break;
1684         default:
1685                 err = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1686                 break;
1687         }
1688
1689         _handle->width = width;
1690         _handle->height = height;
1691
1692         return err;
1693 }
1694
1695 int image_util_encode_set_colorspace(image_util_encode_h handle, image_util_colorspace_e colorspace)
1696 {
1697         int err = IMAGE_UTIL_ERROR_NONE;
1698         decode_encode_s *_handle = (decode_encode_s *) handle;
1699
1700         if (_handle == NULL || _handle->is_decode == TRUE) {
1701                 image_util_error("Invalid Handle");
1702                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1703         }
1704
1705         image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_jpeg_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
1706         switch (_handle->image_type) {
1707         case IMAGE_UTIL_JPEG:
1708                 image_util_retvm_if((_convert_jpeg_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1709                 break;
1710         case IMAGE_UTIL_PNG:
1711                 image_util_retvm_if((_convert_png_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1712                 break;
1713         case IMAGE_UTIL_GIF:
1714                 image_util_retvm_if((_convert_gif_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1715                 break;
1716         case IMAGE_UTIL_BMP:
1717                 image_util_retvm_if((_convert_bmp_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1718                 break;
1719         default:
1720                 image_util_error("Invalid image type");
1721                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1722         }
1723
1724         _handle->colorspace = colorspace;
1725
1726         return err;
1727 }
1728
1729 int image_util_encode_set_quality(image_util_encode_h handle, int quality)
1730 {
1731         int err = IMAGE_UTIL_ERROR_NONE;
1732         decode_encode_s *_handle = (decode_encode_s *) handle;
1733
1734         if (_handle == NULL || _handle->is_decode == TRUE) {
1735                 image_util_error("Invalid Handle");
1736                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1737         }
1738         if (_handle->image_type != IMAGE_UTIL_JPEG) {
1739                 image_util_error("Wrong image format");
1740                 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1741         }
1742         image_util_retvm_if((quality <= 0 || quality > 100), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid quality");
1743
1744         _handle->quality = quality;
1745
1746         return err;
1747 }
1748
1749 int image_util_encode_set_png_compression(image_util_encode_h handle, image_util_png_compression_e compression)
1750 {
1751         int err = IMAGE_UTIL_ERROR_NONE;
1752         decode_encode_s *_handle = (decode_encode_s *) handle;
1753         mm_util_png_data *png_data;
1754
1755         if (_handle == NULL || _handle->is_decode == TRUE) {
1756                 image_util_error("Invalid Handle");
1757                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1758         }
1759         if (_handle->image_type != IMAGE_UTIL_PNG) {
1760                 image_util_error("Wrong image format");
1761                 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1762         }
1763         image_util_retvm_if((compression < IMAGE_UTIL_PNG_COMPRESSION_0 || compression > IMAGE_UTIL_PNG_COMPRESSION_9), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid compression value");
1764
1765         png_data = (mm_util_png_data *) _handle->image_h;
1766         if (png_data == NULL) {
1767                 image_util_error("Invalid png data");
1768                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1769         }
1770
1771         mm_util_png_encode_set_compression_level(png_data, compression);
1772
1773         return err;
1774 }
1775
1776 int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigned char *src_buffer)
1777 {
1778         int err = IMAGE_UTIL_ERROR_NONE;
1779         decode_encode_s *_handle = (decode_encode_s *) handle;
1780
1781         if (_handle == NULL || _handle->is_decode == TRUE) {
1782                 image_util_error("Invalid Handle");
1783                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1784         }
1785         if (src_buffer == NULL) {
1786                 image_util_error("Invalid input buffer");
1787                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1788         }
1789
1790         _handle->src_buffer = (void *)src_buffer;
1791
1792         return err;
1793 }
1794
1795 int image_util_encode_set_output_path(image_util_encode_h handle, const char *path)
1796 {
1797         int err = IMAGE_UTIL_ERROR_NONE;
1798         decode_encode_s *_handle = (decode_encode_s *) handle;
1799
1800         if (_handle == NULL || _handle->is_decode == TRUE) {
1801                 image_util_error("Invalid Handle");
1802                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1803         }
1804         image_util_retvm_if((path == NULL || strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
1805
1806         if (_handle->dst_buffer)
1807                 _handle->dst_buffer = NULL;
1808
1809         _handle->path = path;
1810
1811         return err;
1812 }
1813
1814 int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned char **dst_buffer)
1815 {
1816         int err = IMAGE_UTIL_ERROR_NONE;
1817         decode_encode_s *_handle = (decode_encode_s *) handle;
1818
1819         if (_handle == NULL || _handle->is_decode == TRUE) {
1820                 image_util_error("Invalid Handle");
1821                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1822         }
1823         if (_handle->image_type == IMAGE_UTIL_BMP) {
1824                 image_util_error("BMP library does not support encoding to memory");
1825                 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1826         }
1827         if (dst_buffer == NULL) {
1828                 image_util_error("Invalid output buffer");
1829                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1830         }
1831
1832         if (_handle->path)
1833                 _handle->path = NULL;
1834
1835         _handle->dst_buffer = (void **)dst_buffer;
1836
1837         return err;
1838 }
1839
1840 static int _image_util_encode_internal(decode_encode_s * _handle)
1841 {
1842         int err = MM_UTIL_ERROR_NONE;
1843
1844         switch (_handle->image_type) {
1845         case IMAGE_UTIL_JPEG:
1846                 {
1847                         if (_handle->path)
1848                                 err = mm_util_jpeg_encode_to_file(_handle->path, _handle->src_buffer, _handle->width, _handle->height, _convert_jpeg_colorspace_tbl[_handle->colorspace], _handle->quality);
1849                         else
1850                                 err = mm_util_jpeg_encode_to_memory(_handle->dst_buffer, (int *)&(_handle->dst_size), _handle->src_buffer, _handle->width, _handle->height, _convert_jpeg_colorspace_tbl[_handle->colorspace], _handle->quality);
1851                 }
1852                 break;
1853         case IMAGE_UTIL_PNG:
1854                 {
1855                         mm_util_png_data *png_data;
1856
1857                         png_data = (mm_util_png_data *) _handle->image_h;
1858                         if (png_data == NULL) {
1859                                 image_util_error("Invalid png data");
1860                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1861                         }
1862
1863                         if (_handle->path)
1864                                 err = mm_util_encode_to_png_file(&(_handle->src_buffer), png_data, _handle->path);
1865                         else
1866                                 err = mm_util_encode_to_png_memory(&(_handle->src_buffer), png_data);
1867
1868                         if (err == MM_UTIL_ERROR_NONE) {
1869                                 if (_handle->dst_buffer)
1870                                         *(_handle->dst_buffer) = png_data->data;
1871                                 _handle->dst_size = png_data->size;
1872                                 _handle->width = png_data->width;
1873                                 _handle->height = png_data->height;
1874                         }
1875                 }
1876                 break;
1877         case IMAGE_UTIL_GIF:
1878                 {
1879                         mm_util_gif_data *gif_data;
1880                         void *dst_buffer = NULL;
1881
1882                         gif_data = (mm_util_gif_data *) _handle->image_h;
1883                         if (gif_data == NULL || gif_data->frames == NULL) {
1884                                 image_util_error("Invalid gif data");
1885                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1886                         }
1887
1888                         gif_data->frames[0].data = _handle->src_buffer;
1889                         if (_handle->path)
1890                                 err = mm_util_encode_gif_to_file(gif_data, _handle->path);
1891                         else
1892                                 err = mm_util_encode_gif_to_memory(gif_data, &dst_buffer);
1893
1894                         if (err == MM_UTIL_ERROR_NONE) {
1895                                 if (_handle->dst_buffer)
1896                                         *(_handle->dst_buffer) = (unsigned char *)dst_buffer;
1897                                 _handle->dst_size = gif_data->size;
1898                                 _handle->width = gif_data->width;
1899                                 _handle->height = gif_data->height;
1900                         }
1901                 }
1902                 break;
1903         case IMAGE_UTIL_BMP:
1904                 {
1905                         mm_util_bmp_data *bmp_data;
1906
1907                         bmp_data = (mm_util_bmp_data *) _handle->image_h;
1908                         if (bmp_data == NULL) {
1909                                 image_util_error("Invalid bmp data");
1910                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1911                         }
1912
1913                         bmp_data->data = _handle->src_buffer;
1914                         if (_handle->path)
1915                                 err = mm_util_encode_bmp_to_file(bmp_data, _handle->path);
1916                         else {
1917                                 image_util_error("Not yet implemented");
1918                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1919                         }
1920
1921                         if (err == MM_UTIL_ERROR_NONE) {
1922                                 if (_handle->dst_buffer)
1923                                         *(_handle->dst_buffer) = bmp_data->data;
1924                                 _handle->dst_size = bmp_data->size;
1925                                 _handle->width = bmp_data->width;
1926                                 _handle->height = bmp_data->height;
1927                         }
1928                 }
1929                 break;
1930         default:
1931                 err = MM_UTIL_ERROR_INVALID_PARAMETER;
1932                 break;
1933         }
1934
1935         return err;
1936 }
1937
1938 int image_util_encode_run(image_util_encode_h handle, unsigned long long *size)
1939 {
1940         int err = MM_UTIL_ERROR_NONE;
1941         decode_encode_s *_handle = (decode_encode_s *) handle;
1942
1943         if (_handle == NULL || _handle->is_decode == TRUE) {
1944                 image_util_error("Invalid Handle");
1945                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1946         }
1947         if ((_handle->path == NULL && _handle->dst_buffer == NULL) || _handle->src_buffer == NULL) {
1948                 image_util_error("Invalid input/output");
1949                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1950         }
1951         image_util_retvm_if((_image_util_check_resolution(_handle->width, _handle->height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
1952
1953         err = _image_util_encode_internal(_handle);
1954
1955         if (err != MM_UTIL_ERROR_NONE) {
1956                 image_util_error("Error - encode run");
1957                 return _convert_image_util_error_code(__func__, err);
1958         }
1959
1960         if (size)
1961                 *size = _handle->dst_size;
1962
1963         return _convert_image_util_error_code(__func__, err);
1964 }
1965
1966 gpointer _image_util_encode_thread(gpointer data)
1967 {
1968         decode_encode_s *_handle = (decode_encode_s *) data;
1969         int err = MM_UTIL_ERROR_NONE;
1970         gint64 end_time = 0;
1971
1972         if (!_handle) {
1973                 image_util_error("[ERROR] - handle");
1974                 return NULL;
1975         }
1976
1977         while (!_handle->is_finish) {
1978                 end_time = g_get_monotonic_time() + 1 * G_TIME_SPAN_SECOND;
1979                 image_util_debug("waiting...");
1980                 g_mutex_lock(&(_handle->thread_mutex));
1981                 g_cond_wait_until(&(_handle->thread_cond), &(_handle->thread_mutex), end_time);
1982                 image_util_debug("<=== get run encode thread signal");
1983                 g_mutex_unlock(&(_handle->thread_mutex));
1984
1985                 if (_handle->is_finish) {
1986                         image_util_debug("exit loop");
1987                         break;
1988                 }
1989
1990                 err = _image_util_encode_internal(_handle);
1991                 if (err == MM_UTIL_ERROR_NONE)
1992                         image_util_debug("Success - encode_internal");
1993                 else
1994                         image_util_error("Error - encode_internal");
1995
1996                 if (_handle->_encode_cb) {
1997                         image_util_debug("completed_cb");
1998                         _handle->is_finish = TRUE;
1999                         _handle->_encode_cb->image_encode_completed_cb(_convert_image_util_error_code(__func__, err), _handle->_encode_cb->user_data, _handle->dst_size);
2000                 }
2001         }
2002
2003         image_util_debug("exit thread");
2004
2005         return NULL;
2006 }
2007
2008 static int _image_util_encode_create_thread(decode_encode_s * handle)
2009 {
2010         int ret = MM_UTIL_ERROR_NONE;
2011
2012         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
2013
2014         g_mutex_init(&(handle->thread_mutex));
2015
2016         g_cond_init(&(handle->thread_cond));
2017
2018         /*create threads */
2019         handle->thread = g_thread_new("encode_thread", (GThreadFunc) _image_util_encode_thread, (gpointer) handle);
2020         if (!handle->thread) {
2021                 image_util_error("ERROR - create thread");
2022                 g_mutex_clear(&(handle->thread_mutex));
2023
2024                 g_cond_clear(&(handle->thread_cond));
2025                 return MM_UTIL_ERROR_INVALID_OPERATION;
2026         }
2027
2028         return ret;
2029 }
2030
2031 int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_completed_cb completed_cb, void *user_data)
2032 {
2033         int err = MM_UTIL_ERROR_NONE;
2034         decode_encode_s *_handle = (decode_encode_s *) handle;
2035
2036         if (_handle == NULL || _handle->is_decode == TRUE) {
2037                 image_util_error("Invalid Handle");
2038                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2039         }
2040         if ((_handle->path == NULL && _handle->dst_buffer == NULL) || _handle->src_buffer == NULL) {
2041                 image_util_error("Invalid input/output");
2042                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2043         }
2044         image_util_retvm_if((_image_util_check_resolution(_handle->width, _handle->height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
2045
2046         image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
2047
2048         if (_handle->_encode_cb != NULL) {
2049                 IMAGE_UTIL_SAFE_FREE(_handle->_encode_cb);
2050                 _handle->_encode_cb = NULL;
2051         }
2052         _handle->_encode_cb = (encode_cb_s *) calloc(1, sizeof(encode_cb_s));
2053         image_util_retvm_if((_handle->_encode_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
2054
2055         _handle->_encode_cb->user_data = user_data;
2056         _handle->_encode_cb->image_encode_completed_cb = completed_cb;
2057
2058         err = _image_util_encode_create_thread(_handle);
2059
2060         return _convert_image_util_error_code(__func__, err);
2061 }
2062
2063 int image_util_encode_destroy(image_util_encode_h handle)
2064 {
2065         int err = IMAGE_UTIL_ERROR_NONE;
2066         decode_encode_s *_handle = (decode_encode_s *) handle;
2067
2068         image_util_debug("image_util_encode_destroy");
2069
2070         if (_handle == NULL || _handle->is_decode == TRUE) {
2071                 image_util_error("Invalid Handle");
2072                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2073         }
2074
2075         switch (_handle->image_type) {
2076         case IMAGE_UTIL_JPEG:
2077                 {
2078                         mm_util_jpeg_yuv_data *jpeg_data;
2079
2080                         jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
2081                         if (jpeg_data == NULL) {
2082                                 image_util_error("Invalid jpeg data");
2083                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2084                         }
2085                         IMAGE_UTIL_SAFE_FREE(jpeg_data);
2086                 }
2087                 break;
2088         case IMAGE_UTIL_PNG:
2089                 {
2090                         mm_util_png_data *png_data;
2091
2092                         png_data = (mm_util_png_data *) _handle->image_h;
2093                         if (png_data == NULL) {
2094                                 image_util_error("Invalid png data");
2095                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2096                         }
2097                         IMAGE_UTIL_SAFE_FREE(png_data);
2098                 }
2099                 break;
2100         case IMAGE_UTIL_GIF:
2101                 {
2102                         mm_util_gif_data *gif_data;
2103
2104                         gif_data = (mm_util_gif_data *) _handle->image_h;
2105                         if (gif_data == NULL) {
2106                                 image_util_error("Invalid gif data");
2107                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2108                         }
2109                         IMAGE_UTIL_SAFE_FREE(gif_data->frames);
2110                         IMAGE_UTIL_SAFE_FREE(gif_data);
2111                 }
2112                 break;
2113         case IMAGE_UTIL_BMP:
2114                 {
2115                         mm_util_bmp_data *bmp_data;
2116
2117                         bmp_data = (mm_util_bmp_data *) _handle->image_h;
2118                         if (bmp_data == NULL) {
2119                                 image_util_error("Invalid bmp data");
2120                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2121                         }
2122                         IMAGE_UTIL_SAFE_FREE(bmp_data);
2123                 }
2124                 break;
2125         default:
2126                 err = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2127                 break;
2128         }
2129
2130         /* g_thread_exit(handle->thread); */
2131         if (_handle->thread) {
2132                 _handle->is_finish = TRUE;
2133                 g_mutex_lock(&(_handle->thread_mutex));
2134                 g_cond_signal(&(_handle->thread_cond));
2135                 image_util_debug("===> send signal(finish) to decode_thread");
2136                 g_mutex_unlock(&(_handle->thread_mutex));
2137
2138                 g_thread_join(_handle->thread);
2139
2140                 g_mutex_clear(&(_handle->thread_mutex));
2141
2142                 g_cond_clear(&(_handle->thread_cond));
2143         }
2144
2145         IMAGE_UTIL_SAFE_FREE(_handle);
2146
2147         return err;
2148 }