[SATIZENVUL-926] Check allocation
[platform/core/multimedia/libmedia-thumbnail.git] / src / media-thumb-internal.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-debug.h"
23 #include "media-thumb-util.h"
24 #include "media-thumb-internal.h"
25 #include "media-thumb-ipc.h"
26
27 #include "AGifFrameInfo.h"
28 #include "IfegDecodeAGIF.h"
29 #include "img-codec.h"
30 #include "img-codec-agif.h"
31 #include "img-codec-common.h"
32 #include "img-codec-osal.h"
33 #include "img-codec-parser.h"
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39
40 #include <mm_file.h>
41 #include <mm_util_imgp.h>
42 #include <mm_util_jpeg.h>
43 #include <Evas.h>
44 #include <Ecore_Evas.h>
45 #include <libexif/exif-data.h>
46 #include <sys/stat.h>
47
48 #define MEDIA_THUMB_ROUND_UP_8(num) (((num)+7)&~7)
49
50 int _media_thumb_rgb_to_argb(const unsigned char *src_data, const int src_size,
51                                                         unsigned char **dst_data,
52                                                         unsigned int *buf_size,
53                                                         int width,
54                                                         int height)
55 {
56         int err = MS_MEDIA_ERR_NONE;
57         int i = 0, j;
58
59         if (mm_util_get_image_size(MM_UTIL_IMG_FMT_BGRA8888, width, height, buf_size) < 0) {
60                 thumb_err("mm_util_get_image_size failed");
61                 return MS_MEDIA_ERR_INTERNAL;
62         }
63
64         thumb_dbg("mm_util_get_image_size : %d", *buf_size);
65
66         *dst_data = (unsigned char *)malloc(*buf_size);
67         if (*dst_data == NULL) {
68                 thumb_err("Failed to allocate memory");
69                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
70         }
71
72         for (j = 0; ((j < src_size) && (i < *buf_size)); j += 3) {
73                 (*dst_data)[i++] = (src_data[j + 2]);
74                 (*dst_data)[i++] = (src_data[j + 1]);
75                 (*dst_data)[i++] = (src_data[j]);
76                 (*dst_data)[i++] = 0x0;
77         }
78
79         thumb_dbg("_media_thumb_rgb_to_argb success");
80
81         return err;
82 }
83
84 int _media_thumb_resize_with_evas(const void *image, int thumb_width, int thumb_height, media_thumb_info *thumb_info)
85 {
86         Ecore_Evas *resize_img_ee;
87
88         if (image == NULL) {
89                 thumb_err("Invalid parameter");
90                 return MS_MEDIA_ERR_INVALID_PARAMETER;
91         }
92         resize_img_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
93         if (!resize_img_ee) {
94                 thumb_err("ecore_evas_buffer_new failed");
95                 return MS_MEDIA_ERR_INTERNAL;
96         }
97
98         Evas *resize_img_e = ecore_evas_get(resize_img_ee);
99         if (!resize_img_e) {
100                 thumb_err("ecore_evas_get failed");
101                 ecore_evas_free(resize_img_ee);
102                 return MS_MEDIA_ERR_INTERNAL;
103         }
104
105         Evas_Object *source_img = evas_object_image_add(resize_img_e);
106         if (!source_img) {
107                 thumb_err("evas_object_image_add failed");
108                 ecore_evas_free(resize_img_ee);
109                 return MS_MEDIA_ERR_INTERNAL;
110         }
111
112         evas_object_image_size_set(source_img, thumb_info->origin_width, thumb_info->origin_height);
113         evas_object_image_colorspace_set(source_img, EVAS_COLORSPACE_ARGB8888);
114         evas_object_image_fill_set(source_img, 0, 0, thumb_info->origin_width, thumb_info->origin_height);
115         evas_object_image_filled_set(source_img, EINA_TRUE);
116
117         evas_object_image_data_set(source_img, (int *)image);
118         evas_object_image_data_update_add(source_img, 0, 0, thumb_info->origin_width, thumb_info->origin_height);
119
120         if (thumb_info->origin_width * thumb_info->origin_height > THUMB_MAX_ALLOWED_MEM_FOR_THUMB) {
121                 thumb_warn("This is too large image. so this's scale is going to be down");
122                 evas_object_image_load_scale_down_set(source_img, 10);
123         }
124
125         ecore_evas_resize(resize_img_ee, thumb_width, thumb_height);
126
127         evas_object_image_load_size_set(source_img, thumb_width, thumb_height);
128         evas_object_image_fill_set(source_img, 0, 0, thumb_width, thumb_height);
129         evas_object_image_filled_set(source_img, EINA_TRUE);
130
131         evas_object_resize(source_img, thumb_width, thumb_height);
132         evas_object_show(source_img);
133
134         /* Set alpha from original */
135         thumb_info->alpha = evas_object_image_alpha_get(source_img);
136         if (thumb_info->alpha)
137                 ecore_evas_alpha_set(resize_img_ee, EINA_TRUE);
138
139         /* Create target buffer and copy origin resized img to it */
140         Ecore_Evas *target_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
141         if (!target_ee) {
142                 thumb_err("ecore_evas_buffer_new failed");
143                 ecore_evas_free(resize_img_ee);
144                 return MS_MEDIA_ERR_INTERNAL;
145         }
146
147         Evas *target_evas = ecore_evas_get(target_ee);
148         if (!target_evas) {
149                 thumb_err("ecore_evas_get failed");
150                 ecore_evas_free(resize_img_ee);
151                 ecore_evas_free(target_ee);
152                 return MS_MEDIA_ERR_INTERNAL;
153         }
154
155         Evas_Object *ret_image = evas_object_image_add(target_evas);
156         evas_object_image_size_set(ret_image, thumb_width, thumb_height);
157         evas_object_image_fill_set(ret_image, 0, 0, thumb_width, thumb_height);
158         evas_object_image_filled_set(ret_image, EINA_TRUE);
159
160         evas_object_image_data_set(ret_image, (int *)ecore_evas_buffer_pixels_get(resize_img_ee));
161         evas_object_image_data_update_add(ret_image, 0, 0, thumb_width, thumb_height);
162
163         unsigned int buf_size = 0;
164         if (mm_util_get_image_size(MM_UTIL_IMG_FMT_BGRA8888, thumb_width, thumb_height, &buf_size) < 0) {
165                 thumb_err("mm_util_get_image_size failed");
166
167                 ecore_evas_free(resize_img_ee);
168                 ecore_evas_free(target_ee);
169
170                 return MS_MEDIA_ERR_INTERNAL;
171         }
172
173         thumb_info->size = buf_size;
174         thumb_info->width = thumb_width;
175         thumb_info->height = thumb_height;
176         thumb_info->data = malloc(buf_size);
177         if (thumb_info->data == NULL) {
178                 thumb_err("Failed to allocate memory");
179                 ecore_evas_free(resize_img_ee);
180                 ecore_evas_free(target_ee);
181
182                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
183         }
184
185         void *image_data = evas_object_image_data_get(ret_image, EINA_TRUE);
186         if (image_data != NULL) {
187                 memcpy(thumb_info->data, image_data, buf_size);
188         } else {
189                 thumb_err("image_data is NULL. evas_object_image_data_get failed");
190         }
191
192         ecore_evas_free(target_ee);
193         ecore_evas_free(resize_img_ee);
194
195         thumb_dbg("_media_thumb_resize_with_evas success");
196
197         return MS_MEDIA_ERR_NONE;
198 }
199
200 int _media_thumb_rotate_argb(unsigned char *source, const unsigned int size, int format, int *ori_width, int *ori_height)
201 {
202         int dpp = 0; /* data per pixel */
203         int x = 0, y = 0;
204         int i = 0;
205         int width = 0, height = 0;
206         unsigned char *temp_buf = NULL;
207
208         if (format == MM_UTIL_JPEG_FMT_BGRA8888) {
209                 dpp = 4;
210         } else if (format == MM_UTIL_JPEG_FMT_RGB888) {
211                 dpp = 3;
212         } else {
213                 thumb_err("Invalid parameter");
214                 return MS_MEDIA_ERR_INVALID_PARAMETER;
215         }
216
217         temp_buf = malloc(size);
218         if (temp_buf == NULL) {
219                 thumb_err("Failed to allocate memory");
220                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
221         }
222         /* initialize */
223         memset(temp_buf, 0x00, size);
224         width = *ori_width;
225         height = *ori_height;
226
227         /* rotate image to 90 degree clockwise */
228         for (y = 0; y < height; y++) {
229                 for (x = 0; x < width; x++) {
230                         for (i = 0; i < dpp; i++) {
231                                 temp_buf[(x * height + (height - y - 1)) * dpp + i] = source[(y * width + x) * dpp + i];
232                         }
233                 }
234         }
235
236         /* copy image from temp buffer to original buffer */
237         memcpy(source, temp_buf, size);
238         SAFE_FREE(temp_buf);
239
240         /* swap width & height due to rotate 90 degree */
241         *ori_width = height;
242         *ori_height = width;
243
244         return MS_MEDIA_ERR_NONE;
245 }
246
247 int _media_thumb_rotate_thumb(unsigned char *data, int size, int *width, int *height, int orientation, int format)
248 {
249         int err = MS_MEDIA_ERR_NONE;
250         int i = 0, count = 0;
251
252         if (orientation == MM_UTIL_ROTATE_90) {
253                 count = 1;
254         } else if (orientation == MM_UTIL_ROTATE_180) {
255                 count = 2;
256         } else if (orientation == MM_UTIL_ROTATE_270) {
257                 count = 3;
258         }
259
260         for (i = 0; i < count; i++) {
261                 err = _media_thumb_rotate_argb(data, size, format, width, height);
262                 if (err != MS_MEDIA_ERR_NONE) {
263                         thumb_err("Failed to rotate video thumbnail %d", err);
264                         return err;
265                 }
266 //              thumb_dbg("[%d rotate] width:%d, height:%d", (i + 1) * 90, thumb_info->width, thumb_info->height);
267         }
268
269         thumb_dbg("_media_thumb_rotate_thumb success");
270         return MS_MEDIA_ERR_NONE;
271 }
272
273 int _media_thumb_get_proper_thumb_size(int orig_w, int orig_h, int *thumb_w, int *thumb_h)
274 {
275         BOOL portrait = FALSE;
276         double ratio;
277
278         if (orig_w < orig_h) {
279                 portrait = TRUE;
280         }
281
282         /* Set smaller length to default size */
283         if (portrait) {
284                 if (orig_w < *thumb_w)
285                         *thumb_w = orig_w;
286                 ratio = (double)orig_h / (double)orig_w;
287                 *thumb_h = *thumb_w * ratio;
288         } else {
289                 if (orig_h < *thumb_h)
290                         *thumb_h = orig_h;
291                 ratio = (double)orig_w / (double)orig_h;
292                 *thumb_w = *thumb_h * ratio;
293         }
294
295         /** CAUTION :: The width of RGB888 raw data has to be rounded by 8 **/
296         *thumb_w = MEDIA_THUMB_ROUND_UP_8(*thumb_w);
297
298         thumb_dbg("proper thumb w: %d h: %d", *thumb_w, *thumb_h);
299
300         return MS_MEDIA_ERR_NONE;
301 }
302
303 int _media_thumb_get_exif_info(ExifData *ed, int *value, int ifdtype, long tagtype)
304 {
305         ExifEntry *entry;
306         ExifIfd ifd;
307         ExifTag tag;
308
309         if (ed == NULL) {
310                 return MS_MEDIA_ERR_INVALID_PARAMETER;
311         }
312
313         ifd = ifdtype;
314         tag = tagtype;
315
316         entry = exif_content_get_entry(ed->ifd[ifd], tag);
317         if (entry) {
318                 if (tag == EXIF_TAG_ORIENTATION ||
319                                 tag == EXIF_TAG_PIXEL_X_DIMENSION ||
320                                 tag == EXIF_TAG_PIXEL_Y_DIMENSION) {
321
322                         if (value == NULL) {
323                                 thumb_err("value is NULL");
324                                 return MS_MEDIA_ERR_INVALID_PARAMETER;
325                         }
326
327                         ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
328                         short exif_value = exif_get_short(entry->data, mByteOrder);
329                         *value = (int)exif_value;
330                 }
331         }
332
333         return MS_MEDIA_ERR_NONE;
334 }
335
336 static int __media_thumb_safe_atoi(char *buffer, int *si)
337 {
338         char *end = NULL;
339         errno = 0;
340         thumb_retvm_if(buffer == NULL || si == NULL, MS_MEDIA_ERR_INTERNAL, "invalid parameter");
341
342         const long sl = strtol(buffer, &end, 10);
343
344         thumb_retvm_if(end == buffer, MS_MEDIA_ERR_INTERNAL, "not a decimal number");
345         thumb_retvm_if('\0' != *end, MS_MEDIA_ERR_INTERNAL, "extra characters at end of input: %s", end);
346         thumb_retvm_if((LONG_MIN == sl || LONG_MAX == sl) && (ERANGE == errno), MS_MEDIA_ERR_INTERNAL, "out of range of type long");
347         thumb_retvm_if(sl > INT_MAX, MS_MEDIA_ERR_INTERNAL, "greater than INT_MAX");
348         thumb_retvm_if(sl < INT_MIN, MS_MEDIA_ERR_INTERNAL, "less than INT_MIN");
349
350         *si = (int)sl;
351
352         return MS_MEDIA_ERR_NONE;
353 }
354
355 static int _media_thumb_get_data_from_exif(ExifData *ed,
356                                                                                                 void **thumb_data,
357                                                                                                 int *thumb_size,
358                                                                                                 int *thumb_width,
359                                                                                                 int *thumb_height,
360                                                                                                 int *origin_width,
361                                                                                                 int *origin_height)
362 {
363         ExifEntry *entry;
364         ExifIfd ifd;
365         ExifTag tag;
366
367         ExifByteOrder byte_order = exif_data_get_byte_order(ed);
368
369         ifd = EXIF_IFD_1;
370         tag = EXIF_TAG_COMPRESSION;
371
372         entry = exif_content_get_entry(ed->ifd[ifd], tag);
373
374         if (entry) {
375                 /* Get the contents of the tag in human-readable form */
376                 ExifShort value = exif_get_short(entry->data, byte_order);
377                 //thumb_dbg("%s: %d", exif_tag_get_name_in_ifd(tag,ifd), value);
378
379                 if (value == 6) {
380                         thumb_dbg("There's jpeg thumb in this image");
381                 } else {
382                         thumb_dbg("There's NO jpeg thumb in this image");
383                         return MS_MEDIA_ERR_INVALID_PARAMETER;
384                 }
385         } else {
386                 thumb_dbg("entry is NULL");
387                 return MS_MEDIA_ERR_INVALID_PARAMETER;
388         }
389
390         /* copy the real thumbnail data from exif data */
391         if (ed->data && ed->size) {
392                 /* NOTICE : ExifData->size type is unsigned int, But Internal IPC, and CAPI use int */
393                 if (ed->size > INT_MAX) {
394                         thumb_err("EXIF thumbnail size is over INT_MAX");
395                         return MS_MEDIA_ERR_THUMB_TOO_BIG;
396                 }
397
398                 *thumb_data = (char *)malloc(ed->size);
399
400                 if (*thumb_data == NULL) {
401                         thumb_dbg("malloc failed!");
402                         return MS_MEDIA_ERR_INVALID_PARAMETER;
403                 }
404
405                 memcpy(*thumb_data, (void *)ed->data, ed->size);
406                 *thumb_size = ed->size;
407         } else {
408                 thumb_dbg("data is NULL");
409                 return MS_MEDIA_ERR_INVALID_PARAMETER;
410         }
411
412         /* Get width and height of thumbnail */
413         tag = EXIF_TAG_IMAGE_WIDTH;
414         entry = exif_content_get_entry(ed->ifd[ifd], tag);
415
416         if (entry) {
417                 /* Get the contents of the tag in human-readable form */
418                 char width[10] = {0,};
419                 exif_entry_get_value(entry, width, 10);
420                 __media_thumb_safe_atoi(width, thumb_width);
421         } else {
422                 thumb_warn("EXIF_TAG_IMAGE_WIDTH does not exist");
423                 *thumb_width = 0;
424         }
425
426         tag = EXIF_TAG_IMAGE_LENGTH;
427         entry = exif_content_get_entry(ed->ifd[ifd], tag);
428         if (entry) {
429                 /* Get the contents of the tag in human-readable form */
430                 char height[10] = {0, };
431                 exif_entry_get_value(entry, height, 10);
432                 __media_thumb_safe_atoi(height, thumb_height);
433         } else {
434                 thumb_warn("EXIF_TAG_IMAGE_LENGTH does not exist");
435                 *thumb_height = 0;
436         }
437
438         thumb_dbg("thumb width : height [%d:%d]", *thumb_width, *thumb_height);
439
440         /* Get width and height of original image from exif */
441         ifd = EXIF_IFD_EXIF;
442         tag = EXIF_TAG_PIXEL_X_DIMENSION;
443         entry = exif_content_get_entry(ed->ifd[ifd], tag);
444
445         if (entry) {
446                 char width[10] = {0,};
447                 exif_entry_get_value(entry, width, 10);
448                 __media_thumb_safe_atoi(width, origin_width);
449         } else {
450                 thumb_warn("EXIF_TAG_PIXEL_X_DIMENSION does not exist");
451                 *origin_width = 0;
452         }
453
454         tag = EXIF_TAG_PIXEL_Y_DIMENSION;
455         entry = exif_content_get_entry(ed->ifd[ifd], tag);
456
457         if (entry) {
458                 char height[10] = {0, };
459                 exif_entry_get_value(entry, height, 10);
460                 __media_thumb_safe_atoi(height, origin_height);
461         } else {
462                 thumb_warn("EXIF_TAG_PIXEL_Y_DIMENSION does not exist");
463                 *origin_height = 0;
464         }
465
466         return MS_MEDIA_ERR_NONE;
467 }
468
469 int _media_thumb_get_thumb_from_exif(ExifData *ed,
470                                                                 const char *file_full_path,
471                                                                 const char *thumb_path,
472                                                                 int orientation,
473                                                                 int required_width,
474                                                                 int required_height,
475                                                                 media_thumb_info *thumb_info)
476 {
477         int err = MS_MEDIA_ERR_NONE;
478         int size = 0;
479         int thumb_width = 0;
480         int thumb_height = 0;
481         int origin_width = 0;
482         int origin_height = 0;
483         void *thumb = NULL;
484         bool is_rotated = (orientation == ROT_90 || orientation == ROT_180 || orientation == ROT_270) ? TRUE : FALSE;
485         mm_util_jpeg_yuv_data decoded = {0,};
486
487         if (ed == NULL) {
488                 return MS_MEDIA_ERR_INVALID_PARAMETER;
489         }
490
491         err = _media_thumb_get_data_from_exif(ed,
492                                                                                 &thumb,
493                                                                                 &size,
494                                                                                 &thumb_width,
495                                                                                 &thumb_height,
496                                                                                 &origin_width,
497                                                                                 &origin_height);
498
499         if (err != MS_MEDIA_ERR_NONE) {
500                 thumb_err("There is no exif data");
501                 return err;
502         }
503
504         thumb_dbg("thumb width : height [%d:%d]", thumb_width, thumb_height);
505         thumb_dbg("origin width : height [%d:%d]", origin_width, origin_height);
506         thumb_info->origin_height = origin_height;
507         thumb_info->origin_width = origin_width;
508
509         if (thumb_width < required_width) {
510                 thumb_err("Thumb data in exif is too small");
511                 SAFE_FREE(thumb);
512                 return MS_MEDIA_ERR_INVALID_PARAMETER;
513         }
514
515         if (is_rotated) {
516                 err = mm_util_decode_from_jpeg_memory(&decoded, thumb, (unsigned int)size, MM_UTIL_JPEG_FMT_RGB888);
517                 SAFE_FREE(thumb);
518                 if (err != MS_MEDIA_ERR_NONE) {
519                         thumb_err("mm_util_decode_from_jpeg_turbo_memory failed : %d", err);
520                         return err;
521                 }
522
523                 thumb_width = decoded.width;
524                 thumb_height = decoded.height;
525
526                 int rot_type = MM_UTIL_ROTATE_0;
527                 if (orientation == ROT_90) {
528                         rot_type = MM_UTIL_ROTATE_90;
529                 } else if (orientation == ROT_180) {
530                         rot_type = MM_UTIL_ROTATE_180;
531                 } else if (orientation == ROT_270) {
532                         rot_type = MM_UTIL_ROTATE_270;
533                 }
534                 err = _media_thumb_rotate_thumb(decoded.data, decoded.size, &(decoded.width), &(decoded.height), rot_type, MM_UTIL_JPEG_FMT_RGB888);
535                 if (err != MS_MEDIA_ERR_NONE) {
536                         thumb_err("_media_thumb_rotate_thumb falied: %d", err);
537                         SAFE_FREE(thumb_info->data);
538                         return err;
539                 }
540                 //thumb_dbg("Width : %d, Height : %d", decoded.width, decoded.height);
541                 thumb_info->data = decoded.data;
542                 thumb_info->size = decoded.size;
543                 thumb_info->width = decoded.width;
544                 thumb_info->height = decoded.height;
545         } else {
546                 /*in this case, just write raw data in file */
547                 thumb_dbg_slog("Thumb is :%s", thumb_path);
548
549                 int nwrite;
550                 int fd = open(thumb_path, O_RDWR | O_CREAT | O_EXCL | O_SYNC, 0644);
551                 if (fd < 0) {
552                         if (errno == EEXIST) {
553                                 thumb_err("thumb alread exist!");
554                         } else {
555                                 thumb_err("open failed");
556                                 SAFE_FREE(thumb);
557                                 return MS_MEDIA_ERR_INVALID_PARAMETER;
558                         }
559                 } else {
560                         nwrite = write(fd, thumb, size);
561                         if (nwrite < 0) {
562                                 thumb_err("write failed");
563                                 close(fd);
564
565                                 SAFE_FREE(thumb);
566                                 return MS_MEDIA_ERR_INVALID_PARAMETER;
567                         }
568                         close(fd);
569                 }
570
571                 SAFE_FREE(thumb);
572                 thumb_info->data = NULL;
573                 thumb_info->size = size;
574                 thumb_info->width = thumb_width;
575                 thumb_info->height = thumb_height;
576                 thumb_info->is_saved = TRUE;
577         }
578
579         return err;
580 }
581
582 int _media_thumb_get_wh_with_evas(const char *origin_path, int *width, int *height)
583 {
584         /* using evas to get w/h */
585         Ecore_Evas *ee = ecore_evas_buffer_new(0, 0);
586         if (!ee) {
587                 thumb_err("ecore_evas_buffer_new fails");
588                 return MS_MEDIA_ERR_INTERNAL;
589         }
590
591         Evas *evas = ecore_evas_get(ee);
592         if (!evas) {
593                 thumb_err("ecore_evas_get fails");
594                 ecore_evas_free(ee);
595                 return MS_MEDIA_ERR_INTERNAL;
596         }
597
598         Evas_Object *image_object = evas_object_image_add(evas);
599         if (!image_object) {
600                 thumb_err("evas_object_image_add fails");
601                 ecore_evas_free(ee);
602                 return MS_MEDIA_ERR_INTERNAL;
603         }
604
605         evas_object_image_file_set(image_object, origin_path, NULL);
606         evas_object_image_size_get(image_object, width, height);
607
608         thumb_dbg("Width:%d, Height:%d", *width, *height);
609
610         ecore_evas_free(ee);
611
612         return MS_MEDIA_ERR_NONE;
613 }
614
615 int _media_thumb_decode_with_evas(const char *origin_path,
616                                         int thumb_width, int thumb_height,
617                                         media_thumb_info *thumb_info, int need_scale, int orientation)
618 {
619         Ecore_Evas *resize_img_ee;
620
621         resize_img_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
622         if (!resize_img_ee) {
623                 thumb_err("ecore_evas_buffer_new failed");
624                 return MS_MEDIA_ERR_INTERNAL;
625         }
626
627         Evas *resize_img_e = ecore_evas_get(resize_img_ee);
628         if (!resize_img_e) {
629                 thumb_err("ecore_evas_get failed");
630                 ecore_evas_free(resize_img_ee);
631                 return MS_MEDIA_ERR_INTERNAL;
632         }
633
634         Evas_Object *source_img = evas_object_image_add(resize_img_e);
635         if (!source_img) {
636                 thumb_err("evas_object_image_add failed");
637                 ecore_evas_free(resize_img_ee);
638                 return MS_MEDIA_ERR_INTERNAL;
639         }
640
641         evas_object_image_file_set(source_img, origin_path, NULL);
642
643         /* Get w/h of original image */
644         int width = 0;
645         int height = 0;
646
647         evas_object_image_size_get(source_img, &width, &height);
648         thumb_info->origin_width = width;
649         thumb_info->origin_height = height;
650         //thumb_dbg("origin width:%d, origin height:%d", width, height);
651
652         /* This case for only JPEG format.. JPEG can be partially processed.. */
653         if ((need_scale == 1) && (width * height > THUMB_MAX_ALLOWED_MEM_FOR_THUMB)) {
654                 thumb_warn("This is too large image. so this's scale is going to be down");
655                 evas_object_image_load_scale_down_set(source_img, 10);
656         }
657
658         if (orientation != TRANSPOSE)
659                 evas_object_image_load_orientation_set(source_img, 1);
660
661         int rotated_orig_w = 0;
662         int rotated_orig_h = 0;
663
664         if (orientation == ROT_90 || orientation == ROT_270) {
665                 rotated_orig_w = height;
666                 rotated_orig_h = width;
667         } else {
668                 rotated_orig_w = width;
669                 rotated_orig_h = height;
670         }
671         //thumb_dbg("rotated - origin width:%d, origin height:%d", rotated_orig_w, rotated_orig_h);
672
673         int err = MS_MEDIA_ERR_NONE;
674
675         err = _media_thumb_get_proper_thumb_size(rotated_orig_w, rotated_orig_h, &thumb_width, &thumb_height);
676         if (err != MS_MEDIA_ERR_NONE) {
677                 thumb_err("_media_thumb_get_proper_thumb_size failed: %d", err);
678                 ecore_evas_free(resize_img_ee);
679                 return err;
680         }
681
682         ecore_evas_resize(resize_img_ee, thumb_width, thumb_height);
683
684         evas_object_image_load_size_set(source_img, thumb_width, thumb_height);
685         evas_object_image_fill_set(source_img, 0, 0, thumb_width, thumb_height);
686         evas_object_image_filled_set(source_img, 1);
687
688         evas_object_resize(source_img, thumb_width, thumb_height);
689         evas_object_show(source_img);
690
691         /* Set alpha from original */
692         thumb_info->alpha = evas_object_image_alpha_get(source_img);
693         if (thumb_info->alpha) ecore_evas_alpha_set(resize_img_ee, EINA_TRUE);
694
695         /* Create target buffer and copy origin resized img to it */
696         Ecore_Evas *target_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
697         if (!target_ee) {
698                 thumb_err("ecore_evas_buffer_new failed");
699                 ecore_evas_free(resize_img_ee);
700                 return MS_MEDIA_ERR_INTERNAL;
701         }
702
703         Evas *target_evas = ecore_evas_get(target_ee);
704         if (!target_evas) {
705                 thumb_err("ecore_evas_get failed");
706                 ecore_evas_free(resize_img_ee);
707                 ecore_evas_free(target_ee);
708                 return MS_MEDIA_ERR_INTERNAL;
709         }
710
711         Evas_Object *ret_image = evas_object_image_add(target_evas);
712         evas_object_image_size_set(ret_image, thumb_width, thumb_height);
713         evas_object_image_fill_set(ret_image, 0, 0, thumb_width, thumb_height);
714         evas_object_image_filled_set(ret_image, EINA_TRUE);
715
716         evas_object_image_data_set(ret_image, (int *)ecore_evas_buffer_pixels_get(resize_img_ee));
717         evas_object_image_data_update_add(ret_image, 0, 0, thumb_width, thumb_height);
718
719         unsigned int buf_size = 0;
720         if (mm_util_get_image_size(MM_UTIL_IMG_FMT_BGRA8888, thumb_width, thumb_height, &buf_size) < 0) {
721                 thumb_err("mm_util_get_image_size failed");
722
723                 ecore_evas_free(resize_img_ee);
724                 ecore_evas_free(target_ee);
725
726                 return MS_MEDIA_ERR_INTERNAL;
727         }
728         //thumb_dbg("mm_util_get_image_size : %d", buf_size);
729
730         thumb_info->size = buf_size;
731         thumb_info->width = thumb_width;
732         thumb_info->height = thumb_height;
733         thumb_info->data = malloc(buf_size);
734         if (thumb_info->data == NULL) {
735                 thumb_err("Failed to allocate memory");
736                 ecore_evas_free(resize_img_ee);
737                 ecore_evas_free(target_ee);
738
739                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
740         }
741
742         void *image_data = evas_object_image_data_get(ret_image, 1);
743         if (image_data != NULL) {
744                 memcpy(thumb_info->data, image_data, buf_size);
745         } else {
746                 thumb_err("image_data is NULL. evas_object_image_data_get failed");
747         }
748
749         ecore_evas_free(target_ee);
750         ecore_evas_free(resize_img_ee);
751
752         return err;
753 }
754
755 int _media_thumb_convert_data(media_thumb_info *thumb_info, int thumb_width, int thumb_height)
756 {
757         int err = MS_MEDIA_ERR_NONE;
758         unsigned int buf_size = 0;
759         unsigned char *src_data = thumb_info->data;
760         unsigned char *dst_data = NULL;
761         int i = 0, j;
762
763         if (mm_util_get_image_size(MM_UTIL_IMG_FMT_BGRA8888, thumb_width, thumb_height, &buf_size) < 0) {
764                 thumb_err("mm_util_get_image_size failed");
765                 return MS_MEDIA_ERR_INTERNAL;
766         }
767
768         thumb_dbg("mm_util_get_image_size : %d", buf_size);
769
770         dst_data = (unsigned char *)malloc(buf_size);
771         if (dst_data == NULL) {
772                 thumb_err("Failed to allocate memory");
773                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
774         }
775
776         for (j = 0; j < thumb_width * 3 * thumb_height; j += 3) {
777                 dst_data[i++] = (src_data[j + 2]);
778                 dst_data[i++] = (src_data[j + 1]);
779                 dst_data[i++] = (src_data[j]);
780                 dst_data[i++] = 0x0;
781         }
782
783         SAFE_FREE(thumb_info->data);
784         thumb_info->data = dst_data;
785         thumb_info->size = buf_size;
786
787         thumb_dbg("_media_thumb_convert_data success");
788
789         return err;
790 }
791
792 int _media_thumb_agif(const char *origin_path, int thumb_width, int thumb_height, media_thumb_info *thumb_info)
793 {
794         int err = MS_MEDIA_ERR_NONE;
795         unsigned int *thumb = NULL;
796         unsigned char *dst_image = NULL;
797         unsigned int dst_size = 0;
798         unsigned int thumb_size = 0;
799
800         thumb = ImgGetFirstFrameAGIFAtSize(origin_path, thumb_info->origin_width, thumb_info->origin_height);
801         if (!thumb) {
802                 thumb_err("Frame data is NULL!!");
803                 return MS_MEDIA_ERR_INTERNAL;
804         }
805
806         err = mm_util_get_image_size(MM_UTIL_IMG_FMT_RGB888, thumb_info->origin_width, thumb_info->origin_height, &thumb_size);
807         if (err != MS_MEDIA_ERR_NONE) {
808                 thumb_err("mm_util_get_image_size failed: %d", err);
809                 SAFE_FREE(thumb);
810                 return err;
811         }
812
813         err = _media_thumb_get_proper_thumb_size(thumb_info->origin_width, thumb_info->origin_height, &thumb_width, &thumb_height);
814         if (err != MS_MEDIA_ERR_NONE) {
815                 thumb_err("_media_thumb_get_proper_thumb_size failed: %d", err);
816                 SAFE_FREE(thumb);
817                 return err;
818         }
819
820         err = _media_thumb_rgb_to_argb((unsigned char *) thumb, thumb_size, &dst_image, &dst_size, thumb_info->origin_width, thumb_info->origin_height);
821         if (err != MS_MEDIA_ERR_NONE) {
822                 thumb_err("_media_thumb_convert_data falied: %d", err);
823                 SAFE_FREE(thumb);
824                 return err;
825         }
826
827         err = _media_thumb_resize_with_evas(dst_image, thumb_width, thumb_height, thumb_info);
828         if (err != MS_MEDIA_ERR_NONE) {
829                 thumb_err("_media_thumb_resize_data failed: %d", err);
830                 SAFE_FREE(thumb_info->data);
831                 SAFE_FREE(thumb);
832                 return err;
833         }
834
835         SAFE_FREE(thumb);
836
837         return err;
838 }
839
840 int _media_thumb_general(const char *origin_path, int thumb_width, int thumb_height, media_thumb_info *thumb_info)
841 {
842         int err = MS_MEDIA_ERR_NONE;
843
844         err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
845         if (err != MS_MEDIA_ERR_NONE) {
846                 thumb_err("decode_with_evas failed : %d", err);
847                 return err;
848         }
849
850         return err;
851 }
852
853 int _media_thumb_jpeg(const char *origin_path, const char *thumb_path, int thumb_width, int thumb_height, media_thumb_info *thumb_info)
854 {
855         int err = MS_MEDIA_ERR_NONE;
856         int thumb_done = 0;
857         int orientation = NORMAL;
858         ExifData *ed = NULL;
859
860         if (!thumb_info->is_raw) {
861                 /* Load an ExifData object from an EXIF file */
862                 ed = exif_data_new_from_file(origin_path);
863
864                 if (ed) {
865                         /* First, Get orientation from exif */
866                         err = _media_thumb_get_exif_info(ed, &orientation, EXIF_IFD_0, EXIF_TAG_ORIENTATION);
867                         if (err != MS_MEDIA_ERR_NONE) {
868                                 thumb_warn("_media_thumb_get_exif_info failed");
869                         }
870
871                         /* Second, Get thumb from exif */
872                         err = _media_thumb_get_thumb_from_exif(ed, origin_path, thumb_path, orientation, thumb_width, thumb_height, thumb_info);
873                         if (err != MS_MEDIA_ERR_NONE) {
874                                 thumb_dbg("_media_thumb_get_thumb_from_exif failed");
875                         } else {
876                                 thumb_done = 1;
877                                 thumb_dbg("_media_thumb_get_thumb_from_exif succeed");
878
879                                 /* The case that original image's size is not in exif header. Use evas to get w/h */
880                                 if (thumb_info->origin_width == 0 || thumb_info->origin_height == 0) {
881                                         thumb_warn("original image's size is not in exif header. Use evas to get w/h");
882                                         err = _media_thumb_get_wh_with_evas(origin_path, &(thumb_info->origin_width), &(thumb_info->origin_height));
883                                         if (err != MS_MEDIA_ERR_NONE) {
884                                                 thumb_err("Couldn't get w/h using evas : %s", origin_path);
885                                         } else {
886                                                 thumb_dbg("origin w : %d, origin h : %d", thumb_info->origin_width, thumb_info->origin_height);
887                                         }
888                                 }
889
890                                 if (thumb_info->is_saved == FALSE) {
891                                         err = _media_thumb_convert_data(thumb_info, thumb_info->width, thumb_info->height);
892                                         if (err != MS_MEDIA_ERR_NONE) {
893                                                 thumb_err("_media_thumb_convert_data failed : %d", err);
894                                                 exif_data_unref(ed);
895                                                 return err;
896                                         }
897                                 }
898                         }
899
900                         exif_data_unref(ed);
901                 }
902         } else {
903                 ed = exif_data_new_from_file(origin_path);
904                 if (ed) {
905                         err = _media_thumb_get_exif_info(ed, &orientation, EXIF_IFD_0, EXIF_TAG_ORIENTATION);
906                         if (err != MS_MEDIA_ERR_NONE) {
907                                 thumb_warn("_media_thumb_get_exif_info failed");
908                         }
909                         exif_data_unref(ed);
910                 }
911         }
912
913         if (!thumb_done) {
914                 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, orientation);
915                 if (err != MS_MEDIA_ERR_NONE) {
916                         thumb_err("decode_with_evas failed : %d", err);
917                         return err;
918                 }
919         }
920
921         return err;
922 }
923
924 int _media_thumb_image(const char *origin_path, const char *thumb_path, int thumb_width, int thumb_height, media_thumb_info *thumb_info)
925 {
926         int err = MS_MEDIA_ERR_NONE;
927         ImgCodecType image_type = 0;
928         unsigned int origin_w = 0;
929         unsigned int origin_h = 0;
930
931         err = ImgGetImageInfoForThumb(origin_path, &image_type, &origin_w, &origin_h);
932         if (err != MS_MEDIA_ERR_NONE) {
933                 thumb_warn("Getting image info is failed err: %d", err);
934         }
935
936         thumb_info->origin_width = origin_w;
937         thumb_info->origin_height = origin_h;
938
939         if ((image_type != IMG_CODEC_JPEG) && (origin_w * origin_h > THUMB_MAX_ALLOWED_MEM_FOR_THUMB)) {
940                 thumb_warn("This original image is too big");
941                 return MS_MEDIA_ERR_THUMB_TOO_BIG;
942         }
943
944         if (image_type == IMG_CODEC_AGIF) {
945                 err = _media_thumb_agif(origin_path, thumb_width, thumb_height, thumb_info);
946         } else if (image_type == IMG_CODEC_JPEG) {
947                 err = _media_thumb_jpeg(origin_path, thumb_path, thumb_width, thumb_height, thumb_info);
948         } else if (image_type == IMG_CODEC_PNG || image_type == IMG_CODEC_GIF || image_type == IMG_CODEC_BMP || image_type == IMG_CODEC_WBMP) {
949                 err = _media_thumb_general(origin_path, thumb_width, thumb_height, thumb_info);
950         } else {
951                 thumb_warn("Unsupported image type");
952                 return MS_MEDIA_ERR_THUMB_UNSUPPORTED;
953         }
954
955         return err;
956 }
957
958 int _media_thumb_video(const char *origin_path, int thumb_width, int thumb_height, media_thumb_info *thumb_info)
959 {
960         int err = MS_MEDIA_ERR_NONE;
961
962         MMHandleType content = (MMHandleType) NULL;
963         void *frame = NULL;
964         int video_track_num = 0;
965         char *err_msg = NULL;
966         int is_drm = 0;
967         int size = 0;
968         int width = 0;
969         int height = 0;
970         bool drm_type = FALSE;
971
972         is_drm = drm_type;
973
974         /* Get Content Tag attribute for orientatin */
975         MMHandleType tag = (MMHandleType) NULL;
976         char *p = NULL;
977         int cdis_value = 0;
978         err = mm_file_create_tag_attrs(&tag, origin_path);
979         mm_util_img_rotate_type rot_type = MM_UTIL_ROTATE_0;
980
981         if (err == FILEINFO_ERROR_NONE) {
982                 err = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_ROTATE, &p, &size, NULL);
983                 if (err == FILEINFO_ERROR_NONE && size >= 0) {
984                         if (p == NULL) {
985                                 rot_type = MM_UTIL_ROTATE_0;
986                         } else {
987                                 if (strncmp(p, "90", size) == 0) {
988                                         rot_type = MM_UTIL_ROTATE_90;
989                                 } else if (strncmp(p, "180", size) == 0) {
990                                         rot_type = MM_UTIL_ROTATE_180;
991                                 } else if (strncmp(p, "270", size) == 0) {
992                                         rot_type = MM_UTIL_ROTATE_270;
993                                 } else {
994                                         rot_type = MM_UTIL_ROTATE_0;
995                                 }
996                         }
997                         thumb_dbg("There is tag rotate : %d", rot_type);
998                 } else {
999                         thumb_dbg("There is NOT tag rotate");
1000                         rot_type = MM_UTIL_ROTATE_0;
1001                         SAFE_FREE(err_msg);
1002                 }
1003
1004                 err = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_CDIS, &cdis_value, NULL);
1005                 if (err != FILEINFO_ERROR_NONE) {
1006                         cdis_value = 0;
1007                         SAFE_FREE(err_msg);
1008                 }
1009
1010         } else {
1011                 rot_type = MM_UTIL_ROTATE_0;
1012                 cdis_value = 0;
1013         }
1014
1015         err = mm_file_destroy_tag_attrs(tag);
1016         if (err != FILEINFO_ERROR_NONE) {
1017                 thumb_err("fail to free tag attr - err(%x)", err);
1018         }
1019
1020         if (cdis_value == 1) {
1021                 thumb_warn("This is CDIS vlaue 1");
1022                 err = mm_file_create_content_attrs_safe(&content, origin_path);
1023         } else {
1024                 err = mm_file_create_content_attrs(&content, origin_path);
1025         }
1026
1027         if (err != FILEINFO_ERROR_NONE) {
1028                 thumb_err("mm_file_create_content_attrs fails : %d", err);
1029                 return MS_MEDIA_ERR_INTERNAL;
1030         }
1031
1032         err = mm_file_get_attrs(content, &err_msg, MM_FILE_CONTENT_VIDEO_TRACK_COUNT, &video_track_num, NULL);
1033         if (err != FILEINFO_ERROR_NONE) {
1034                 thumb_err("mm_file_get_attrs fails : %s", err_msg);
1035                 SAFE_FREE(err_msg);
1036                 mm_file_destroy_content_attrs(content);
1037                 return MS_MEDIA_ERR_INTERNAL;
1038         }
1039
1040         /* MMF api handle both normal and DRM video */
1041         if (video_track_num > 0 || is_drm) {
1042                 err = mm_file_get_attrs(content, &err_msg,
1043                                         MM_FILE_CONTENT_VIDEO_WIDTH,
1044                                         &width,
1045                                         MM_FILE_CONTENT_VIDEO_HEIGHT,
1046                                         &height,
1047                                         MM_FILE_CONTENT_VIDEO_THUMBNAIL, &frame, /* raw image is RGB888 format */
1048                                         &size, NULL);
1049
1050                 if (err != FILEINFO_ERROR_NONE) {
1051                         thumb_err("mm_file_get_attrs fails : %s", err_msg);
1052                         SAFE_FREE(err_msg);
1053                         mm_file_destroy_content_attrs(content);
1054                         return MS_MEDIA_ERR_INTERNAL;
1055                 }
1056
1057                 thumb_dbg("video width: %d", width);
1058                 thumb_dbg("video height: %d", height);
1059                 thumb_dbg("thumbnail size: %d", size);
1060                 thumb_dbg("frame: %p", frame);
1061                 thumb_dbg("orientation: %d", rot_type);
1062
1063                 if (frame == NULL || width == 0 || height == 0) {
1064                         thumb_err("Failed to get frame data");
1065                         mm_file_destroy_content_attrs(content);
1066                         return MS_MEDIA_ERR_INTERNAL;
1067                 }
1068
1069                 thumb_info->origin_width = width;
1070                 thumb_info->origin_height = height;
1071
1072                 err = _media_thumb_get_proper_thumb_size(width, height, &thumb_width, &thumb_height);
1073
1074                 unsigned int new_size = 0;
1075                 unsigned char *new_frame = NULL;
1076                 err = _media_thumb_rgb_to_argb(frame, size, &new_frame, &new_size, width, height);
1077                 if ((err != MS_MEDIA_ERR_NONE) || (new_frame == NULL)) {
1078                         thumb_err("_media_thumb_convert_video falied: %d", err);
1079                         mm_file_destroy_content_attrs(content);
1080                         SAFE_FREE(new_frame);
1081                         return err;
1082                 }
1083                 mm_file_destroy_content_attrs(content);
1084                 thumb_dbg("original size - width:%d, height:%d", width, height);
1085                 thumb_dbg("proper thumb size - width:%d, height:%d", thumb_width, thumb_height);
1086                 if (width > thumb_width || height > thumb_height) {
1087                         err = _media_thumb_resize_with_evas(new_frame, thumb_width, thumb_height, thumb_info);
1088                         if (err != MS_MEDIA_ERR_NONE) {
1089                                 thumb_err("_media_thumb_resize_video_with_evas falied: %d", err);
1090                                 SAFE_FREE(new_frame);
1091                                 return err;
1092                         }
1093                 } else {
1094                         thumb_info->size = new_size;
1095                         thumb_info->width = width;
1096                         thumb_info->height = height;
1097                         thumb_info->data = malloc(new_size);
1098                         if (thumb_info->data == NULL) {
1099                                 thumb_err("memory allcation failed");
1100                                 SAFE_FREE(new_frame);
1101                                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
1102                         }
1103                         memcpy(thumb_info->data, new_frame, new_size);
1104                 }
1105                 SAFE_FREE(new_frame);
1106
1107                 if (rot_type == MM_UTIL_ROTATE_90 || rot_type == MM_UTIL_ROTATE_180 || rot_type == MM_UTIL_ROTATE_270) {
1108                         err = _media_thumb_rotate_thumb(thumb_info->data, thumb_info->size, &(thumb_info->width), &(thumb_info->height), rot_type, MM_UTIL_JPEG_FMT_BGRA8888);
1109                         if (err != MS_MEDIA_ERR_NONE) {
1110                                 thumb_err("_media_thumb_rotate_thumb falied: %d", err);
1111                                 SAFE_FREE(thumb_info->data);
1112                                 return err;
1113                         }
1114                 }
1115         } else {
1116                 thumb_dbg("no contents information");
1117                 frame = NULL;
1118                 mm_file_destroy_content_attrs(content);
1119
1120                 return MS_MEDIA_ERR_INTERNAL;
1121         }
1122
1123         return err;
1124 }
1125
1126 int _media_thumb_get_hash_name(const char *file_full_path, char *thumb_hash_path, size_t max_thumb_path, uid_t uid)
1127 {
1128         char *hash_name = NULL;
1129         /*char *thumb_dir = NULL;*/
1130         char file_ext[255] = { 0 };
1131         char *get_path = NULL;
1132         int ret_len = 0;
1133         ms_user_storage_type_t store_type = -1;
1134         int ret = MS_MEDIA_ERR_NONE;
1135
1136         if (file_full_path == NULL || thumb_hash_path == NULL || max_thumb_path <= 0) {
1137                 thumb_err("file_full_path==NULL || thumb_hash_path == NULL || max_thumb_path <= 0");
1138                 return MS_MEDIA_ERR_INVALID_PARAMETER;
1139         }
1140
1141         _media_thumb_get_file_ext(file_full_path, file_ext, sizeof(file_ext));
1142
1143         ret = ms_user_get_storage_type(uid, file_full_path, &store_type);
1144         if((ret != MS_MEDIA_ERR_NONE) || ((store_type != MS_USER_STORAGE_INTERNAL) && (store_type != MS_USER_STORAGE_EXTERNAL))) {
1145                 thumb_err_slog("origin path(%s) is invalid. err : [%d] store_type [%d]", file_full_path, ret, store_type);
1146                 return MS_MEDIA_ERR_INVALID_PARAMETER;
1147         }
1148
1149         hash_name = _media_thumb_generate_hash_name(file_full_path);
1150         if (hash_name == NULL) {
1151                 thumb_err("_media_thumb_generate_hash_name fail");
1152                 return MS_MEDIA_ERR_INTERNAL;
1153         }
1154
1155         if (store_type == MS_USER_STORAGE_EXTERNAL) {
1156                 ret = ms_user_get_mmc_thumb_store_path(uid, &get_path);
1157                 if (get_path != NULL)
1158                         ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", get_path, file_ext, hash_name);
1159         } else {
1160                 ret = ms_user_get_default_thumb_store_path(uid, &get_path);
1161                 if (get_path != NULL)
1162                         ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", get_path, file_ext, hash_name);
1163         }
1164
1165         SAFE_FREE(get_path);
1166
1167         if ((ret_len < 0) || (ret_len > (int)max_thumb_path)) {
1168                 thumb_err("invalid hash path ret_len[%d]", ret_len);
1169                 return MS_MEDIA_ERR_INTERNAL;
1170         }
1171         //thumb_dbg("thumb hash : %s", thumb_hash_path);
1172
1173         return MS_MEDIA_ERR_NONE;
1174 }
1175
1176
1177 int _media_thumb_save_to_file_with_evas(unsigned char *data, int w, int h, int alpha, char *thumb_path)
1178 {
1179         Ecore_Evas *ee = ecore_evas_buffer_new(w, h);
1180         if (ee == NULL) {
1181                 thumb_err("ecore_evas_buffer_new failed");
1182                 return MS_MEDIA_ERR_INTERNAL;
1183         }
1184
1185         Evas *evas = ecore_evas_get(ee);
1186         if (evas == NULL) {
1187                 thumb_err("ecore_evas_get failed");
1188                 ecore_evas_free(ee);
1189                 return MS_MEDIA_ERR_INTERNAL;
1190         }
1191
1192         Evas_Object *img = NULL;
1193         img = evas_object_image_add(evas);
1194
1195         if (img == NULL) {
1196                 thumb_err("evas_object_image_add failed");
1197                 ecore_evas_free(ee);
1198                 return MS_MEDIA_ERR_INTERNAL;
1199         }
1200
1201         evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
1202         evas_object_image_size_set(img, w, h);
1203         evas_object_image_fill_set(img, 0, 0, w, h);
1204
1205         if (alpha) evas_object_image_alpha_set(img, 1);
1206
1207         evas_object_image_data_set(img, data);
1208         evas_object_image_data_update_add(img, 0, 0, w, h);
1209
1210         if (evas_object_image_save(img, thumb_path, NULL,       "quality=90 compress=1")) {
1211                 thumb_dbg("evas_object_image_save success");
1212                 ecore_evas_free(ee);
1213
1214                 return MS_MEDIA_ERR_NONE;
1215         } else {
1216                 thumb_err("evas_object_image_save failed");
1217                 ecore_evas_free(ee);
1218                 return MS_MEDIA_ERR_INTERNAL;
1219         }
1220 }