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