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