Fix wrong enum init value
[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
28 #define MAX_SIZE 16
29 #define MAX_PATH_SIZE 4096
30
31 static int __thumbnail_util_replace_path(const char *path, char *replace_path)
32 {
33         if (!STRING_VALID(path)) {
34                 thumbnail_util_error("Invalid path");
35                 return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
36         }
37
38         if (strncmp(path, MEDIA_ROOT_PATH_INTERNAL_OLD, strlen(MEDIA_ROOT_PATH_INTERNAL_OLD)) == 0) {
39                 thumbnail_util_sec_debug("Old path[%s]", path);
40                 snprintf(replace_path, MAX_PATH_SIZE, "%s%s", tzplatform_getenv(TZ_USER_CONTENT), path + strlen(MEDIA_ROOT_PATH_INTERNAL_OLD));
41         } else {
42                 snprintf(replace_path, MAX_PATH_SIZE, "%s", path);
43         }
44
45         if (!STRING_VALID(replace_path)) {
46                 thumbnail_util_error("replace failed");
47                 return THUMBNAIL_UTIL_ERROR_INVALID_OPERATION;
48         }
49
50         return THUMBNAIL_UTIL_ERROR_NONE;
51 }
52
53 static int __thumbnail_util_error_capi(int internal_error)
54 {
55         switch (internal_error) {
56         case MS_MEDIA_ERR_NONE:
57                 return THUMBNAIL_UTIL_ERROR_NONE;
58         case MS_MEDIA_ERR_INVALID_PARAMETER:
59                 return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
60         case MS_MEDIA_ERR_OUT_OF_MEMORY:
61                 return THUMBNAIL_UTIL_ERROR_OUT_OF_MEMORY;
62         case MS_MEDIA_ERR_PERMISSION_DENIED:
63                 return THUMBNAIL_UTIL_ERROR_PERMISSION_DENIED;
64         case MS_MEDIA_ERR_THUMB_TOO_BIG:
65         case MS_MEDIA_ERR_THUMB_UNSUPPORTED:
66                 return THUMBNAIL_UTIL_ERROR_UNSUPPORTED_CONTENT;
67         default:
68                 return THUMBNAIL_UTIL_ERROR_INVALID_OPERATION;
69         }
70 }
71
72 static void __thumbnail_util_convert_itoa(int request_id, char **req_str)
73 {
74         char buf[MAX_SIZE] = {0, };
75
76         snprintf(buf, MAX_SIZE, "%d", request_id);
77         *req_str = strndup(buf, strlen(buf));
78 }
79 static 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)
80 {
81         thumbnail_extract_cb_s *_thumb_cb = (thumbnail_extract_cb_s *)user_data;
82         char *request_id_str = NULL;
83
84         if (_thumb_cb != NULL) {
85                 __thumbnail_util_convert_itoa(request_id, &request_id_str);
86                 if (_thumb_cb->thumb_extract_cb)
87                         _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);
88                 SAFE_FREE(request_id_str);
89         }
90         SAFE_FREE(_thumb_cb);
91 }
92
93 int thumbnail_util_create(thumbnail_h *thumb)
94 {
95         int ret = THUMBNAIL_UTIL_ERROR_NONE;
96         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_create() is deprecated and will be removed from next release.");
97
98         if (thumb == NULL) {
99                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
100                 return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
101         }
102
103         thumbnail_s *_thumb = (thumbnail_s *)malloc(sizeof(thumbnail_s));
104         if (_thumb == NULL) {
105                 thumbnail_util_error("OUT_OF_MEMORY(0x%08x)", THUMBNAIL_UTIL_ERROR_OUT_OF_MEMORY);
106                 return THUMBNAIL_UTIL_ERROR_OUT_OF_MEMORY;
107         }
108
109         _thumb->request_id = 0;
110         _thumb->file_path = NULL;
111         _thumb->dst_width = CONTENT_THUMB_DEFAULT_WIDTH;
112         _thumb->dst_height = CONTENT_THUMB_DEFAULT_HEIGHT;
113
114         *thumb = (thumbnail_h)_thumb;
115
116         return ret;
117 }
118
119 int thumbnail_util_extract(thumbnail_h thumb, thumbnail_extracted_cb callback, void *user_data, char **request_id)
120 {
121         int ret = THUMBNAIL_UTIL_ERROR_NONE;
122         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.");
123         int res = 0;
124         static int g_thumbnail_req_id = 0;
125         thumbnail_s *_thumb = (thumbnail_s *)thumb;
126
127         if (_thumb != NULL && STRING_VALID(_thumb->file_path)) {
128                 g_thumbnail_req_id++;
129                 _thumb->request_id = g_thumbnail_req_id;
130                 __thumbnail_util_convert_itoa(_thumb->request_id, request_id);
131                 thumbnail_extract_cb_s *_thumb_cb = (thumbnail_extract_cb_s *)calloc(1, sizeof(thumbnail_extract_cb_s));
132
133                 if (_thumb_cb != NULL) {
134                         _thumb_cb->user_data = user_data;
135                         _thumb_cb->thumb_extract_cb = callback;
136                 }
137
138                 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));
139                 ret = __thumbnail_util_error_capi(res);
140                 if (ret != THUMBNAIL_UTIL_ERROR_NONE)
141                         free(_thumb_cb);
142         } else {
143                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
144                 ret = THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
145         }
146
147         return ret;
148 }
149
150 int thumbnail_util_set_path(thumbnail_h thumb, const char *path)
151 {
152         int ret = THUMBNAIL_UTIL_ERROR_NONE;
153         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_set_path() is deprecated and will be removed from next release.");
154         char repl_path[MAX_PATH_SIZE + 1] = {0, };
155         thumbnail_s *_thumb = (thumbnail_s *)thumb;
156
157         if (_thumb != NULL && path != NULL) {
158                 SAFE_FREE(_thumb->file_path);
159                 memset(repl_path, 0, sizeof(repl_path));
160                 ret = __thumbnail_util_replace_path(path, repl_path);
161                 if (ret != THUMBNAIL_UTIL_ERROR_NONE) {
162                         thumbnail_util_error("Convert path failed");
163                         _thumb->file_path = NULL;
164                 } else {
165                         _thumb->file_path = strndup(repl_path, strlen(repl_path));
166                 }
167         } else {
168                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
169                 ret = THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
170         }
171
172         return ret;
173 }
174
175 int thumbnail_util_set_size(thumbnail_h thumb, int width, int height)
176 {
177         int ret = THUMBNAIL_UTIL_ERROR_NONE;
178         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_set_size() is deprecated and will be removed from next release.");
179         thumbnail_s *_thumb = (thumbnail_s *)thumb;
180
181         if (_thumb != NULL && width > 0 && height > 0) {
182                 _thumb->dst_width = width;
183                 _thumb->dst_height = height;
184         } else {
185                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
186                 ret = THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
187         }
188
189         return ret;
190 }
191
192 int thumbnail_util_cancel(thumbnail_h thumb, const char *request_id)
193 {
194         int ret = THUMBNAIL_UTIL_ERROR_NONE;
195         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_cancel() is deprecated and will be removed from next release.");
196         thumbnail_s *_thumb = (thumbnail_s *)thumb;
197
198         if (_thumb != NULL && STRING_VALID(request_id)) {
199                 unsigned int request_id_integer = atoi(request_id);
200                 ret = thumbnail_request_cancel_raw_data(request_id_integer);
201         } else {
202                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
203                 ret = THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
204         }
205
206         return ret;
207 }
208
209 int thumbnail_util_destroy(thumbnail_h thumb)
210 {
211         thumbnail_util_warn("DEPRECATION WARNING: thumbnail_util_destroy() is deprecated and will be removed from next release.");
212         int ret = THUMBNAIL_UTIL_ERROR_NONE;
213         thumbnail_s *_thumb = (thumbnail_s *)thumb;
214
215         if (_thumb) {
216                 SAFE_FREE(_thumb->file_path);
217                 SAFE_FREE(_thumb);
218         } else {
219                 thumbnail_util_error("INVALID_PARAMETER(0x%08x)", THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
220                 ret = THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
221         }
222
223         return ret;
224 }
225
226 static int __thumbnail_util_get_file_ext(const char *file_path, char *file_ext, int max_len)
227 {
228         int i = 0;
229
230         for (i = (int)strlen(file_path); i >= 0; i--) {
231                 if ((file_path[i] == '.') && (i < (int)strlen(file_path))) {
232                         g_strlcpy(file_ext, &file_path[i + 1], max_len);
233                         return THUMBNAIL_UTIL_ERROR_NONE;
234                 }
235
236                 /* meet the dir. no ext */
237                 if (file_path[i] == '/')
238                         return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
239         }
240
241         return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
242 }
243
244 static int __thumbnail_util_check_media_type(const char *path, thumbnail_util_media_type_e *type)
245 {
246         int ret = THUMBNAIL_UTIL_ERROR_NONE;
247         char mimetype[255] = {0,};
248         const char *unsupported_type = "image/tiff";
249         const char *supported_type = "application/vnd.ms-asf";
250
251         // Check file is existed
252         thumbnail_util_retv_if(path == NULL, THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER);
253         if (access(path, R_OK) < 0) {
254                 if (errno == EACCES || errno == EPERM) {
255                         thumbnail_util_error("Fail to open path: Permission Denied [%s]", path);
256                         return  THUMBNAIL_UTIL_ERROR_PERMISSION_DENIED;
257                 } else {
258                         thumbnail_util_error("Fail to open path: Invalid Path [%s]", path);
259                         return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
260                 }
261         }
262
263         // Check media type
264         ret = aul_get_mime_from_file(path, mimetype, sizeof(mimetype));
265         thumbnail_util_retvm_if(ret < 0, THUMBNAIL_UTIL_ERROR_INVALID_OPERATION, "aul_get_mime_from_file failed");
266
267         thumbnail_util_debug("mime type : %s", mimetype);
268
269         /* categorize from mimetype */
270         if (strstr(mimetype, "image") != NULL) {
271                 thumbnail_util_retvm_if(!strcmp(mimetype, unsupported_type), THUMBNAIL_UTIL_ERROR_UNSUPPORTED_CONTENT, "This is unsupport file type");
272                 *type = THUMBNAIL_UTIL_IMAGE;
273                 return THUMBNAIL_UTIL_ERROR_NONE;
274         } else if (strstr(mimetype, "video") != NULL) {
275                 *type = THUMBNAIL_UTIL_VIDEO;
276                 return THUMBNAIL_UTIL_ERROR_NONE;
277         } else if (strstr(mimetype, supported_type) != NULL) {
278                 *type = THUMBNAIL_UTIL_VIDEO;
279                 return THUMBNAIL_UTIL_ERROR_NONE;
280         }
281
282         return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
283 }
284
285 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)
286 {
287         int ret = THUMBNAIL_UTIL_ERROR_NONE;
288         thumbnail_util_media_type_e type = -1;
289
290         /* check media type */
291         ret = __thumbnail_util_check_media_type(path, &type);
292         thumbnail_util_retvm_if(ret != THUMBNAIL_UTIL_ERROR_NONE, ret, "__thumbnail_util_check_media_type failed");
293
294         /* If image, check support format */
295         if (type == THUMBNAIL_UTIL_IMAGE)
296                 ret = create_image_thumbnail_to_buffer(path, width, height, thumb_buffer, thumb_size, thumb_width, thumb_height);
297         else
298                 ret = create_video_thumbnail_to_buffer(path, width, height, thumb_buffer, thumb_size, thumb_width, thumb_height, false);
299
300         return __thumbnail_util_error_capi(ret);
301 }
302
303 int thumbnail_util_extract_to_file(const char *path, unsigned int width, unsigned int height, const char *thumbnail_path)
304 {
305         int ret = THUMBNAIL_UTIL_ERROR_NONE;
306         thumbnail_util_media_type_e type;
307
308         /* check media type */
309         ret = __thumbnail_util_check_media_type(path, &type);
310         thumbnail_util_retvm_if(ret != THUMBNAIL_UTIL_ERROR_NONE, ret, "__thumbnail_util_check_media_type failed");
311
312         /* If image, check support format */
313         if (type == THUMBNAIL_UTIL_IMAGE) {
314                 ret = create_image_thumbnail_to_file(path, width, height, thumbnail_path);
315         } else {
316                 char ext[255] = { 0 };
317                 ret = __thumbnail_util_get_file_ext(thumbnail_path, ext, sizeof(ext));
318                 thumbnail_util_retvm_if(ret != THUMBNAIL_UTIL_ERROR_NONE, ret, "__thumbnail_util_get_file_ext failed");
319
320                 /* If video file, thumbnail extension is only JPEG */
321                 if (strcasecmp(ext, "JPG") != 0 && strcasecmp(ext, "JPEG") != 0) {
322                         thumbnail_util_error("Wrong file name[%s]", thumbnail_path);
323                         return THUMBNAIL_UTIL_ERROR_INVALID_PARAMETER;
324                 }
325
326                 ret = create_video_thumbnail_to_file(path, width, height, thumbnail_path, false);
327         }
328
329         return __thumbnail_util_error_capi(ret);
330 }