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