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