3f287bdd22a733e63fcaac84f435f780bad2c20f
[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
30 #include <Evas.h>
31 #include <Ecore_Evas.h>
32 #include <grp.h>
33 #include <pwd.h>
34
35 #define GLOBAL_USER     0 //#define     tzplatform_getenv(TZ_GLOBAL) //TODO
36
37 int _media_thumb_get_width(media_thumb_type thumb_type)
38 {
39         if (thumb_type == MEDIA_THUMB_LARGE) {
40                 return THUMB_LARGE_WIDTH;
41         } else if (thumb_type == MEDIA_THUMB_SMALL) {
42                 return  THUMB_SMALL_WIDTH;
43         } else {
44                 return -1;
45         }
46 }
47
48 int _media_thumb_get_height(media_thumb_type thumb_type)
49 {
50         if (thumb_type == MEDIA_THUMB_LARGE) {
51                 return THUMB_LARGE_HEIGHT;
52         } else if (thumb_type == MEDIA_THUMB_SMALL) {
53                 return  THUMB_SMALL_HEIGHT;
54         } else {
55                 return -1;
56         }
57 }
58
59 int _media_thumb_get_file_ext(const char *file_path, char *file_ext, int max_len)
60 {
61         int i = 0;
62
63         for (i = strlen(file_path); i >= 0; i--) {
64                 if ((file_path[i] == '.') && (i < strlen(file_path))) {
65                         strncpy(file_ext, &file_path[i + 1], max_len);
66                         return 0;
67                 }
68
69                 /* meet the dir. no ext */
70                 if (file_path[i] == '/') {
71                         return -1;
72                 }
73         }
74
75         return -1;
76 }
77
78 int
79 _media_thumb_get_file_type(const char *file_full_path)
80 {
81         int ret = 0;
82         drm_bool_type_e drm_type;
83         drm_file_type_e drm_file_type;
84         char mimetype[255];
85
86         if (file_full_path == NULL)
87                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
88
89         ret = drm_is_drm_file(file_full_path, &drm_type);
90         if (ret < 0) {
91                 thumb_err("drm_is_drm_file falied : %d", ret);
92                 drm_type = DRM_FALSE;
93         }
94
95         if (drm_type == DRM_TRUE) {
96                 thumb_dbg("DRM file : %s", file_full_path);
97
98                 ret = drm_get_file_type(file_full_path, &drm_file_type);
99                 if (ret < 0) {
100                         thumb_err("drm_get_file_type falied : %d", ret);
101                         return THUMB_NONE_TYPE;
102                 }
103
104                 if (drm_file_type == DRM_TYPE_UNDEFINED) {
105                         return THUMB_NONE_TYPE;
106                 } else {
107                         drm_content_info_s contentInfo;
108                         memset(&contentInfo, 0x00, sizeof(drm_content_info_s));
109
110                         ret = drm_get_content_info(file_full_path, &contentInfo);
111                         if (ret != DRM_RETURN_SUCCESS) {
112                                 thumb_err("drm_get_content_info() fails. : %d", ret);
113                                 return THUMB_NONE_TYPE;
114                         }
115                         thumb_dbg("DRM mime type: %s", contentInfo.mime_type);
116
117                         strncpy(mimetype, contentInfo.mime_type, sizeof(mimetype) - 1);
118                         mimetype[sizeof(mimetype) - 1] = '\0';
119                 }
120         } else {
121                 /* get content type and mime type from file. */
122                 ret =
123                         aul_get_mime_from_file(file_full_path, mimetype, sizeof(mimetype));
124                 if (ret < 0) {
125                         thumb_warn
126                                 ("aul_get_mime_from_file fail.. Now trying to get type by extension");
127         
128                         char ext[255] = { 0 };
129                         int ret = _media_thumb_get_file_ext(file_full_path, ext, sizeof(ext));
130                         if (ret < 0) {
131                                 thumb_err("_media_thumb_get_file_ext failed");
132                                 return THUMB_NONE_TYPE;
133                         }
134         
135                         if (strcasecmp(ext, "JPG") == 0 ||
136                                 strcasecmp(ext, "JPEG") == 0 ||
137                                 strcasecmp(ext, "PNG") == 0 ||
138                                 strcasecmp(ext, "GIF") == 0 ||
139                                 strcasecmp(ext, "AGIF") == 0 ||
140                                 strcasecmp(ext, "XWD") == 0 ||
141                                 strcasecmp(ext, "BMP") == 0 ||
142                                 strcasecmp(ext, "WBMP") == 0) {
143                                 return THUMB_IMAGE_TYPE;
144                         } else if (strcasecmp(ext, "AVI") == 0 ||
145                                 strcasecmp(ext, "MPEG") == 0 ||
146                                 strcasecmp(ext, "MP4") == 0 ||
147                                 strcasecmp(ext, "DCF") == 0 ||
148                                 strcasecmp(ext, "WMV") == 0 ||
149                                 strcasecmp(ext, "3GPP") == 0 ||
150                                 strcasecmp(ext, "3GP") == 0) {
151                                 return THUMB_VIDEO_TYPE;
152                         } else {
153                                 return THUMB_NONE_TYPE;
154                         }
155                 }
156         }
157
158         thumb_dbg("mime type : %s", mimetype);
159
160         /* categorize from mimetype */
161         if (strstr(mimetype, "image") != NULL) {
162                 return THUMB_IMAGE_TYPE;
163         } else if (strstr(mimetype, "video") != NULL) {
164                 return THUMB_VIDEO_TYPE;
165         }
166
167         return THUMB_NONE_TYPE;
168 }
169
170 int _media_thumb_get_store_type_by_path(const char *full_path)
171 {
172         if (full_path != NULL) {
173                 if (strncmp
174                     (full_path, THUMB_PATH_PHONE,
175                      strlen(THUMB_PATH_PHONE)) == 0) {
176                         return THUMB_PHONE;
177                 } else
178                     if (strncmp
179                         (full_path, THUMB_PATH_MMC,
180                          strlen(THUMB_PATH_MMC)) == 0) {
181                         return THUMB_MMC;
182                 }
183         }
184
185         return -1;
186 }
187
188 int _media_thumb_remove_file(const char *path)
189 {
190         int result = -1;
191
192         result = remove(path);
193         if (result == 0) {
194                 thumb_dbg("success to remove file");
195                 return TRUE;
196         } else {
197                 thumb_err("fail to remove file[%s] result errno = %s", path, strerror(errno));
198                 return FALSE;
199         }
200 }
201
202 static int _mkdir(const char *dir, mode_t mode) {
203         char tmp[256];
204         char *p = NULL;
205         size_t len;
206
207         snprintf(tmp, sizeof(tmp),"%s",dir);
208         len = strlen(tmp);
209         if(tmp[len - 1] == '/')
210                 tmp[len - 1] = 0;
211         for(p = tmp + 1; *p; p++)
212                 if(*p == '/') {
213                         *p = 0;
214                         mkdir(tmp, mode);
215                         *p = '/';
216                 }
217         return mkdir(tmp, mode);
218 }
219
220 static char* _media_thumb_mmc_get_path(uid_t uid)
221 {
222         char *result_psswd = NULL;
223         struct group *grpinfo = NULL;
224         if(uid == getuid())
225         {
226                 result_psswd = strdup(THUMB_MMC_PATH);
227                 grpinfo = getgrnam("users");
228                 if(grpinfo == NULL) {
229                         thumb_err("getgrnam(users) returns NULL !");
230                         return NULL;
231                 }
232         }
233         else
234         {
235                 struct passwd *userinfo = getpwuid(uid);
236                 if(userinfo == NULL) {
237                         thumb_err("getpwuid(%d) returns NULL !", uid);
238                         return NULL;
239                 }
240                 grpinfo = getgrnam("users");
241                 if(grpinfo == NULL) {
242                         thumb_err("getgrnam(users) returns NULL !");
243                         return NULL;
244                 }
245                 // Compare git_t type and not group name
246                 if (grpinfo->gr_gid != userinfo->pw_gid) {
247                         thumb_err("UID [%d] does not belong to 'users' group!", uid);
248                         return NULL;
249                 }
250                 asprintf(&result_psswd, "%s/data/file-manager-service/.thumb/mmc", userinfo->pw_dir);
251         }
252         
253         _mkdir(result_psswd,S_IRWXU | S_IRWXG | S_IRWXO);
254
255         return result_psswd;
256 }
257
258 static char* _media_thumb_phone_get_path(uid_t uid)
259 {
260         char *result_psswd = NULL;
261         struct group *grpinfo = NULL;
262         if(uid == getuid())
263         {
264                 result_psswd = strdup(THUMB_PHONE_PATH);
265                 grpinfo = getgrnam("users");
266                 if(grpinfo == NULL) {
267                         thumb_err("getgrnam(users) returns NULL !");
268                         return NULL;
269                 }
270         }
271         else
272         {
273                 struct passwd *userinfo = getpwuid(uid);
274                 if(userinfo == NULL) {
275                         thumb_err("getpwuid(%d) returns NULL !", uid);
276                         return NULL;
277                 }
278                 grpinfo = getgrnam("users");
279                 if(grpinfo == NULL) {
280                         thumb_err("getgrnam(users) returns NULL !");
281                         return NULL;
282                 }
283                 // Compare git_t type and not group name
284                 if (grpinfo->gr_gid != userinfo->pw_gid) {
285                         thumb_err("UID [%d] does not belong to 'users' group!", uid);
286                         return NULL;
287                 }
288                 asprintf(&result_psswd, "%s/data/file-manager-service/.thumb/phone", userinfo->pw_dir);
289         }
290
291         _mkdir(result_psswd,S_IRWXU | S_IRWXG | S_IRWXO);
292
293         return result_psswd;
294 }
295
296 int
297 _media_thumb_get_hash_name(const char *file_full_path,
298                                  char *thumb_hash_path, size_t max_thumb_path, uid_t uid)
299 {
300         char *hash_name;
301         char *thumb_dir = NULL;
302         char file_ext[255] = { 0 };
303         media_thumb_store_type store_type = -1;
304
305         if (file_full_path == NULL || thumb_hash_path == NULL
306             || max_thumb_path <= 0) {
307                 thumb_err
308                     ("file_full_path==NULL || thumb_hash_path == NULL || max_thumb_path <= 0");
309                 return -1;
310         }
311
312         _media_thumb_get_file_ext(file_full_path, file_ext, sizeof(file_ext));
313
314         store_type = _media_thumb_get_store_type_by_path(file_full_path);
315         if (store_type == THUMB_PHONE) {
316                 thumb_dir = _media_thumb_phone_get_path(uid);
317         } else if (store_type == THUMB_MMC) {
318                 thumb_dir = _media_thumb_mmc_get_path(uid);
319         } else {
320                 thumb_dir = _media_thumb_phone_get_path(uid);
321         }
322
323         hash_name = _media_thumb_generate_hash_name(file_full_path);
324
325         int ret_len;
326         ret_len =
327             snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg",
328                      thumb_dir, file_ext, hash_name);
329         if (ret_len < 0) {
330                 thumb_err("Error when snprintf");
331                 return -1;
332         } else if (ret_len > max_thumb_path) {
333                 thumb_err("Error for the length of thumb pathname");
334                 return -1;
335         }
336
337         //thumb_dbg("thumb hash : %s", thumb_hash_path);
338
339         return 0;
340 }
341
342
343 int _media_thumb_save_to_file_with_evas(unsigned char *data, 
344                                                                                         int w,
345                                                                                         int h,
346                                                                                         int alpha,
347                                                                                         char *thumb_path)
348 {       
349         Ecore_Evas *ee =
350                 ecore_evas_buffer_new(w, h);
351         if (ee == NULL) {
352                 thumb_err("Failed to create a new ecore evas buffer\n");
353                 return -1;
354         }
355
356         Evas *evas = ecore_evas_get(ee);
357         if (evas == NULL) {
358                 thumb_err("Failed to ecore_evas_get\n");
359                 ecore_evas_free(ee);
360                 return -1;
361         }
362
363         Evas_Object *img = NULL;
364         img = evas_object_image_add(evas);
365
366         if (img == NULL) {
367                 thumb_err("image object is NULL\n");
368                 ecore_evas_free(ee);
369                 return -1;
370         }
371
372         evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
373         evas_object_image_size_set(img, w, h);
374         evas_object_image_fill_set(img, 0, 0, w, h);
375
376         if (alpha) evas_object_image_alpha_set(img, 1);
377
378         evas_object_image_data_set(img, data);
379         evas_object_image_data_update_add(img, 0, 0, w, h);
380
381         if (evas_object_image_save
382                 (img, thumb_path, NULL, "quality=100 compress=1")) {
383                 thumb_dbg("evas_object_image_save success\n");
384                 ecore_evas_free(ee);
385
386                 return 0;
387         } else {
388                 thumb_dbg("evas_object_image_save failed\n");
389                 ecore_evas_free(ee);
390                 return -1;
391         }
392 }
393
394
395 int _thumbnail_get_data(const char *origin_path, 
396                                                 media_thumb_type thumb_type, 
397                                                 media_thumb_format format, 
398                                                 unsigned char **data,
399                                                 int *size,
400                                                 int *width,
401                                                 int *height,
402                                                 int *origin_width,
403                                                 int *origin_height,
404                                                 int *alpha,
405                                                 uid_t uid)
406 {
407         int err = -1;
408         int thumb_width = -1;
409         int thumb_height = -1;
410
411         if (origin_path == NULL || size == NULL 
412                         || width == NULL || height == NULL) {
413                 thumb_err("Invalid parameter");
414                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
415         }
416
417         if (format < MEDIA_THUMB_BGRA || format > MEDIA_THUMB_RGB888) {
418                 thumb_err("parameter format is invalid");
419                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
420         }
421
422         if (!g_file_test
423             (origin_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
424                         thumb_err("Original path (%s) does not exist", origin_path);
425                         return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
426         }
427
428         thumb_width = _media_thumb_get_width(thumb_type);
429         if (thumb_width < 0) {
430                 thumb_err("media_thumb_type is invalid");
431                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
432         }
433
434         thumb_height = _media_thumb_get_height(thumb_type);
435         if (thumb_height < 0) {
436                 thumb_err("media_thumb_type is invalid");
437                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
438         }
439
440         thumb_dbg("Origin path : %s", origin_path);
441
442         int file_type = THUMB_NONE_TYPE;
443         media_thumb_info thumb_info = {0,};
444         file_type = _media_thumb_get_file_type(origin_path);
445
446         if (file_type == THUMB_IMAGE_TYPE) {
447                 err = _media_thumb_image(origin_path, thumb_width, thumb_height, format, &thumb_info, uid);
448                 if (err < 0) {
449                         thumb_err("_media_thumb_image failed");
450                         return err;
451                 }
452
453         } else if (file_type == THUMB_VIDEO_TYPE) {
454                 err = _media_thumb_video(origin_path, thumb_width, thumb_height, format, &thumb_info,uid);
455                 if (err < 0) {
456                         thumb_err("_media_thumb_image failed");
457                         return err;
458                 }
459         }
460
461         if (size) *size = thumb_info.size;
462         if (width) *width = thumb_info.width;
463         if (height) *height = thumb_info.height;
464         *data = thumb_info.data;
465         if (origin_width) *origin_width = thumb_info.origin_width;
466         if (origin_height) *origin_height = thumb_info.origin_height;
467         if (alpha) *alpha = thumb_info.alpha;
468
469         thumb_dbg("Thumb data is generated successfully (Size:%d, W:%d, H:%d) 0x%x",
470                                 *size, *width, *height, *data);
471
472         return MEDIA_THUMB_ERROR_NONE;
473 }