ca3e22d1873b35adc44138ba780c8746b99b4190
[platform/core/api/image-util.git] / src / image_util_decode.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 <mm_util_imgp.h>
18 #include <mm_util_jpeg.h>
19 #include <mm_util_png.h>
20 #include <mm_util_gif.h>
21 #include <mm_util_bmp.h>
22
23 #include <image_util.h>
24 #include <image_util_private.h>
25
26 static int _convert_decode_scale_tbl[] = {
27         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_1,
28         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_2,
29         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_4,
30         MM_UTIL_JPEG_DECODE_DOWNSCALE_1_8,
31 };
32
33 #define _NUM_OF_SCALE                   (sizeof(_convert_decode_scale_tbl)/sizeof(int))
34 #define _NOT_SUPPORTED_IMAGE_TYPE (-1)
35
36 static int _image_util_decode_read_header(const char *path, unsigned char **buffer)
37 {
38 #define IMG_HEADER_LENGTH 8
39
40         FILE *fp = NULL;
41         unsigned char *read_buffer = NULL;
42
43         image_util_retvm_if(!IMAGE_UTIL_STRING_VALID(path), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
44         image_util_retvm_if(buffer == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid buffer");
45
46         fp = fopen(path, "r");
47         if (fp == NULL) {
48                 image_util_error("File open failed %s", path);
49                 return IMAGE_UTIL_ERROR_NO_SUCH_FILE;
50         }
51
52         read_buffer = (void *)calloc(1, IMG_HEADER_LENGTH + 1);
53         if (read_buffer == NULL) {
54                 image_util_error("Allocation fail");
55                 fclose(fp);
56                 fp = NULL;
57                 return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
58         }
59
60         if (fread(read_buffer, 1, IMG_HEADER_LENGTH, fp) != IMG_HEADER_LENGTH) {
61                 image_util_error("File read failed");
62                 fclose(fp);
63                 fp = NULL;
64                 IMAGE_UTIL_SAFE_FREE(read_buffer);
65                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
66         }
67
68         *buffer = read_buffer;
69
70         fclose(fp);
71         fp = NULL;
72
73         return IMAGE_UTIL_ERROR_NONE;
74 }
75
76 static int _image_util_decode_check_image_type(const unsigned char *image_buffer, image_util_type_e *image_type)
77 {
78         static char _JPEG_HEADER[] = { 0xFF, 0xD8 };
79         static char _PNG_HEADER[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
80         static char _GIF_HEADER[] = { 'G', 'I', 'F' };
81         static char _BMP_HEADER[] = { 'B', 'M' };
82
83         static struct {
84                 char *header;
85                 int size;
86                 image_util_type_e image_type;
87         } image_header[] = {
88                 { _JPEG_HEADER, sizeof(_JPEG_HEADER), IMAGE_UTIL_JPEG },
89                 { _PNG_HEADER, sizeof(_PNG_HEADER), IMAGE_UTIL_PNG },
90                 { _GIF_HEADER, sizeof(_GIF_HEADER), IMAGE_UTIL_GIF },
91                 { _BMP_HEADER, sizeof(_BMP_HEADER), IMAGE_UTIL_BMP }
92         ,};
93         unsigned int i = 0;
94
95         image_util_retvm_if((image_buffer == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid buffer");
96         image_util_retvm_if((image_type == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid type");
97
98         *image_type = _NOT_SUPPORTED_IMAGE_TYPE;        /* init */
99         for (i = 0; i < sizeof(image_header) / sizeof(image_header[0]); i++) {
100                 if (strncmp((const char *)image_buffer, image_header[i].header, image_header[i].size) == 0) {
101                         *image_type = image_header[i].image_type;
102                         break;
103                 }
104         }
105
106         return IMAGE_UTIL_ERROR_NONE;
107 }
108
109 static void _image_util_decode_destroy_image_handle(decode_encode_s * handle)
110 {
111         image_util_retm_if((handle == NULL), "Invalid Handle");
112         void *image_handle =  (void *)(handle->image_h);
113         image_util_retm_if((image_handle == NULL), "Invalid image handle");
114
115         IMAGE_UTIL_SAFE_FREE(image_handle);
116 }
117
118 static int _image_util_decode_create_jpeg_handle(decode_encode_s * handle)
119 {
120         int err = MM_UTIL_ERROR_NONE;
121
122         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
123
124         /* It is needed to reuse decode handle for C#, so it shoud be reallocated */
125         _image_util_decode_destroy_image_handle(handle);
126
127         mm_util_jpeg_yuv_data *_handle = (mm_util_jpeg_yuv_data *) calloc(1, sizeof(mm_util_jpeg_yuv_data));
128         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
129
130         handle->image_h = (mm_util_imgp_h) _handle;
131         handle->colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888;
132         handle->down_scale = sizeof(image_util_scale_e);
133
134         return err;
135 }
136
137 static int _image_util_decode_create_png_handle(decode_encode_s * handle)
138 {
139         int err = MM_UTIL_ERROR_NONE;
140
141         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
142
143         /* It is needed to reuse decode handle for C#, so it shoud be reallocated */
144         _image_util_decode_destroy_image_handle(handle);
145
146         mm_util_png_data *_handle = (mm_util_png_data *) calloc(1, sizeof(mm_util_png_data));
147         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
148
149         mm_util_init_decode_png(_handle);
150
151         handle->image_h = (mm_util_imgp_h) _handle;
152
153         return err;
154 }
155
156 static int _image_util_decode_create_gif_handle(decode_encode_s * handle)
157 {
158         int err = MM_UTIL_ERROR_NONE;
159
160         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
161
162         /* It is needed to reuse decode handle for C#, so it shoud be reallocated */
163         _image_util_decode_destroy_image_handle(handle);
164
165         mm_util_gif_data *_handle = (mm_util_gif_data *) calloc(1, sizeof(mm_util_gif_data));
166         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
167
168         handle->image_h = (mm_util_imgp_h) _handle;
169
170         return err;
171 }
172
173 static int _image_util_decode_create_bmp_handle(decode_encode_s * handle)
174 {
175         int err = MM_UTIL_ERROR_NONE;
176
177         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
178
179         /* It is needed to reuse decode handle for C#, so it shoud be reallocated */
180         _image_util_decode_destroy_image_handle(handle);
181
182         mm_util_bmp_data *_handle = (mm_util_bmp_data *) calloc(1, sizeof(mm_util_bmp_data));
183         image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
184
185         handle->image_h = (mm_util_imgp_h) _handle;
186
187         return err;
188 }
189
190 int image_util_decode_create(image_util_decode_h * handle)
191 {
192         int err = MM_UTIL_ERROR_NONE;
193
194         image_util_debug("image_util_decode_create");
195
196         image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
197
198         decode_encode_s *_handle = (decode_encode_s *) calloc(1, sizeof(decode_encode_s));
199         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
200
201         _handle->src_buffer = NULL;
202         _handle->dst_buffer = NULL;
203         _handle->path = NULL;
204         _handle->image_h = 0;
205         _handle->is_decode = TRUE;
206         _handle->image_type = _NOT_SUPPORTED_IMAGE_TYPE;
207
208         *handle = (image_util_decode_h) _handle;
209
210         return _convert_image_util_error_code(__func__, err);
211 }
212
213 static int _image_util_decode_create_image_handle(image_util_decode_h handle)
214 {
215         int err = MM_UTIL_ERROR_NONE;
216         decode_encode_s *_handle = (decode_encode_s *) handle;
217
218         if (_handle == NULL || _handle->is_decode == FALSE) {
219                 image_util_error("Invalid Handle");
220                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
221         }
222
223         switch (_handle->image_type) {
224         case IMAGE_UTIL_JPEG:
225                 err = _image_util_decode_create_jpeg_handle(_handle);
226                 break;
227         case IMAGE_UTIL_PNG:
228                 err = _image_util_decode_create_png_handle(_handle);
229                 break;
230         case IMAGE_UTIL_GIF:
231                 err = _image_util_decode_create_gif_handle(_handle);
232                 break;
233         case IMAGE_UTIL_BMP:
234                 err = _image_util_decode_create_bmp_handle(_handle);
235                 break;
236         default:
237                 err = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
238                 break;
239         }
240
241         if (err != MM_UTIL_ERROR_NONE) {
242                 image_util_error("Error - create image handle");
243                 return _convert_image_util_error_code(__func__, err);
244         }
245
246         return _convert_image_util_error_code(__func__, err);
247 }
248
249 int image_util_decode_set_input_path(image_util_decode_h handle, const char *path)
250 {
251         int err = IMAGE_UTIL_ERROR_NONE;
252         decode_encode_s *_handle = (decode_encode_s *) handle;
253         unsigned char *image_header = NULL;
254
255         image_util_retvm_if(((_handle == NULL) || (_handle->is_decode == FALSE)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
256         image_util_retvm_if(!IMAGE_UTIL_STRING_VALID(path), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
257
258         if (_handle->src_buffer)
259                 _handle->src_buffer = NULL;
260
261         err = _image_util_decode_read_header(path, &image_header);
262         if (err != IMAGE_UTIL_ERROR_NONE) {
263                 image_util_error("_image_util_decode_read_header failed");
264                 return err;
265         }
266
267         err = _image_util_decode_check_image_type(image_header, &_handle->image_type);
268         if (err != IMAGE_UTIL_ERROR_NONE) {
269                 image_util_error("_image_util_decode_check_image_type failed");
270                 IMAGE_UTIL_SAFE_FREE(image_header);
271                 return err;
272         }
273
274         IMAGE_UTIL_SAFE_FREE(image_header);
275
276         err = _image_util_decode_create_image_handle(_handle);
277         if (err != IMAGE_UTIL_ERROR_NONE) {
278                 image_util_error("_image_util_decode_create_image_handle failed");
279                 return err;
280         }
281
282         _handle->path = g_strndup(path, strlen(path));
283
284         return err;
285 }
286
287 int image_util_decode_set_input_buffer(image_util_decode_h handle, const unsigned char *src_buffer, unsigned long long src_size)
288 {
289         int err = IMAGE_UTIL_ERROR_NONE;
290         decode_encode_s *_handle = (decode_encode_s *) handle;
291
292         if (_handle == NULL || _handle->is_decode == FALSE) {
293                 image_util_error("Invalid Handle");
294                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
295         }
296         if (src_buffer == NULL || src_size == 0) {
297                 image_util_error("Invalid input buffer");
298                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
299         }
300
301         IMAGE_UTIL_SAFE_FREE(_handle->path);
302
303         err = _image_util_decode_check_image_type(src_buffer, &_handle->image_type);
304         if (err != IMAGE_UTIL_ERROR_NONE) {
305                 image_util_error("_image_util_decode_check_image_type failed");
306                 return err;
307         }
308
309         err = _image_util_decode_create_image_handle(_handle);
310         if (err != IMAGE_UTIL_ERROR_NONE) {
311                 image_util_error("_image_util_decode_create_image_handle failed");
312                 return err;
313         }
314
315         IMAGE_UTIL_SAFE_FREE(_handle->src_buffer);
316
317         _handle->src_buffer = (void *)calloc(1, sizeof(void *));
318         if (_handle->src_buffer == NULL) {
319                 image_util_error("The memory of input buffer was not allocated");
320                 _image_util_decode_destroy_image_handle(_handle);
321                 return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
322         }
323
324         _handle->src_buffer[0] = (void *)src_buffer;
325         _handle->src_size = src_size;
326
327         return err;
328 }
329
330 int image_util_decode_set_output_buffer(image_util_decode_h handle, unsigned char **dst_buffer)
331 {
332         int err = IMAGE_UTIL_ERROR_NONE;
333         decode_encode_s *_handle = (decode_encode_s *) handle;
334
335         if (_handle == NULL || _handle->is_decode == FALSE) {
336                 image_util_error("Invalid Handle");
337                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
338         }
339         if (dst_buffer == NULL) {
340                 image_util_error("Invalid output buffer");
341                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
342         }
343
344         _handle->dst_buffer = (void **)dst_buffer;
345
346         return err;
347 }
348
349 int image_util_decode_set_colorspace(image_util_encode_h handle, image_util_colorspace_e colorspace)
350 {
351         int err = IMAGE_UTIL_ERROR_NONE;
352         decode_encode_s *_handle = (decode_encode_s *) handle;
353
354         if (_handle == NULL || _handle->is_decode == FALSE) {
355                 image_util_error("Invalid Handle");
356                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
357         }
358
359         image_util_retvm_if((is_valid_colorspace(colorspace) == FALSE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
360         if ((_handle->image_type == IMAGE_UTIL_JPEG) || (_handle->image_type == IMAGE_UTIL_PNG)
361                 || (_handle->image_type == IMAGE_UTIL_GIF) || (_handle->image_type == IMAGE_UTIL_BMP)) {
362                 image_util_retvm_if((is_supported_colorspace(colorspace, _handle->image_type) == FALSE), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
363         } else {
364                 image_util_error("Invalid image type");
365                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
366         }
367
368         _handle->colorspace = colorspace;
369
370         return err;
371 }
372
373 int image_util_decode_set_jpeg_downscale(image_util_encode_h handle, image_util_scale_e down_scale)
374 {
375         int err = IMAGE_UTIL_ERROR_NONE;
376         decode_encode_s *_handle = (decode_encode_s *) handle;
377
378         if (_handle == NULL || _handle->is_decode == FALSE) {
379                 image_util_error("Invalid Handle");
380                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
381         }
382         if (_handle->image_type != IMAGE_UTIL_JPEG) {
383                 image_util_error("Wrong image format");
384                 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
385         }
386         image_util_retvm_if((down_scale < 0 || down_scale >= _NUM_OF_SCALE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downscale is invalid");
387
388         _handle->down_scale = down_scale;
389
390         return err;
391 }
392
393 static int _image_util_decode_internal(decode_encode_s * _handle)
394 {
395         int err = MM_UTIL_ERROR_NONE;
396
397         switch (_handle->image_type) {
398         case IMAGE_UTIL_JPEG:
399                 {
400                         mm_util_jpeg_yuv_data *jpeg_data;
401
402                         jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
403                         if (jpeg_data == NULL) {
404                                 image_util_error("Invalid jpeg data");
405                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
406                         }
407
408                         if (_handle->path) {
409                                 if (_handle->down_scale < sizeof(image_util_scale_e))
410                                         err = mm_util_decode_from_jpeg_file_with_downscale(jpeg_data, _handle->path, TYPECAST_COLOR_BY_TYPE(_handle->colorspace, IMAGE_UTIL_JPEG), _convert_decode_scale_tbl[_handle->down_scale]);
411                                 else
412                                         err = mm_util_decode_from_jpeg_file(jpeg_data, _handle->path, TYPECAST_COLOR_BY_TYPE(_handle->colorspace, IMAGE_UTIL_JPEG));
413                         } else {
414                                 if (_handle->down_scale < sizeof(image_util_scale_e))
415                                         err = mm_util_decode_from_jpeg_memory_with_downscale(jpeg_data, _handle->src_buffer[0], (unsigned int)_handle->src_size, TYPECAST_COLOR_BY_TYPE(_handle->colorspace, IMAGE_UTIL_JPEG), _convert_decode_scale_tbl[_handle->down_scale]);
416                                 else
417                                         err = mm_util_decode_from_jpeg_memory(jpeg_data, _handle->src_buffer[0], (unsigned int)_handle->src_size, TYPECAST_COLOR_BY_TYPE(_handle->colorspace, IMAGE_UTIL_JPEG));
418                         }
419
420                         if (err == MM_UTIL_ERROR_NONE) {
421                                 *(_handle->dst_buffer) = jpeg_data->data;
422                                 _handle->dst_size = (unsigned long long)jpeg_data->size;
423                                 _handle->width = jpeg_data->width;
424                                 _handle->height = jpeg_data->height;
425                         }
426                 }
427                 break;
428         case IMAGE_UTIL_PNG:
429                 {
430                         mm_util_png_data *png_data;
431
432                         png_data = (mm_util_png_data *) _handle->image_h;
433                         if (png_data == NULL) {
434                                 image_util_error("Invalid png data");
435                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
436                         }
437
438                         if (_handle->path)
439                                 err = mm_util_decode_from_png_file(png_data, _handle->path);
440                         else
441                                 err = mm_util_decode_from_png_memory(png_data, &_handle->src_buffer[0], _handle->src_size);
442
443                         if (err == MM_UTIL_ERROR_NONE) {
444                                 *(_handle->dst_buffer) = png_data->data;
445                                 _handle->dst_size = png_data->size;
446                                 _handle->width = png_data->width;
447                                 _handle->height = png_data->height;
448                         }
449                 }
450                 break;
451         case IMAGE_UTIL_GIF:
452                 {
453                         mm_util_gif_data *gif_data;
454
455                         gif_data = (mm_util_gif_data *) _handle->image_h;
456                         if (gif_data == NULL) {
457                                 image_util_error("Invalid gif data");
458                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
459                         }
460
461                         if (_handle->path)
462                                 err = mm_util_decode_from_gif_file(gif_data, _handle->path);
463                         else
464                                 err = mm_util_decode_from_gif_memory(gif_data, &_handle->src_buffer[0]);
465
466                         if (err == MM_UTIL_ERROR_NONE) {
467                                 *(_handle->dst_buffer) = gif_data->frames[0]->data;
468                                 _handle->dst_size = gif_data->size;
469                                 _handle->width = gif_data->width;
470                                 _handle->height = gif_data->height;
471                         }
472                 }
473                 break;
474         case IMAGE_UTIL_BMP:
475                 {
476                         mm_util_bmp_data *bmp_data;
477
478                         bmp_data = (mm_util_bmp_data *) _handle->image_h;
479                         if (bmp_data == NULL) {
480                                 image_util_error("Invalid bmp data");
481                                 return MM_UTIL_ERROR_INVALID_PARAMETER;
482                         }
483
484                         if (_handle->path)
485                                 err = mm_util_decode_from_bmp_file(bmp_data, _handle->path);
486                         else
487                                 err = mm_util_decode_from_bmp_memory(bmp_data, &_handle->src_buffer[0], _handle->src_size);
488
489                         if (err == MM_UTIL_ERROR_NONE) {
490                                 *(_handle->dst_buffer) = bmp_data->data;
491                                 _handle->dst_size = bmp_data->size;
492                                 _handle->width = bmp_data->width;
493                                 _handle->height = bmp_data->height;
494                         }
495                 }
496                 break;
497         default:
498                 err = MM_UTIL_ERROR_INVALID_PARAMETER;
499                 break;
500         }
501
502         return err;
503 }
504
505 int image_util_decode_run(image_util_decode_h handle, unsigned long *width, unsigned long *height, unsigned long long *size)
506 {
507         int err = MM_UTIL_ERROR_NONE;
508         decode_encode_s *_handle = (decode_encode_s *) handle;
509
510         if (_handle == NULL || _handle->is_decode == FALSE) {
511                 image_util_error("Invalid Handle");
512                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
513         }
514         if ((_handle->path == NULL && _handle->src_buffer == NULL) || _handle->dst_buffer == NULL) {
515                 image_util_error("Invalid input/output");
516                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
517         }
518
519         err = _image_util_decode_internal(_handle);
520
521         if (err != MM_UTIL_ERROR_NONE) {
522                 image_util_error("Error - decode run");
523                 return _convert_image_util_error_code(__func__, err);
524         }
525
526         if (width)
527                 *width = _handle->width;
528         if (height)
529                 *height = _handle->height;
530         if (size)
531                 *size = _handle->dst_size;
532
533         return _convert_image_util_error_code(__func__, err);
534 }
535
536 gpointer _image_util_decode_thread(gpointer data)
537 {
538         decode_encode_s *_handle = (decode_encode_s *) data;
539         int err = MM_UTIL_ERROR_NONE;
540
541         if (!_handle) {
542                 image_util_error("[ERROR] - handle");
543                 return NULL;
544         }
545
546         err = _image_util_decode_internal(_handle);
547         if (err == MM_UTIL_ERROR_NONE)
548                 image_util_debug("Success - decode_internal");
549         else
550                 image_util_error("Error - decode_internal");
551
552         if (_handle->_decode_cb) {
553                 image_util_debug("completed_cb");
554                 _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);
555         }
556
557         image_util_debug("exit thread");
558
559         return NULL;
560 }
561
562 static int _image_util_decode_create_thread(decode_encode_s * handle)
563 {
564         int err = MM_UTIL_ERROR_NONE;
565
566         image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
567         image_util_retvm_if((handle->thread != NULL), MM_UTIL_ERROR_INVALID_OPERATION, "A thread is alread running");
568
569         /*create threads */
570         handle->thread = g_thread_new("decode_thread", (GThreadFunc) _image_util_decode_thread, (gpointer) handle);
571         if (!handle->thread) {
572                 image_util_error("ERROR - create thread");
573                 return MM_UTIL_ERROR_INVALID_OPERATION;
574         }
575
576         return err;
577 }
578
579 int image_util_decode_run_async(image_util_decode_h handle, image_util_decode_completed_cb completed_cb, void *user_data)
580 {
581         int err = MM_UTIL_ERROR_NONE;
582         decode_encode_s *_handle = (decode_encode_s *) handle;
583
584         if (_handle == NULL || _handle->is_decode == FALSE) {
585                 image_util_error("Invalid Handle");
586                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
587         }
588         if ((_handle->path == NULL && _handle->src_buffer == NULL) || _handle->dst_buffer == NULL) {
589                 image_util_error("Invalid input/output");
590                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
591         }
592         image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
593         image_util_retvm_if((_handle->thread != NULL), MM_UTIL_ERROR_INVALID_OPERATION, "A thread is alread running");
594
595         if (_handle->_decode_cb != NULL) {
596                 IMAGE_UTIL_SAFE_FREE(_handle->_decode_cb);
597                 _handle->_decode_cb = NULL;
598         }
599
600         _handle->_decode_cb = (decode_cb_s *) calloc(1, sizeof(decode_cb_s));
601         image_util_retvm_if((_handle->_decode_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
602
603         _handle->_decode_cb->user_data = user_data;
604         _handle->_decode_cb->image_decode_completed_cb = completed_cb;
605
606         err = _image_util_decode_create_thread(_handle);
607         if (err != MM_UTIL_ERROR_NONE) {
608                 IMAGE_UTIL_SAFE_FREE(_handle->_decode_cb);
609                 _handle->_decode_cb = NULL;
610         }
611
612         return _convert_image_util_error_code(__func__, err);
613 }
614
615 int image_util_decode_destroy(image_util_decode_h handle)
616 {
617         int err = IMAGE_UTIL_ERROR_NONE;
618         decode_encode_s *_handle = (decode_encode_s *) handle;
619
620         image_util_debug("image_util_decode_destroy");
621
622         if (_handle == NULL || _handle->is_decode == FALSE) {
623                 image_util_error("Invalid Handle");
624                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
625         }
626
627         _image_util_decode_destroy_image_handle(_handle);
628
629         /* g_thread_exit(handle->thread); */
630         if (_handle->thread) {
631                 g_thread_join(_handle->thread);
632                 IMAGE_UTIL_SAFE_FREE(_handle->_decode_cb);
633         }
634         IMAGE_UTIL_SAFE_FREE(_handle->src_buffer);
635         IMAGE_UTIL_SAFE_FREE(_handle);
636
637         return err;
638 }
639 int image_util_decode_jpeg(const char *path, image_util_colorspace_e colorspace, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
640 {
641         int err = MM_UTIL_ERROR_NONE;
642
643         DEPRECATION_LOGW("image_util_decode_jpeg()", "image_util_decode_create()");
644
645         image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
646         image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
647         image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
648         image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
649         image_util_retvm_if((is_valid_colorspace(colorspace) == FALSE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
650         image_util_retvm_if((is_supported_colorspace(colorspace, IMAGE_UTIL_JPEG) == FALSE), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
651
652         mm_util_jpeg_yuv_data decoded;
653         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
654
655         err = mm_util_decode_from_jpeg_file(&decoded, path, TYPECAST_COLOR_BY_TYPE(colorspace, IMAGE_UTIL_JPEG));
656         if (err == MM_UTIL_ERROR_NONE) {
657                 *image_buffer = decoded.data;
658                 if (width)
659                         *width = decoded.width;
660                 if (height)
661                         *height = decoded.height;
662                 if (size)
663                         *size = decoded.size;
664         }
665         return _convert_image_util_error_code(__func__, err);
666 }
667
668 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)
669 {
670         int err = MM_UTIL_ERROR_NONE;
671
672         DEPRECATION_LOGW("image_util_decode_jpeg_from_memory()", "image_util_decode_create()");
673
674         image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer 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((is_valid_colorspace(colorspace) == FALSE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
678         image_util_retvm_if((is_supported_colorspace(colorspace, IMAGE_UTIL_JPEG) == FALSE), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
679
680         mm_util_jpeg_yuv_data decoded;
681         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
682
683         err = mm_util_decode_from_jpeg_memory(&decoded, (void *)jpeg_buffer, (unsigned int)jpeg_size, TYPECAST_COLOR_BY_TYPE(colorspace, IMAGE_UTIL_JPEG));
684
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 = decoded.size;
693         }
694
695         return _convert_image_util_error_code(__func__, err);
696 }
697
698 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)
699 {
700         int err = MM_UTIL_ERROR_NONE;
701
702         DEPRECATION_LOGW("image_util_decode_jpeg_with_downscale()", "image_util_decode_create()");
703
704         image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
705         image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
706         image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
707         image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
708         image_util_retvm_if((is_valid_colorspace(colorspace) == FALSE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
709         image_util_retvm_if((is_supported_colorspace(colorspace, IMAGE_UTIL_JPEG) == FALSE), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
710         image_util_retvm_if((downscale < 0 || downscale >= _NUM_OF_SCALE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downsacle is invalid");
711
712         mm_util_jpeg_yuv_data decoded;
713         memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
714
715         err = mm_util_decode_from_jpeg_file_with_downscale(&decoded, path, TYPECAST_COLOR_BY_TYPE(colorspace, IMAGE_UTIL_JPEG), _convert_decode_scale_tbl[downscale]);
716         if (err == MM_UTIL_ERROR_NONE) {
717                 *image_buffer = decoded.data;
718                 if (width)
719                         *width = decoded.width;
720                 if (height)
721                         *height = decoded.height;
722                 if (size)
723                         *size = decoded.size;
724         }
725         return _convert_image_util_error_code(__func__, err);
726 }
727
728 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)
729 {
730         int err = MM_UTIL_ERROR_NONE;
731
732         DEPRECATION_LOGW("image_util_decode_jpeg_from_memory_with_downscale()", "image_util_decode_create()");
733
734         image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
735         image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
736         image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
737         image_util_retvm_if((is_valid_colorspace(colorspace) == FALSE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
738         image_util_retvm_if((is_supported_colorspace(colorspace, IMAGE_UTIL_JPEG) == FALSE), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
739         image_util_retvm_if((downscale < 0 || downscale >= _NUM_OF_SCALE), 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_memory_with_downscale(&decoded, (void *)jpeg_buffer, (unsigned int)jpeg_size, TYPECAST_COLOR_BY_TYPE(colorspace, IMAGE_UTIL_JPEG), _convert_decode_scale_tbl[downscale]);
745
746         if (err == MM_UTIL_ERROR_NONE) {
747                 *image_buffer = decoded.data;
748                 if (width)
749                         *width = decoded.width;
750                 if (height)
751                         *height = decoded.height;
752                 if (size)
753                         *size = decoded.size;
754         }
755
756         return _convert_image_util_error_code(__func__, err);
757 }