Remove Ecore evas dependency
[platform/core/multimedia/libmedia-thumbnail.git] / src / util / media-thumb-util.c
1 /*
2  * libmedia-thumbnail
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hyunjun Ko <zzoon.ko@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include "media-thumb-util.h"
23 #include "media-thumb-internal.h"
24
25 #include <glib.h>
26 #include <aul.h>
27 #include <string.h>
28 #include <drm_client.h>
29 #include <sys/stat.h>
30 #include <grp.h>
31 #include <pwd.h>
32 #include <sys/smack.h>
33
34 #define GLOBAL_USER     0 //#define     tzplatform_getenv(TZ_GLOBAL) //TODO
35
36 int _media_thumb_get_width(media_thumb_type thumb_type)
37 {
38         if (thumb_type == MEDIA_THUMB_LARGE) {
39                 return THUMB_LARGE_WIDTH;
40         } else if (thumb_type == MEDIA_THUMB_SMALL) {
41                 return  THUMB_SMALL_WIDTH;
42         } else {
43                 return -1;
44         }
45 }
46
47 int _media_thumb_get_height(media_thumb_type thumb_type)
48 {
49         if (thumb_type == MEDIA_THUMB_LARGE) {
50                 return THUMB_LARGE_HEIGHT;
51         } else if (thumb_type == MEDIA_THUMB_SMALL) {
52                 return  THUMB_SMALL_HEIGHT;
53         } else {
54                 return -1;
55         }
56 }
57
58 int _media_thumb_get_file_ext(const char *file_path, char *file_ext, int max_len)
59 {
60         int i = 0;
61
62         for (i = strlen(file_path); i >= 0; i--) {
63                 if ((file_path[i] == '.') && (i < strlen(file_path))) {
64                         strncpy(file_ext, &file_path[i + 1], max_len);
65                         return 0;
66                 }
67
68                 /* meet the dir. no ext */
69                 if (file_path[i] == '/') {
70                         return -1;
71                 }
72         }
73
74         return -1;
75 }
76
77 int
78 _media_thumb_get_file_type(const char *file_full_path)
79 {
80         int ret = 0;
81         drm_bool_type_e drm_type;
82         drm_file_type_e drm_file_type;
83         char mimetype[255];
84
85         if (file_full_path == NULL)
86                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
87
88         ret = drm_is_drm_file(file_full_path, &drm_type);
89         if (ret < 0) {
90                 thumb_err("drm_is_drm_file falied : %d", ret);
91                 drm_type = DRM_FALSE;
92         }
93
94         if (drm_type == DRM_TRUE) {
95                 thumb_dbg("DRM file : %s", file_full_path);
96
97                 ret = drm_get_file_type(file_full_path, &drm_file_type);
98                 if (ret < 0) {
99                         thumb_err("drm_get_file_type falied : %d", ret);
100                         return THUMB_NONE_TYPE;
101                 }
102
103                 if (drm_file_type == DRM_TYPE_UNDEFINED) {
104                         return THUMB_NONE_TYPE;
105                 } else {
106                         drm_content_info_s contentInfo;
107                         memset(&contentInfo, 0x00, sizeof(drm_content_info_s));
108
109                         ret = drm_get_content_info(file_full_path, &contentInfo);
110                         if (ret != DRM_RETURN_SUCCESS) {
111                                 thumb_err("drm_get_content_info() fails. : %d", ret);
112                                 return THUMB_NONE_TYPE;
113                         }
114                         thumb_dbg("DRM mime type: %s", contentInfo.mime_type);
115
116                         strncpy(mimetype, contentInfo.mime_type, sizeof(mimetype) - 1);
117                         mimetype[sizeof(mimetype) - 1] = '\0';
118                 }
119         } else {
120                 /* get content type and mime type from file. */
121                 ret =
122                         aul_get_mime_from_file(file_full_path, mimetype, sizeof(mimetype));
123                 if (ret < 0) {
124                         thumb_warn
125                                 ("aul_get_mime_from_file fail.. Now trying to get type by extension");
126         
127                         char ext[255] = { 0 };
128                         int ret = _media_thumb_get_file_ext(file_full_path, ext, sizeof(ext));
129                         if (ret < 0) {
130                                 thumb_err("_media_thumb_get_file_ext failed");
131                                 return THUMB_NONE_TYPE;
132                         }
133         
134                         if (strcasecmp(ext, "JPG") == 0 ||
135                                 strcasecmp(ext, "JPEG") == 0 ||
136                                 strcasecmp(ext, "PNG") == 0 ||
137                                 strcasecmp(ext, "GIF") == 0 ||
138                                 strcasecmp(ext, "AGIF") == 0 ||
139                                 strcasecmp(ext, "XWD") == 0 ||
140                                 strcasecmp(ext, "BMP") == 0 ||
141                                 strcasecmp(ext, "WBMP") == 0) {
142                                 return THUMB_IMAGE_TYPE;
143                         } else if (strcasecmp(ext, "AVI") == 0 ||
144                                 strcasecmp(ext, "MPEG") == 0 ||
145                                 strcasecmp(ext, "MP4") == 0 ||
146                                 strcasecmp(ext, "DCF") == 0 ||
147                                 strcasecmp(ext, "WMV") == 0 ||
148                                 strcasecmp(ext, "3GPP") == 0 ||
149                                 strcasecmp(ext, "3GP") == 0) {
150                                 return THUMB_VIDEO_TYPE;
151                         } else {
152                                 return THUMB_NONE_TYPE;
153                         }
154                 }
155         }
156
157         thumb_dbg("mime type : %s", mimetype);
158
159         /* categorize from mimetype */
160         if (strstr(mimetype, "image") != NULL) {
161                 return THUMB_IMAGE_TYPE;
162         } else if (strstr(mimetype, "video") != NULL) {
163                 return THUMB_VIDEO_TYPE;
164         }
165
166         return THUMB_NONE_TYPE;
167 }
168
169 int _media_thumb_get_store_type_by_path(const char *full_path)
170 {
171         if (full_path != NULL) {
172                 if (strncmp
173                     (full_path, THUMB_PATH_PHONE,
174                      strlen(THUMB_PATH_PHONE)) == 0) {
175                         return THUMB_PHONE;
176                 } else
177                     if (strncmp
178                         (full_path, THUMB_PATH_MMC,
179                          strlen(THUMB_PATH_MMC)) == 0) {
180                         return THUMB_MMC;
181                 }
182         }
183
184         return -1;
185 }
186
187 int _media_thumb_remove_file(const char *path)
188 {
189         int result = -1;
190
191         result = remove(path);
192         if (result == 0) {
193                 thumb_dbg("success to remove file");
194                 return TRUE;
195         } else {
196                 thumb_err("fail to remove file[%s] result errno = %s", path, strerror(errno));
197                 return FALSE;
198         }
199 }
200
201 static int _mkdir(const char *dir, mode_t mode) {
202         char tmp[256];
203         char *p = NULL;
204         size_t len;
205
206         snprintf(tmp, sizeof(tmp),"%s",dir);
207         len = strlen(tmp);
208         if(tmp[len - 1] == '/')
209                 tmp[len - 1] = 0;
210         for(p = tmp + 1; *p; p++)
211                 if(*p == '/') {
212                         *p = 0;
213                         mkdir(tmp, mode);
214                         *p = '/';
215                 }
216         return mkdir(tmp, mode);
217 }
218
219 static char* _media_thumb_mmc_get_path(uid_t uid)
220 {
221         char *result_psswd = NULL;
222         struct group *grpinfo = NULL;
223         if(uid == getuid())
224         {
225                 result_psswd = strdup(THUMB_MMC_PATH);
226                 grpinfo = getgrnam("users");
227                 if(grpinfo == NULL) {
228                         thumb_err("getgrnam(users) returns NULL !");
229                         return NULL;
230                 }
231         }
232         else
233         {
234                 struct passwd *userinfo = getpwuid(uid);
235                 if(userinfo == NULL) {
236                         thumb_err("getpwuid(%d) returns NULL !", uid);
237                         return NULL;
238                 }
239                 grpinfo = getgrnam("users");
240                 if(grpinfo == NULL) {
241                         thumb_err("getgrnam(users) returns NULL !");
242                         return NULL;
243                 }
244                 // Compare git_t type and not group name
245                 if (grpinfo->gr_gid != userinfo->pw_gid) {
246                         thumb_err("UID [%d] does not belong to 'users' group!", uid);
247                         return NULL;
248                 }
249                 asprintf(&result_psswd, "%s/data/file-manager-service/.thumb/mmc", userinfo->pw_dir);
250         }
251         
252         _mkdir(result_psswd,S_IRWXU | S_IRWXG | S_IRWXO);
253
254         return result_psswd;
255 }
256
257 static char* _media_thumb_phone_get_path(uid_t uid)
258 {
259         char *result_psswd = NULL;
260         struct group *grpinfo = NULL;
261         if(uid == getuid())
262         {
263                 result_psswd = strdup(THUMB_PHONE_PATH);
264                 grpinfo = getgrnam("users");
265                 if(grpinfo == NULL) {
266                         thumb_err("getgrnam(users) returns NULL !");
267                         return NULL;
268                 }
269         }
270         else
271         {
272                 struct passwd *userinfo = getpwuid(uid);
273                 if(userinfo == NULL) {
274                         thumb_err("getpwuid(%d) returns NULL !", uid);
275                         return NULL;
276                 }
277                 grpinfo = getgrnam("users");
278                 if(grpinfo == NULL) {
279                         thumb_err("getgrnam(users) returns NULL !");
280                         return NULL;
281                 }
282                 // Compare git_t type and not group name
283                 if (grpinfo->gr_gid != userinfo->pw_gid) {
284                         thumb_err("UID [%d] does not belong to 'users' group!", uid);
285                         return NULL;
286                 }
287                 asprintf(&result_psswd, "%s/data/file-manager-service/.thumb/phone", userinfo->pw_dir);
288         }
289
290         _mkdir(result_psswd,S_IRWXU | S_IRWXG | S_IRWXO);
291
292         return result_psswd;
293 }
294
295 int
296 _media_thumb_get_hash_name(const char *file_full_path,
297                                  char *thumb_hash_path, size_t max_thumb_path, uid_t uid)
298 {
299         char *hash_name;
300         char *thumb_dir = NULL;
301         char file_ext[255] = { 0 };
302         media_thumb_store_type store_type = -1;
303
304         if (file_full_path == NULL || thumb_hash_path == NULL
305             || max_thumb_path <= 0) {
306                 thumb_err
307                     ("file_full_path==NULL || thumb_hash_path == NULL || max_thumb_path <= 0");
308                 return -1;
309         }
310
311         _media_thumb_get_file_ext(file_full_path, file_ext, sizeof(file_ext));
312
313         store_type = _media_thumb_get_store_type_by_path(file_full_path);
314         if (store_type == THUMB_PHONE) {
315                 thumb_dir = _media_thumb_phone_get_path(uid);
316         } else if (store_type == THUMB_MMC) {
317                 thumb_dir = _media_thumb_mmc_get_path(uid);
318         } else {
319                 thumb_dir = _media_thumb_phone_get_path(uid);
320         }
321
322         hash_name = _media_thumb_generate_hash_name(file_full_path);
323
324         int ret_len;
325         ret_len =
326             snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg",
327                      thumb_dir, file_ext, hash_name);
328         if (ret_len < 0) {
329                 thumb_err("Error when snprintf");
330                 return -1;
331         } else if (ret_len > max_thumb_path) {
332                 thumb_err("Error for the length of thumb pathname");
333                 return -1;
334         }
335
336         //thumb_dbg("thumb hash : %s", thumb_hash_path);
337
338         return 0;
339 }
340
341 int _media_thumb_save_to_file_with_gdk(GdkPixbuf *data, 
342                                                                                         int w,
343                                                                                         int h,
344                                                                                         gboolean alpha,
345                                                                                         char *thumb_path)
346 {       
347         GError *error = NULL;
348         
349         gdk_pixbuf_save(data,thumb_path,"jpeg", &error, NULL);
350         if (error) {
351                 thumb_dbg ("Error saving image file %s", thumb_path);
352                 g_error_free (error);
353                 return -1;
354         }
355
356         if(smack_setlabel(thumb_path, "User", SMACK_LABEL_ACCESS)){
357                 thumb_dbg("failed chsmack -a \"User\" %s", thumb_path);
358                 return -1;
359         } else {
360                 thumb_dbg("chsmack -a \"User\" %s", thumb_path);
361         }
362
363         return 0;
364 }
365
366 int _thumbnail_get_data(const char *origin_path, 
367                                                 media_thumb_type thumb_type, 
368                                                 media_thumb_format format, 
369                                                 unsigned char **data,
370                                                 int *size,
371                                                 int *width,
372                                                 int *height,
373                                                 int *origin_width,
374                                                 int *origin_height,
375                                                 int *alpha,
376                                                 uid_t uid)
377 {
378         int err = -1;
379         int thumb_width = -1;
380         int thumb_height = -1;
381
382         if (origin_path == NULL || size == NULL 
383                         || width == NULL || height == NULL) {
384                 thumb_err("Invalid parameter");
385                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
386         }
387
388         if (format < MEDIA_THUMB_BGRA || format > MEDIA_THUMB_RGB888) {
389                 thumb_err("parameter format is invalid");
390                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
391         }
392
393         if (!g_file_test
394             (origin_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
395                         thumb_err("Original path (%s) does not exist", origin_path);
396                         return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
397         }
398
399         thumb_width = _media_thumb_get_width(thumb_type);
400         if (thumb_width < 0) {
401                 thumb_err("media_thumb_type is invalid");
402                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
403         }
404
405         thumb_height = _media_thumb_get_height(thumb_type);
406         if (thumb_height < 0) {
407                 thumb_err("media_thumb_type is invalid");
408                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
409         }
410
411         thumb_dbg("Origin path : %s", origin_path);
412
413         int file_type = THUMB_NONE_TYPE;
414         media_thumb_info thumb_info = {0,};
415         file_type = _media_thumb_get_file_type(origin_path);
416
417         if (file_type == THUMB_IMAGE_TYPE) {
418                 err = _media_thumb_image(origin_path, thumb_width, thumb_height, format, &thumb_info, uid);
419                 if (err < 0) {
420                         thumb_err("_media_thumb_image failed");
421                         return err;
422                 }
423
424         } else if (file_type == THUMB_VIDEO_TYPE) {
425                 err = _media_thumb_video(origin_path, thumb_width, thumb_height, format, &thumb_info,uid);
426                 if (err < 0) {
427                         thumb_err("_media_thumb_image failed");
428                         return err;
429                 }
430         }
431
432         if (size) *size = thumb_info.size;
433         if (width) *width = thumb_info.width;
434         if (height) *height = thumb_info.height;
435         *data = thumb_info.data;
436         if (origin_width) *origin_width = thumb_info.origin_width;
437         if (origin_height) *origin_height = thumb_info.origin_height;
438         if (alpha) *alpha = thumb_info.alpha;
439
440         thumb_dbg("Thumb data is generated successfully (Size:%d, W:%d, H:%d) 0x%x",
441                                 *size, *width, *height, *data);
442
443         return MEDIA_THUMB_ERROR_NONE;
444 }