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