Update socket_info.
[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 #include "media-thumb-debug.h"
25
26 #include <glib.h>
27 #include <aul.h>
28 #include <string.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         char mimetype[255] = {0,};
82
83         if (file_full_path == NULL)
84                 return MS_MEDIA_ERR_INVALID_PARAMETER;
85
86         /* get content type and mime type from file. */
87         ret = aul_get_mime_from_file(file_full_path, mimetype, sizeof(mimetype));
88         if (ret < 0) {
89                 thumb_warn
90                         ("aul_get_mime_from_file fail.. Now trying to get type by extension");
91
92                 char ext[255] = { 0 };
93                 int ret = _media_thumb_get_file_ext(file_full_path, ext, sizeof(ext));
94                 if (ret < 0) {
95                         thumb_err("_media_thumb_get_file_ext failed");
96                         return THUMB_NONE_TYPE;
97                 }
98
99                 if (strcasecmp(ext, "JPG") == 0 ||
100                         strcasecmp(ext, "JPEG") == 0 ||
101                         strcasecmp(ext, "PNG") == 0 ||
102                         strcasecmp(ext, "GIF") == 0 ||
103                         strcasecmp(ext, "AGIF") == 0 ||
104                         strcasecmp(ext, "XWD") == 0 ||
105                         strcasecmp(ext, "BMP") == 0 ||
106                         strcasecmp(ext, "WBMP") == 0) {
107                         return THUMB_IMAGE_TYPE;
108                 } else if (strcasecmp(ext, "AVI") == 0 ||
109                         strcasecmp(ext, "MPEG") == 0 ||
110                         strcasecmp(ext, "MP4") == 0 ||
111                         strcasecmp(ext, "DCF") == 0 ||
112                         strcasecmp(ext, "WMV") == 0 ||
113                         strcasecmp(ext, "3GPP") == 0 ||
114                         strcasecmp(ext, "3GP") == 0) {
115                         return THUMB_VIDEO_TYPE;
116                 } else {
117                         return THUMB_NONE_TYPE;
118                 }
119         }
120
121         thumb_dbg("mime type : %s", mimetype);
122
123         /* categorize from mimetype */
124         if (strstr(mimetype, "image") != NULL) {
125                 return THUMB_IMAGE_TYPE;
126         } else if (strstr(mimetype, "video") != NULL) {
127                 return THUMB_VIDEO_TYPE;
128         }
129
130         return THUMB_NONE_TYPE;
131 }
132
133 int _media_thumb_get_store_type_by_path(const char *full_path)
134 {
135         if (full_path != NULL) {
136                 if (strncmp(full_path, THUMB_PATH_PHONE, strlen(THUMB_PATH_PHONE)) == 0) {
137                         return THUMB_PHONE;
138                 } else if (strncmp(full_path, THUMB_PATH_MMC, strlen(THUMB_PATH_MMC)) == 0) {
139                         return THUMB_MMC;
140                 }
141         }
142
143         return -1;
144 }
145
146 int _media_thumb_remove_file(const char *path)
147 {
148         int result = -1;
149
150         result = remove(path);
151         if (result == 0) {
152                 thumb_dbg("success to remove file");
153                 return TRUE;
154         } else {
155                 thumb_stderror("fail to remove file[%s] result");
156                 return FALSE;
157         }
158 }
159
160 static int _mkdir(const char *dir, mode_t mode) {
161         char tmp[256];
162         char *p = NULL;
163         size_t len;
164
165         snprintf(tmp, sizeof(tmp),"%s",dir);
166         len = strlen(tmp);
167         if(tmp[len - 1] == '/')
168                 tmp[len - 1] = 0;
169         for(p = tmp + 1; *p; p++)
170                 if(*p == '/') {
171                         *p = 0;
172                         mkdir(tmp, mode);
173                         *p = '/';
174                 }
175         return mkdir(tmp, mode);
176 }
177
178 static char* _media_thumb_mmc_get_path(uid_t uid)
179 {
180         char *result_psswd = NULL;
181         struct group *grpinfo = NULL;
182         if(uid == getuid())
183         {
184                 result_psswd = strdup(THUMB_MMC_PATH);
185                 grpinfo = getgrnam("users");
186                 if(grpinfo == NULL) {
187                         thumb_err("getgrnam(users) returns NULL !");
188                         return NULL;
189                 }
190         }
191         else
192         {
193                 struct passwd *userinfo = getpwuid(uid);
194                 if(userinfo == NULL) {
195                         thumb_err("getpwuid(%d) returns NULL !", uid);
196                         return NULL;
197                 }
198                 grpinfo = getgrnam("users");
199                 if(grpinfo == NULL) {
200                         thumb_err("getgrnam(users) returns NULL !");
201                         return NULL;
202                 }
203                 // Compare git_t type and not group name
204                 if (grpinfo->gr_gid != userinfo->pw_gid) {
205                         thumb_err("UID [%d] does not belong to 'users' group!", uid);
206                         return NULL;
207                 }
208                 asprintf(&result_psswd, "%s/data/file-manager-service/.thumb/mmc", userinfo->pw_dir);
209         }
210         
211         _mkdir(result_psswd,S_IRWXU | S_IRWXG | S_IRWXO);
212
213         return result_psswd;
214 }
215
216 static char* _media_thumb_phone_get_path(uid_t uid)
217 {
218         char *result_psswd = NULL;
219         struct group *grpinfo = NULL;
220         if(uid == getuid())
221         {
222                 result_psswd = strdup(THUMB_PHONE_PATH);
223                 grpinfo = getgrnam("users");
224                 if(grpinfo == NULL) {
225                         thumb_err("getgrnam(users) returns NULL !");
226                         return NULL;
227                 }
228         }
229         else
230         {
231                 struct passwd *userinfo = getpwuid(uid);
232                 if(userinfo == NULL) {
233                         thumb_err("getpwuid(%d) returns NULL !", uid);
234                         return NULL;
235                 }
236                 grpinfo = getgrnam("users");
237                 if(grpinfo == NULL) {
238                         thumb_err("getgrnam(users) returns NULL !");
239                         return NULL;
240                 }
241                 // Compare git_t type and not group name
242                 if (grpinfo->gr_gid != userinfo->pw_gid) {
243                         thumb_err("UID [%d] does not belong to 'users' group!", uid);
244                         return NULL;
245                 }
246                 asprintf(&result_psswd, "%s/data/file-manager-service/.thumb/phone", userinfo->pw_dir);
247         }
248
249         _mkdir(result_psswd,S_IRWXU | S_IRWXG | S_IRWXO);
250
251         return result_psswd;
252 }
253
254 int _media_thumb_get_hash_name(const char *file_full_path,
255                                  char *thumb_hash_path, size_t max_thumb_path, uid_t uid)
256 {
257         char *hash_name;
258         char *thumb_dir = NULL;
259         char file_ext[255] = { 0 };
260         media_thumb_store_type store_type = -1;
261
262         if (file_full_path == NULL || thumb_hash_path == NULL
263             || max_thumb_path <= 0) {
264                 thumb_err
265                     ("file_full_path==NULL || thumb_hash_path == NULL || max_thumb_path <= 0");
266                 return -1;
267         }
268
269         _media_thumb_get_file_ext(file_full_path, file_ext, sizeof(file_ext));
270
271         store_type = _media_thumb_get_store_type_by_path(file_full_path);
272         if (store_type == THUMB_PHONE) {
273                 thumb_dir = _media_thumb_phone_get_path(uid);
274         } else if (store_type == THUMB_MMC) {
275                 thumb_dir = _media_thumb_mmc_get_path(uid);
276         } else {
277                 thumb_dir = _media_thumb_phone_get_path(uid);
278         }
279
280         hash_name = _media_thumb_generate_hash_name(file_full_path);
281
282         int ret_len;
283         ret_len =
284             snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg",
285                      thumb_dir, file_ext, hash_name);
286         if (ret_len < 0) {
287                 thumb_err("Error when snprintf");
288                 return -1;
289         } else if (ret_len > max_thumb_path) {
290                 thumb_err("Error for the length of thumb pathname");
291                 return -1;
292         }
293
294         //thumb_dbg("thumb hash : %s", thumb_hash_path);
295
296         return 0;
297 }
298
299 int _media_thumb_save_to_file_with_gdk(GdkPixbuf *data, 
300                                                                                         int w,
301                                                                                         int h,
302                                                                                         gboolean alpha,
303                                                                                         char *thumb_path)
304 {       
305         GError *error = NULL;
306         
307         gdk_pixbuf_save(data,thumb_path,"jpeg", &error, NULL);
308         if (error) {
309                 thumb_dbg ("Error saving image file %s", thumb_path);
310                 g_error_free (error);
311                 return -1;
312         }
313
314         if(smack_setlabel(thumb_path, "User", SMACK_LABEL_ACCESS)){
315                 thumb_dbg("failed chsmack -a \"User\" %s", thumb_path);
316                 return -1;
317         } else {
318                 thumb_dbg("chsmack -a \"User\" %s", thumb_path);
319         }
320
321         return 0;
322 }
323
324 int _thumbnail_get_data(const char *origin_path, 
325                                                 media_thumb_type thumb_type, 
326                                                 media_thumb_format format, 
327                                                 unsigned char **data,
328                                                 int *size,
329                                                 int *width,
330                                                 int *height,
331                                                 int *origin_width,
332                                                 int *origin_height,
333                                                 int *alpha,
334                                                 uid_t uid)
335 {
336         int err = -1;
337         int thumb_width = -1;
338         int thumb_height = -1;
339
340         if (origin_path == NULL || size == NULL 
341                         || width == NULL || height == NULL) {
342                 thumb_err("Invalid parameter");
343                 return MS_MEDIA_ERR_INVALID_PARAMETER;
344         }
345
346         if (format < MEDIA_THUMB_BGRA || format > MEDIA_THUMB_RGB888) {
347                 thumb_err("parameter format is invalid");
348                 return MS_MEDIA_ERR_INVALID_PARAMETER;
349         }
350
351         if (!g_file_test
352             (origin_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
353                         thumb_err("Original path (%s) does not exist", origin_path);
354                         return MS_MEDIA_ERR_INVALID_PARAMETER;
355         }
356
357         thumb_width = _media_thumb_get_width(thumb_type);
358         if (thumb_width < 0) {
359                 thumb_err("media_thumb_type is invalid");
360                 return MS_MEDIA_ERR_INVALID_PARAMETER;
361         }
362
363         thumb_height = _media_thumb_get_height(thumb_type);
364         if (thumb_height < 0) {
365                 thumb_err("media_thumb_type is invalid");
366                 return MS_MEDIA_ERR_INVALID_PARAMETER;
367         }
368
369         thumb_dbg("Origin path : %s", origin_path);
370
371         int file_type = THUMB_NONE_TYPE;
372         media_thumb_info thumb_info = {0,};
373         file_type = _media_thumb_get_file_type(origin_path);
374
375         if (file_type == THUMB_IMAGE_TYPE) {
376                 err = _media_thumb_image(origin_path, thumb_width, thumb_height, format, &thumb_info, false, uid);
377                 if (err < 0) {
378                         thumb_err("_media_thumb_image failed");
379                         return err;
380                 }
381
382         } else if (file_type == THUMB_VIDEO_TYPE) {
383                 err = _media_thumb_video(origin_path, thumb_width, thumb_height, format, &thumb_info,uid);
384                 if (err < 0) {
385                         thumb_err("_media_thumb_image failed");
386                         return err;
387                 }
388         }
389
390         if (size) *size = thumb_info.size;
391         if (width) *width = thumb_info.width;
392         if (height) *height = thumb_info.height;
393         *data = thumb_info.gdkdata;
394         if (origin_width) *origin_width = thumb_info.origin_width;
395         if (origin_height) *origin_height = thumb_info.origin_height;
396         if (alpha) *alpha = thumb_info.alpha;
397
398         thumb_dbg("Thumb data is generated successfully (Size:%d, W:%d, H:%d) 0x%x",
399                                 *size, *width, *height, *data);
400
401         return MS_MEDIA_ERR_NONE;
402 }
403
404 int _thumbnail_get_raw_data(const char *origin_path,
405                                                 media_thumb_format format,
406                                                 unsigned char **data,
407                                                 int *size,
408                                                 int *width,
409                                                 int *height,
410                                                 uid_t uid)
411 {
412         int err = -1;
413         int thumb_width = -1;
414         int thumb_height = -1;
415
416         if (origin_path == NULL || * width <= 0 || *height <= 0) {
417                 thumb_err("Invalid parameter");
418                 return MS_MEDIA_ERR_INVALID_PARAMETER;
419         }
420
421         if (format < MEDIA_THUMB_BGRA || format > MEDIA_THUMB_RGB888) {
422                 thumb_err("parameter format is invalid");
423                 return MS_MEDIA_ERR_INVALID_PARAMETER;
424         }
425
426         if (!g_file_test
427             (origin_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
428                         thumb_err("Original path (%s) does not exist", origin_path);
429                         return MS_MEDIA_ERR_INVALID_PARAMETER;
430         }
431
432         thumb_dbg("Origin path : %s", origin_path);
433
434         int file_type = THUMB_NONE_TYPE;
435         media_thumb_info thumb_info = {0,};
436         file_type = _media_thumb_get_file_type(origin_path);
437         thumb_width = *width;
438         thumb_height = *height;
439
440         if (file_type == THUMB_IMAGE_TYPE) {
441                 err = _media_thumb_image(origin_path, thumb_width, thumb_height, format, &thumb_info, true, uid);
442                 if (err < 0) {
443                         thumb_err("_media_thumb_image failed");
444                         return err;
445                 }
446
447         } else if (file_type == THUMB_VIDEO_TYPE) {
448                 err = _media_thumb_video(origin_path, thumb_width, thumb_height, format, &thumb_info,uid);
449                 if (err < 0) {
450                         thumb_err("_media_thumb_image failed");
451                         return err;
452                 }
453         }
454
455         if (size) *size = thumb_info.size;
456         if (width) *width = thumb_info.width;
457         if (height) *height = thumb_info.height;
458         *data = thumb_info.gdkdata;
459
460         thumb_dbg("Thumb data is generated successfully (Size:%d, W:%d, H:%d) 0x%x",
461                                 *size, *width, *height, *data);
462
463         return MS_MEDIA_ERR_NONE;
464 }