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