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