Integrate IPC related errors
[platform/core/api/thumbnail-util.git] / src / thumbnail_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 <thumbnail_util.h>
18 #include <thumbnail_util_private.h>
19
20 /* For async API */
21 #include <storage.h>
22 #include <media-thumbnail.h>
23 #include <media-util.h>
24
25 /* For sync API */
26 #include <aul.h>
27 #include <mm_util_magick.h>
28 #include <mm_file.h>
29
30 #define MAX_SIZE 16
31 #define MAX_PATH_SIZE 4096
32
33 int __thumbnail_util_replace_path(const char *path, char *replace_path)
34 {
35         if (!STRING_VALID(path)) {
36                 thumbnail_util_error("Invalid path");
37                 return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
38         }
39
40         if (strncmp(path, MEDIA_ROOT_PATH_INTERNAL_OLD, strlen(MEDIA_ROOT_PATH_INTERNAL_OLD)) == 0) {
41                 thumbnail_util_sec_debug("Old path[%s]", path);
42                 snprintf(replace_path, MAX_PATH_SIZE, "%s%s", tzplatform_getenv(TZ_USER_CONTENT), path + strlen(MEDIA_ROOT_PATH_INTERNAL_OLD));
43         } else {
44                 snprintf(replace_path, MAX_PATH_SIZE, "%s", path);
45         }
46
47         if (!STRING_VALID(replace_path)) {
48                 thumbnail_util_error("replace failed");
49                 return THUMBNAIL_UTIL_ERROR_INVALID_OPERATION;
50         }
51
52         return THUMBNAIL_UTIL_ERROR_NONE;
53 }
54
55 int __thumbnail_util_error_capi(int content_error)
56 {
57         /*Error None*/
58         if (content_error == MS_MEDIA_ERR_NONE)
59                 return THUMBNAIL_UTIL_ERROR_NONE;
60
61         /* Internal operation error*/
62         else if ((content_error == MS_MEDIA_ERR_INVALID_PARAMETER) ||
63                 (content_error == MS_MEDIA_ERR_INVALID_PATH))
64                 return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
65
66         else if (content_error == MS_MEDIA_ERR_OUT_OF_MEMORY)
67                 return THUMBNAIL_UTIL_ERROR_OUT_OF_MEMORY;
68
69         /* IPC operation error*/
70         else if (content_error == MS_MEDIA_ERR_IPC)
71                 return THUMBNAIL_UTIL_ERROR_INVALID_OPERATION;
72
73         /* MEDIA SERVER error*/
74         else if (content_error == MS_MEDIA_ERR_PERMISSION_DENIED)
75                 return THUMBNAIL_UTIL_ERROR_PERMISSION_DENIED;
76
77         /* Thumbnail error*/
78         else if ((content_error == MS_MEDIA_ERR_THUMB_TOO_BIG) || (content_error == MS_MEDIA_ERR_THUMB_UNSUPPORTED))
79                         return THUMBNAIL_UTIL_ERROR_UNSUPPORTED_CONTENT;
80
81         /*ETC*/
82         return THUMBNAIL_UTIL_ERROR_INVALID_OPERATION;
83 }
84
85 void __thumbnail_util_convert_itoa(int request_id, char **req_str)
86 {
87         char buf[MAX_SIZE] = {0, };
88
89         snprintf(buf, MAX_SIZE, "%d", request_id);
90         *req_str = strndup(buf, strlen(buf));
91 }
92 void __thumbnail_util_extract_completed_cb(int error, int request_id, const char *path, int thumb_width, int thumb_height, unsigned char *thumb_data, int thumb_size, void *user_data)
93 {
94         thumbnail_extract_cb_s *_thumb_cb = (thumbnail_extract_cb_s *)user_data;
95         char *request_id_str = NULL;
96
97         if (_thumb_cb != NULL) {
98                 __thumbnail_util_convert_itoa(request_id, &request_id_str);
99                 if (_thumb_cb->thumb_extract_cb)
100                         _thumb_cb->thumb_extract_cb(__thumbnail_util_error_capi(error), request_id_str, thumb_width, thumb_height, thumb_data, thumb_size, _thumb_cb->user_data);
101
102         }
103         SAFE_FREE(_thumb_cb);
104 }
105
106 int thumbnail_util_create(thumbnail_h *thumb)
107 {
108         int ret = THUMBNAIL_UTIL_ERROR_NONE;
109         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_create() is deprecated and will be removed from next release.");
110
111         if (thumb == NULL) {
112                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
113                 return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
114         }
115
116         thumbnail_s *_thumb = (thumbnail_s *)malloc(sizeof(thumbnail_s));
117         if (_thumb == NULL) {
118                 thumbnail_util_error("OUT_OF_MEMORY(0x%08x)", THUMBNAIL_UTIL_ERROR_OUT_OF_MEMORY);
119                 return THUMBNAIL_UTIL_ERROR_OUT_OF_MEMORY;
120         }
121
122         _thumb->request_id = 0;
123         _thumb->file_path = NULL;
124         _thumb->dst_width = 0;
125         _thumb->dst_height = 0;
126
127         *thumb = (thumbnail_h)_thumb;
128
129         return ret;
130 }
131
132 int thumbnail_util_extract(thumbnail_h thumb, thumbnail_extracted_cb callback, void *user_data, char **request_id)
133 {
134         int ret = THUMBNAIL_UTIL_ERROR_NONE;
135         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_extract() is deprecated and will be removed from next release. Use thumbnail_util_extract_to_file() or thumbnail_util_extract_to_buffer() instead.");
136         int res = 0;
137         static int g_thumbnail_req_id = 0;
138         thumbnail_s *_thumb = (thumbnail_s *)thumb;
139
140         if (_thumb != NULL && STRING_VALID(_thumb->file_path)) {
141                 g_thumbnail_req_id++;
142                 _thumb->request_id = g_thumbnail_req_id;
143                 __thumbnail_util_convert_itoa(_thumb->request_id, request_id);
144                 thumbnail_extract_cb_s *_thumb_cb = (thumbnail_extract_cb_s *)calloc(1, sizeof(thumbnail_extract_cb_s));
145
146                 if (_thumb_cb != NULL) {
147                         _thumb_cb->user_data = user_data;
148                         _thumb_cb->thumb_extract_cb = callback;
149                 }
150
151                 if (_thumb->dst_width == 0 || _thumb->dst_height == 0) {
152                         _thumb->dst_width = 320;
153                         _thumb->dst_height = 240;
154                 }
155
156                 res = thumbnail_request_extract_raw_data_async(_thumb->request_id, _thumb->file_path, _thumb->dst_width, _thumb->dst_height, (ThumbRawFunc)__thumbnail_util_extract_completed_cb, (void *)_thumb_cb, tzplatform_getuid(TZ_USER_NAME));
157                 ret = __thumbnail_util_error_capi(res);
158                 if (ret != THUMBNAIL_UTIL_ERROR_NONE)
159                         free(_thumb_cb);
160         } else {
161                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
162                 ret = THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
163         }
164
165         return ret;
166 }
167
168 int thumbnail_util_set_path(thumbnail_h thumb, const char *path)
169 {
170         int ret = THUMBNAIL_UTIL_ERROR_NONE;
171         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_set_path() is deprecated and will be removed from next release.");
172         char repl_path[MAX_PATH_SIZE + 1] = {0, };
173         thumbnail_s *_thumb = (thumbnail_s *)thumb;
174
175         if (_thumb != NULL && path != NULL) {
176                 SAFE_FREE(_thumb->file_path);
177                 memset(repl_path, 0, sizeof(repl_path));
178                 ret = __thumbnail_util_replace_path(path, repl_path);
179                 if (ret != THUMBNAIL_UTIL_ERROR_NONE) {
180                         thumbnail_util_error("Convert path failed");
181                         _thumb->file_path = NULL;
182                 } else {
183                         _thumb->file_path = strndup(repl_path, strlen(repl_path));
184                 }
185         } else {
186                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
187                 ret = THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
188         }
189
190         return ret;
191 }
192
193 int thumbnail_util_set_size(thumbnail_h thumb, int width, int height)
194 {
195         int ret = THUMBNAIL_UTIL_ERROR_NONE;
196         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_set_size() is deprecated and will be removed from next release.");
197         thumbnail_s *_thumb = (thumbnail_s *)thumb;
198
199         if (_thumb != NULL && width > 0 && height > 0) {
200                 _thumb->dst_width = width;
201                 _thumb->dst_height = height;
202         } else {
203                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
204                 ret = THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
205         }
206
207         return ret;
208 }
209
210 int thumbnail_util_cancel(thumbnail_h thumb, const char *request_id)
211 {
212         int ret = THUMBNAIL_UTIL_ERROR_NONE;
213         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_cancel() is deprecated and will be removed from next release.");
214         thumbnail_s *_thumb = (thumbnail_s *)thumb;
215
216         if (_thumb != NULL && STRING_VALID(request_id)) {
217                 unsigned int request_id_integer = atoi(request_id);
218                 ret = thumbnail_request_cancel_raw_data(request_id_integer);
219         } else {
220                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
221                 ret = THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
222         }
223
224         return ret;
225 }
226
227 int thumbnail_util_destroy(thumbnail_h thumb)
228 {
229         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_destroy() is deprecated and will be removed from next release.");
230         int ret = THUMBNAIL_UTIL_ERROR_NONE;
231         thumbnail_s *_thumb = (thumbnail_s *)thumb;
232
233         if (_thumb) {
234                 SAFE_FREE(_thumb->file_path);
235                 SAFE_FREE(_thumb);
236         } else {
237                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
238                 ret = THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
239         }
240
241         return ret;
242 }
243
244 ////////////////////////////////////////// Sync
245
246 static void __thumbnail_util_destroy_thumb_data(thumbnail_data_s *thumb)
247 {
248         SAFE_FREE(thumb->path);
249         SAFE_FREE(thumb->thumbnail_path);
250         SAFE_FREE(thumb->buffer);
251         SAFE_FREE(thumb);
252 }
253
254 static void __thumbnail_util_get_proper_thumb_size(unsigned int orig_w, unsigned int orig_h, unsigned int *thumb_w, unsigned int *thumb_h)
255 {
256         bool portrait = false;
257         double ratio = 0.0;
258
259         thumbnail_util_retm_if(orig_w == 0, "Invalid orig_w");
260         thumbnail_util_retm_if(orig_h == 0, "Invalid orig_h");
261         thumbnail_util_retm_if(!thumb_w, "Invalid thumb_w");
262         thumbnail_util_retm_if(!thumb_h, "Invalid thumb_h");
263
264         if (orig_w < orig_h)
265                 portrait = true;
266
267         /* Set smaller length to default size */
268         if (portrait) {
269                 if (orig_w < *thumb_w)
270                         *thumb_w = orig_w;
271                 ratio = (double)orig_h / (double)orig_w;
272                 *thumb_h = *thumb_w * ratio;
273         } else {
274                 if (orig_h < *thumb_h)
275                         *thumb_h = orig_h;
276                 ratio = (double)orig_w / (double)orig_h;
277                 *thumb_w = *thumb_h * ratio;
278         }
279
280         thumbnail_util_debug("proper thumb w: %d h: %d", *thumb_w, *thumb_h);
281
282 }
283
284 static int __thumbnail_util_extract_video(thumbnail_data_s *thumb)
285 {
286         int ret = THUMBNAIL_UTIL_ERROR_NONE;
287         MMHandleType content = NULL;
288         MMHandleType tag = NULL;
289         void *frame = NULL;
290         int video_track_num = 0;
291         char *err_msg = NULL;
292         int size = 0;
293         unsigned int width = 0;
294         unsigned int height = 0;
295         unsigned int thumb_width = 0;
296         unsigned int thumb_height = 0;
297         int cdis_value = 0;
298         mm_util_image_h img = NULL;
299
300         thumbnail_util_retvm_if(thumb == NULL, THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER, "Data is NULL");
301
302         thumb_width = thumb->width;
303         thumb_height = thumb->height;
304
305         //1. get CDIS
306         ret = mm_file_create_tag_attrs(&tag, thumb->path);
307         if (ret == FILEINFO_ERROR_NONE) {
308                 ret = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_CDIS, &cdis_value, NULL);
309                 if (ret != FILEINFO_ERROR_NONE) {
310                         cdis_value = 0;
311                         SAFE_FREE(err_msg);
312                 }
313         } else {
314                 cdis_value = 0;
315         }
316
317         ret = mm_file_destroy_tag_attrs(tag);
318         if (ret != FILEINFO_ERROR_NONE) {
319                 thumbnail_util_error("fail to free tag attr - err(%x)", ret);
320         }
321
322         thumbnail_util_warn("CDIS vlaue[%d]", cdis_value);
323         if (cdis_value == 1)
324                 ret = mm_file_create_content_attrs_safe(&content, thumb->path);
325         else
326                 ret = mm_file_create_content_attrs(&content, thumb->path);
327
328         thumbnail_util_retvm_if(ret != FILEINFO_ERROR_NONE, THUMBNAIL_UTIL_ERROR_INVALID_OPERATION, "mm_file_create_content_attrs fails");
329
330         //2. get frame
331         ret = mm_file_get_attrs(content, &err_msg, MM_FILE_CONTENT_VIDEO_TRACK_COUNT, &video_track_num, NULL);
332         if (ret != FILEINFO_ERROR_NONE) {
333                 thumbnail_util_error("mm_file_get_attrs fails : %s", err_msg);
334                 SAFE_FREE(err_msg);
335                 goto ERROR;
336         }
337
338         if (video_track_num > 0) {
339                 ret = mm_file_get_attrs(content, &err_msg,
340                                         MM_FILE_CONTENT_VIDEO_WIDTH,
341                                         &width,
342                                         MM_FILE_CONTENT_VIDEO_HEIGHT,
343                                         &height,
344                                         MM_FILE_CONTENT_VIDEO_THUMBNAIL, &frame,
345                                         &size, NULL);
346
347                 if (ret != FILEINFO_ERROR_NONE) {
348                         thumbnail_util_error("mm_file_get_attrs fails : %s", err_msg);
349                         SAFE_FREE(err_msg);
350                         goto ERROR;
351                 }
352
353                 thumbnail_util_debug("W[%d] H[%d] Size[%d] Frame[%p]", width, height, size, frame);
354
355                 if (frame == NULL || width == 0 || height == 0) {
356                         thumbnail_util_error("Failed to get frame data");
357                         goto ERROR;
358                 }
359
360                 ret = mm_image_create_image(width, height, MM_UTIL_COLOR_RGB24, frame, size, &img);
361                 if (ret != MM_UTIL_ERROR_NONE) {
362                         thumbnail_util_error("Failed to mm_image_create_image");
363                         goto ERROR;
364                 }
365
366                 /* check thumb size */
367                 __thumbnail_util_get_proper_thumb_size(width, height, &thumb_width, &thumb_height);
368
369                 if (thumb->extract_type == THUMBNAIL_UTIL_FILE) {
370                         ret = mm_util_resize_B_P(img, thumb_width, thumb_height, thumb->thumbnail_path);
371                         mm_image_destroy_image(img);
372                         if (ret != MM_UTIL_ERROR_NONE)
373                                 goto ERROR;
374                 } else {
375                         mm_util_image_h res_img = NULL;
376                         unsigned char *res_buf = NULL;
377                         unsigned int res_width = 0;
378                         unsigned int res_height = 0;
379                         size_t res_buf_size = 0;
380                         mm_util_color_format_e res_format = MM_UTIL_COLOR_NUM;
381
382                         ret = mm_util_resize_B_B(img, thumb_width, thumb_height, &res_img);
383                         mm_image_destroy_image(img);
384                         if (ret != MM_UTIL_ERROR_NONE)
385                                 goto ERROR;
386                         ret = mm_image_get_image(res_img, &res_width, &res_height, &res_format, &res_buf, &res_buf_size);
387                         mm_image_destroy_image(res_img);
388                         if (ret != MM_UTIL_ERROR_NONE)
389                                 goto ERROR;
390
391                         thumb->buffer = malloc(res_buf_size * sizeof(unsigned char));
392                         if (thumb->buffer != NULL) {
393                                 memcpy(thumb->buffer, res_buf, res_buf_size);
394                                 thumb->buffer_size = res_buf_size;
395                                 thumb->width = res_width;
396                                 thumb->height = res_height;
397                         } else {
398                                 SAFE_FREE(res_buf);
399                                 goto ERROR;
400                         }
401
402                         SAFE_FREE(res_buf);
403                 }
404         }
405
406         mm_file_destroy_content_attrs(content);
407         return THUMBNAIL_UTIL_ERROR_NONE;
408 ERROR:
409         mm_file_destroy_content_attrs(content);
410         return THUMBNAIL_UTIL_ERROR_OUT_OF_MEMORY;
411 }
412
413 static int __thumbnail_util_extract(thumbnail_data_s *thumb)
414 {
415         int ret = THUMBNAIL_UTIL_ERROR_NONE;
416         unsigned int orig_width = 0;
417         unsigned int orig_height = 0;
418         unsigned int thumb_width = 0;
419         unsigned int thumb_height = 0;
420         mm_util_img_codec_type type = IMG_CODEC_UNKNOWN_TYPE;
421
422         thumbnail_util_retvm_if(thumb == NULL, THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER, "Data is NULL");
423
424         if (thumb->media_type == THUMBNAIL_UTIL_IMAGE) {
425                 thumb_width = thumb->width;
426                 thumb_height = thumb->height;
427                 /* Get original resolution */
428                 ret = mm_util_extract_image_info(thumb->path, &type, &orig_width, &orig_height);
429                 thumbnail_util_retv_if(ret != MM_UTIL_ERROR_NONE, THUMBNAIL_UTIL_ERROR_INVALID_OPERATION);
430
431                 __thumbnail_util_get_proper_thumb_size(orig_width, orig_height, &thumb_width, &thumb_height);
432
433                 if (thumb->extract_type == THUMBNAIL_UTIL_FILE) {
434                         ret = mm_util_resize_P_P(thumb->path, thumb_width, thumb_height, thumb->thumbnail_path);
435                         thumbnail_util_retv_if(ret != MM_UTIL_ERROR_NONE, THUMBNAIL_UTIL_ERROR_INVALID_OPERATION);
436
437                 } else {
438                         mm_util_image_h res_img = NULL;
439                         unsigned char *buf = NULL;
440                         unsigned int width = 0;
441                         unsigned int height = 0;
442                         size_t buf_size = 0;
443                         mm_util_color_format_e format = MM_UTIL_COLOR_NUM;
444
445                         ret = mm_util_resize_P_B(thumb->path, thumb_width, thumb_height, MM_UTIL_COLOR_BGRA, &res_img);
446                         thumbnail_util_retv_if(ret != MM_UTIL_ERROR_NONE, THUMBNAIL_UTIL_ERROR_INVALID_OPERATION);
447
448                         ret = mm_image_get_image(res_img, &width, &height, &format, &buf, &buf_size);
449                         mm_image_destroy_image(res_img);
450                         thumbnail_util_retv_if(ret != MM_UTIL_ERROR_NONE, THUMBNAIL_UTIL_ERROR_INVALID_OPERATION);
451
452                         thumb->buffer = malloc(buf_size * sizeof(unsigned char));
453                         if (thumb->buffer != NULL) {
454                                 memcpy(thumb->buffer, buf, buf_size);
455                                 thumb->buffer_size = buf_size;
456                                 thumb->width = width;
457                                 thumb->height = height;
458                         } else {
459                                 SAFE_FREE(buf);
460                                 return THUMBNAIL_UTIL_ERROR_OUT_OF_MEMORY;
461                         }
462
463                         SAFE_FREE(buf);
464                 }
465         } else {
466                 ret = __thumbnail_util_extract_video(thumb);
467                 thumbnail_util_retvm_if(ret != THUMBNAIL_UTIL_ERROR_NONE, ret, "__thumbnail_util_extract_video failed");
468         }
469
470         return THUMBNAIL_UTIL_ERROR_NONE;
471 }
472
473 int __thumbnail_util_get_file_ext(const char *file_path, char *file_ext, int max_len)
474 {
475         int i = 0;
476
477         for (i = (int)strlen(file_path); i >= 0; i--) {
478                 if ((file_path[i] == '.') && (i < (int)strlen(file_path))) {
479                         strncpy(file_ext, &file_path[i + 1], max_len);
480                         return THUMBNAIL_UTIL_ERROR_NONE;
481                 }
482
483                 /* meet the dir. no ext */
484                 if (file_path[i] == '/')
485                         return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
486         }
487
488         return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
489 }
490
491 static int __thumbnail_util_check_media_type(const char *path, thumbnail_util_media_type_e *type)
492 {
493         int ret = THUMBNAIL_UTIL_ERROR_NONE;
494         char mimetype[255] = {0,};
495         const char *unsupported_type = "image/tiff";
496         const char *supported_type = "application/vnd.ms-asf";
497
498         // Check file is existed
499         thumbnail_util_retv_if(path == NULL, THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
500         if (access(path, R_OK) < 0) {
501                 if (errno == EACCES || errno == EPERM) {
502                         thumbnail_util_error("Fail to open path: Permission Denied [%s]", path);
503                         return  THUMBNAIL_UTIL_ERROR_PERMISSION_DENIED;
504                 } else {
505                         thumbnail_util_error("Fail to open path: Invalid Path [%s]", path);
506                         return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
507                 }
508         }
509
510         // Check media type
511         ret = aul_get_mime_from_file(path, mimetype, sizeof(mimetype));
512         thumbnail_util_retvm_if(ret < 0, THUMBNAIL_UTIL_ERROR_INVALID_OPERATION, "aul_get_mime_from_file failed");
513
514         thumbnail_util_debug("mime type : %s", mimetype);
515
516         /* categorize from mimetype */
517         if (strstr(mimetype, "image") != NULL) {
518                 thumbnail_util_retvm_if(!strcmp(mimetype, unsupported_type), THUMBNAIL_UTIL_ERROR_UNSUPPORTED_CONTENT, "This is unsupport file type");
519                 *type = THUMBNAIL_UTIL_IMAGE;
520                 return THUMBNAIL_UTIL_ERROR_NONE;
521         } else if (strstr(mimetype, "video") != NULL) {
522                 *type = THUMBNAIL_UTIL_VIDEO;
523                 return THUMBNAIL_UTIL_ERROR_NONE;
524         } else if (strstr(mimetype, supported_type) != NULL) {
525                 *type = THUMBNAIL_UTIL_VIDEO;
526                 return THUMBNAIL_UTIL_ERROR_NONE;
527         }
528
529         return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
530 }
531
532 static bool __thumbnail_util_is_support_img(const char *path)
533 {
534         int ret = THUMBNAIL_UTIL_ERROR_NONE;
535         mm_util_img_codec_type t = IMG_CODEC_UNKNOWN_TYPE;
536         unsigned int w = 0;
537         unsigned int h = 0;
538
539         ret = mm_util_extract_image_info(path, &t, &w, &h);
540         if (ret != MM_UTIL_ERROR_NONE || t == IMG_CODEC_UNKNOWN_TYPE)
541                 return false;
542         else
543                 return true;
544 }
545
546 int thumbnail_util_extract_to_buffer(const char *path, unsigned int width, unsigned int height, unsigned char **thumb_buffer, size_t *thumb_size, unsigned int *thumb_width, unsigned int *thumb_height)
547 {
548         int ret = THUMBNAIL_UTIL_ERROR_NONE;
549         thumbnail_data_s *thumb = NULL;
550         thumbnail_util_media_type_e type = -1;
551
552         thumbnail_util_retvm_if(!STRING_VALID(path), THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER, "Wrong path");
553         thumbnail_util_retvm_if((width > 2000 || width == 0) || (height > 2000 || width == 0), THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER, "Wrong width/height");
554         thumbnail_util_retvm_if(thumb_buffer == NULL || thumb_size == NULL || thumb_width == NULL || thumb_height == NULL, THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER, "Out param is NULL");
555
556         /* check media type */
557         ret = __thumbnail_util_check_media_type(path, &type);
558         thumbnail_util_retvm_if(ret != THUMBNAIL_UTIL_ERROR_NONE, ret, "__thumbnail_util_check_media_type failed");
559
560         /* If image, check support format */
561         if (type == THUMBNAIL_UTIL_IMAGE) {
562                 if (__thumbnail_util_is_support_img(path) == false) {
563                         thumbnail_util_error("This image format is not supported");
564                         return THUMBNAIL_UTIL_ERROR_UNSUPPORTED_CONTENT;
565                 }
566         }
567
568         thumb = calloc(1, sizeof(thumbnail_data_s));
569         thumb->extract_type = THUMBNAIL_UTIL_BUFFER;
570         thumb->media_type = type;
571         thumb->path = g_strdup(path);
572         thumb->width = width;
573         thumb->height = height;
574
575         if (thumb->path == NULL) {
576                 __thumbnail_util_destroy_thumb_data(thumb);
577                 return THUMBNAIL_UTIL_ERROR_OUT_OF_MEMORY;
578         }
579
580         ret = __thumbnail_util_extract(thumb);
581         if (ret != THUMBNAIL_UTIL_ERROR_NONE) {
582                 thumbnail_util_error("Extract failed");
583         } else {
584                 *thumb_buffer = malloc(thumb->buffer_size);
585                 memcpy(*thumb_buffer, thumb->buffer, thumb->buffer_size);
586                 *thumb_size = thumb->buffer_size;
587                 *thumb_width = thumb->width;
588                 *thumb_height = thumb->height;
589         }
590
591         __thumbnail_util_destroy_thumb_data(thumb);
592
593         return ret;
594 }
595
596 int thumbnail_util_extract_to_file(const char *path, unsigned int width, unsigned int height, const char *thumbnail_path)
597 {
598         int ret = THUMBNAIL_UTIL_ERROR_NONE;
599         char *check_str = NULL;
600         thumbnail_data_s *thumb = NULL;
601         thumbnail_util_media_type_e type = -1;
602
603         thumbnail_util_retvm_if(!STRING_VALID(path), THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER, "Wrong path");
604         thumbnail_util_retvm_if((width > 2000 || width == 0) || (height > 2000 || height == 0), THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER, "Wrong width/height");
605         thumbnail_util_retvm_if(!STRING_VALID(thumbnail_path), THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER, "Wrong thumbnail_path");
606
607         /* check media type */
608         ret = __thumbnail_util_check_media_type(path, &type);
609         thumbnail_util_retvm_if(ret != THUMBNAIL_UTIL_ERROR_NONE, ret, "__thumbnail_util_check_media_type failed");
610
611         /* If image, check support format */
612         if (type == THUMBNAIL_UTIL_IMAGE) {
613                 if (__thumbnail_util_is_support_img(path) == false) {
614                         thumbnail_util_error("This image format is not supported");
615                         return THUMBNAIL_UTIL_ERROR_UNSUPPORTED_CONTENT;
616                 }
617         }
618
619         /* check thumbnail path is writable */
620         check_str = g_path_get_dirname(thumbnail_path);
621         if (check_str != NULL) {
622                 if (access(check_str, W_OK) != 0) {
623                         thumbnail_util_error("No permission to write[%s]", check_str);
624                         SAFE_FREE(check_str);
625                         return THUMBNAIL_UTIL_ERROR_PERMISSION_DENIED;
626                 } else {
627                         SAFE_FREE(check_str);
628                 }
629         }
630
631         /* If video file, thumbnail extension is only JPEG */
632         if (type == THUMBNAIL_UTIL_VIDEO) {
633                 char ext[255] = { 0 };
634                 ret = __thumbnail_util_get_file_ext(thumbnail_path, ext, sizeof(ext));
635                 thumbnail_util_retvm_if(ret != THUMBNAIL_UTIL_ERROR_NONE, ret, "__thumbnail_util_get_file_ext failed");
636                 if (strcasecmp(ext, "JPG") != 0 && strcasecmp(ext, "JPEG") != 0) {
637                         thumbnail_util_error("Wrong file name[%s]", thumbnail_path);
638                         return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
639                 }
640         }
641
642         thumb = calloc(1, sizeof(thumbnail_data_s));
643         thumb->extract_type = THUMBNAIL_UTIL_FILE;
644         thumb->media_type = type;
645         thumb->path = g_strdup(path);
646         thumb->width = width;
647         thumb->height = height;
648         thumb->thumbnail_path = g_strdup(thumbnail_path);
649
650         if (thumb->path == NULL || thumb->thumbnail_path == NULL) {
651                 __thumbnail_util_destroy_thumb_data(thumb);
652                 return THUMBNAIL_UTIL_ERROR_OUT_OF_MEMORY;
653         }
654
655         ret = __thumbnail_util_extract(thumb);
656         if (ret != THUMBNAIL_UTIL_ERROR_NONE)
657                 thumbnail_util_error("Extract failed");
658
659         __thumbnail_util_destroy_thumb_data(thumb);
660
661         return ret;
662 }
663