Update image_util_encode_set_output_buffer to return error when image type is BMP
[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 (_handle->image_type == IMAGE_UTIL_BMP) {
1811                 image_util_error("BMP library does not support encoding to memory");
1812                 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1813         }
1814         if (dst_buffer == NULL) {
1815                 image_util_error("Invalid output buffer");
1816                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1817         }
1818
1819         if (_handle->path)
1820                 _handle->path = NULL;
1821
1822         _handle->dst_buffer = (void **)dst_buffer;
1823
1824         return err;
1825 }
1826
1827 static int _image_util_encode_internal(decode_encode_s * _handle)
1828 {
1829         int err = MM_UTIL_ERROR_NONE;
1830
1831         switch (_handle->image_type) {
1832         case IMAGE_UTIL_JPEG:
1833                 {
1834                         if (_handle->path)
1835                                 err = mm_util_jpeg_encode_to_file (_handle->path, _handle->src_buffer, _handle->width, _handle->height, _convert_jpeg_colorspace_tbl[_handle->colorspace], _handle->quality);
1836                         else
1837                                 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);
1838                 }
1839                 break;
1840         case IMAGE_UTIL_PNG:
1841                 {
1842                         mm_util_png_data *png_data;
1843
1844                         png_data = (mm_util_png_data *) _handle->image_h;
1845                         if (png_data == NULL) {
1846                                 image_util_error("Invalid png data");
1847                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1848                         }
1849
1850                         if (_handle->path)
1851                                 err = mm_util_encode_to_png_file(&(_handle->src_buffer), png_data, _handle->path);
1852                         else
1853                                 err = mm_util_encode_to_png_memory(&(_handle->src_buffer), png_data);
1854
1855                         if (err == MM_UTIL_ERROR_NONE) {
1856                                 if (_handle->dst_buffer)
1857                                         *(_handle->dst_buffer) = png_data->data;
1858                                 _handle->dst_size = png_data->size;
1859                                 _handle->width = png_data->width;
1860                                 _handle->height = png_data->height;
1861                         }
1862                 }
1863                 break;
1864         case IMAGE_UTIL_GIF:
1865                 {
1866                         mm_util_gif_data *gif_data;
1867                         void *dst_buffer = NULL;
1868
1869                         gif_data = (mm_util_gif_data *) _handle->image_h;
1870                         if (gif_data == NULL || gif_data->frames == NULL) {
1871                                 image_util_error("Invalid gif data");
1872                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1873                         }
1874
1875                         gif_data->frames[0].data = _handle->src_buffer;
1876                         if (_handle->path)
1877                                 err = mm_util_encode_gif_to_file(gif_data, _handle->path);
1878                         else
1879                                 err = mm_util_encode_gif_to_memory(gif_data, &dst_buffer);
1880
1881                         if (err == MM_UTIL_ERROR_NONE) {
1882                                 if (_handle->dst_buffer)
1883                                         *(_handle->dst_buffer) = (unsigned char *)dst_buffer;
1884                                 _handle->dst_size = gif_data->size;
1885                                 _handle->width = gif_data->width;
1886                                 _handle->height = gif_data->height;
1887                         }
1888                 }
1889                 break;
1890         case IMAGE_UTIL_BMP:
1891                 {
1892                         mm_util_bmp_data *bmp_data;
1893
1894                         bmp_data = (mm_util_bmp_data *) _handle->image_h;
1895                         if (bmp_data == NULL) {
1896                                 image_util_error("Invalid bmp data");
1897                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1898                         }
1899
1900                         bmp_data->data = _handle->src_buffer;
1901                         if (_handle->path)
1902                                 err = mm_util_encode_bmp_to_file(bmp_data, _handle->path);
1903                         else {
1904                                 image_util_error("Not yet implemented");
1905                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
1906                         }
1907
1908                         if (err == MM_UTIL_ERROR_NONE) {
1909                                 if (_handle->dst_buffer)
1910                                         *(_handle->dst_buffer) = bmp_data->data;
1911                                 _handle->dst_size = bmp_data->size;
1912                                 _handle->width = bmp_data->width;
1913                                 _handle->height = bmp_data->height;
1914                         }
1915                 }
1916                 break;
1917         default:
1918                 err = MM_UTIL_ERROR_INVALID_PARAMETER;
1919                 break;
1920         }
1921
1922         return err;
1923 }
1924
1925 int image_util_encode_run(image_util_encode_h handle, unsigned long long *size)
1926 {
1927         int err = MM_UTIL_ERROR_NONE;
1928         decode_encode_s *_handle = (decode_encode_s *) handle;
1929
1930         if (_handle == NULL || _handle->is_decode == TRUE) {
1931                 image_util_error("Invalid Handle");
1932                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1933         }
1934         if ((_handle->path == NULL && _handle->dst_buffer == NULL) || _handle->src_buffer == NULL) {
1935                 image_util_error("Invalid input/output");
1936                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1937         }
1938         image_util_retvm_if((_image_util_check_resolution(_handle->width, _handle->height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
1939
1940         err = _image_util_encode_internal(_handle);
1941
1942         if (err != MM_UTIL_ERROR_NONE) {
1943                 image_util_error("Error - encode run");
1944                 return _convert_image_util_error_code(__func__, err);
1945         }
1946
1947         if(size)
1948                 *size = _handle->dst_size;
1949
1950         return _convert_image_util_error_code(__func__, err);
1951 }
1952
1953 gpointer _image_util_encode_thread(gpointer data)
1954 {
1955         decode_encode_s *_handle = (decode_encode_s *) data;
1956         int err = MM_UTIL_ERROR_NONE;
1957         gint64 end_time = 0;
1958
1959         if (!_handle) {
1960                 image_util_error("[ERROR] - handle");
1961                 return NULL;
1962         }
1963
1964         while (!_handle->is_finish) {
1965                 end_time = g_get_monotonic_time() + 1 * G_TIME_SPAN_SECOND;
1966                 image_util_debug("waiting...");
1967                 g_mutex_lock(&(_handle->thread_mutex));
1968                 g_cond_wait_until(&(_handle->thread_cond), &(_handle->thread_mutex), end_time);
1969                 image_util_debug("<=== get run encode thread signal");
1970                 g_mutex_unlock(&(_handle->thread_mutex));
1971
1972                 if (_handle->is_finish) {
1973                         image_util_debug("exit loop");
1974                         break;
1975                 }
1976
1977                 err = _image_util_encode_internal(_handle);
1978                 if(err == MM_UTIL_ERROR_NONE) {
1979                         image_util_debug("Success - encode_internal");
1980                 } else{
1981                         image_util_error("Error - encode_internal");
1982                 }
1983                 if (_handle->_encode_cb) {
1984                         image_util_debug("completed_cb");
1985                         _handle->is_finish = TRUE;
1986                         _handle->_encode_cb->image_encode_completed_cb(_convert_image_util_error_code(__func__, err), _handle->_encode_cb->user_data, _handle->dst_size);
1987                 }
1988         }
1989
1990         image_util_debug("exit thread");
1991
1992         return NULL;
1993 }
1994
1995 static int _image_util_encode_create_thread(decode_encode_s * handle)
1996 {
1997         int ret = MM_UTIL_ERROR_NONE;
1998
1999         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
2000
2001         g_mutex_init(&(handle->thread_mutex));
2002
2003         g_cond_init(&(handle->thread_cond));
2004
2005         /*create threads */
2006         handle->thread = g_thread_new("encode_thread", (GThreadFunc) _image_util_encode_thread, (gpointer) handle);
2007         if (!handle->thread) {
2008                 image_util_error("ERROR - create thread");
2009                 g_mutex_clear(&(handle->thread_mutex));
2010
2011                 g_cond_clear(&(handle->thread_cond));
2012                 return MM_UTIL_ERROR_INVALID_OPERATION;
2013         }
2014
2015         return ret;
2016 }
2017
2018 int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_completed_cb completed_cb, void *user_data)
2019 {
2020         int err = MM_UTIL_ERROR_NONE;
2021         decode_encode_s *_handle = (decode_encode_s *) handle;
2022
2023         if (_handle == NULL || _handle->is_decode == TRUE) {
2024                 image_util_error("Invalid Handle");
2025                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2026         }
2027         if ((_handle->path == NULL && _handle->dst_buffer == NULL) || _handle->src_buffer == NULL) {
2028                 image_util_error("Invalid input/output");
2029                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2030         }
2031         image_util_retvm_if((_image_util_check_resolution(_handle->width, _handle->height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
2032
2033         image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
2034
2035         if (_handle->_encode_cb != NULL) {
2036                 IMAGE_UTIL_SAFE_FREE(_handle->_encode_cb);
2037                 _handle->_encode_cb = NULL;
2038         }
2039         _handle->_encode_cb = (encode_cb_s *) calloc(1, sizeof(encode_cb_s));
2040         image_util_retvm_if((_handle->_encode_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
2041
2042         _handle->_encode_cb->user_data = user_data;
2043         _handle->_encode_cb->image_encode_completed_cb = completed_cb;
2044
2045         err = _image_util_encode_create_thread(_handle);
2046
2047         return _convert_image_util_error_code(__func__, err);
2048 }
2049
2050 int image_util_encode_destroy(image_util_encode_h handle)
2051 {
2052         int err = IMAGE_UTIL_ERROR_NONE;
2053         decode_encode_s *_handle = (decode_encode_s *) handle;
2054
2055         image_util_debug("image_util_encode_destroy");
2056
2057         if (_handle == NULL || _handle->is_decode == TRUE) {
2058                 image_util_error("Invalid Handle");
2059                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2060         }
2061
2062         switch (_handle->image_type) {
2063         case IMAGE_UTIL_JPEG:
2064                 {
2065                         mm_util_jpeg_yuv_data *jpeg_data;
2066
2067                         jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
2068                         if (jpeg_data == NULL) {
2069                                 image_util_error("Invalid jpeg data");
2070                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2071                         }
2072                         IMAGE_UTIL_SAFE_FREE(jpeg_data);
2073                 }
2074                 break;
2075         case IMAGE_UTIL_PNG:
2076                 {
2077                         mm_util_png_data *png_data;
2078
2079                         png_data = (mm_util_png_data *) _handle->image_h;
2080                         if (png_data == NULL) {
2081                                 image_util_error("Invalid png data");
2082                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2083                         }
2084                         IMAGE_UTIL_SAFE_FREE(png_data);
2085                 }
2086                 break;
2087         case IMAGE_UTIL_GIF:
2088                 {
2089                         mm_util_gif_data *gif_data;
2090
2091                         gif_data = (mm_util_gif_data *) _handle->image_h;
2092                         if (gif_data == NULL) {
2093                                 image_util_error("Invalid gif data");
2094                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2095                         }
2096                         IMAGE_UTIL_SAFE_FREE(gif_data->frames);
2097                         IMAGE_UTIL_SAFE_FREE(gif_data);
2098                 }
2099                 break;
2100         case IMAGE_UTIL_BMP:
2101                 {
2102                         mm_util_bmp_data *bmp_data;
2103
2104                         bmp_data = (mm_util_bmp_data *) _handle->image_h;
2105                         if (bmp_data == NULL) {
2106                                 image_util_error("Invalid bmp data");
2107                                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2108                         }
2109                         IMAGE_UTIL_SAFE_FREE(bmp_data);
2110                 }
2111                 break;
2112         default:
2113                 err = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2114                 break;
2115         }
2116
2117         /* g_thread_exit(handle->thread); */
2118         if (_handle->thread) {
2119                 _handle->is_finish = TRUE;
2120                 g_mutex_lock(&(_handle->thread_mutex));
2121                 g_cond_signal(&(_handle->thread_cond));
2122                 image_util_debug("===> send signal(finish) to decode_thread");
2123                 g_mutex_unlock(&(_handle->thread_mutex));
2124
2125                 g_thread_join(_handle->thread);
2126
2127                 g_mutex_clear(&(_handle->thread_mutex));
2128
2129                 g_cond_clear(&(_handle->thread_cond));
2130         }
2131
2132         IMAGE_UTIL_SAFE_FREE(_handle);
2133
2134         return err;
2135 }