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