Modify null pointer dereferenced in _media_thumb_get_thumb_path_from_db
[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 /* performance enhanced to make thumbnail */
50 #define THUMB_PERFORMANCE_ENHANCED 1
51
52 int _media_thumb_resize_data(unsigned char *src_data,
53                                                         int src_width,
54                                                         int src_height,
55                                                         mm_util_img_format src_format,
56                                                         media_thumb_info *thumb_info,
57                                                         int dst_width,
58                                                         int dst_height);
59
60 #if THUMB_PERFORMANCE_ENHANCED
61 int _media_thumb_convert_video(const unsigned char *src_data, const int src_size,
62                                                         unsigned char **dst_data,
63                                                         unsigned int *buf_size,
64                                                         int width,
65                                                         int height,
66                                                         mm_util_img_format src_format,
67                                                         mm_util_img_format dst_format)
68 {
69         int err = MS_MEDIA_ERR_NONE;
70
71         thumb_dbg("src format:%d, dst format:%d", src_format, dst_format);
72
73         if (mm_util_get_image_size(dst_format, width, height, buf_size) < 0) {
74                 thumb_err("mm_util_get_image_size failed");
75                 return MS_MEDIA_ERR_INTERNAL;
76         }
77
78         thumb_dbg("mm_util_get_image_size : %d", *buf_size);
79
80         *dst_data = (unsigned char *)malloc(*buf_size);
81
82         if (*dst_data == NULL) {
83                 thumb_err("Failed to allocate memory");
84                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
85         }
86
87         if (src_format == MM_UTIL_IMG_FMT_RGB888 &&
88                 dst_format == MM_UTIL_IMG_FMT_BGRA8888) {
89
90                 int i = 0, j;
91                 for (j = 0; ((j < src_size) && (i < *buf_size)); j += 3) {
92                         (*dst_data)[i++] = (src_data[j + 2]);
93                         (*dst_data)[i++] = (src_data[j + 1]);
94                         (*dst_data)[i++] = (src_data[j]);
95                         (*dst_data)[i++] = 0x0;
96                 }
97
98         } else {
99                 err = mm_util_convert_colorspace(src_data,
100                                                 width,
101                                                 height,
102                                                 src_format,
103                                                 *dst_data,
104                                                 dst_format);
105
106                 if (err < 0) {
107                         thumb_err("Failed to change from rgb888 to argb8888 %d", err);
108                         SAFE_FREE(*dst_data);
109                         return MS_MEDIA_ERR_INTERNAL;
110                 }
111         }
112
113         thumb_dbg("_media_thumb_convert_video success");
114
115         return err;
116 }
117
118 int _media_thumb_resize_video_with_evas(const void *image,
119                                         int thumb_width, int thumb_height,
120                                         media_thumb_info *thumb_info)
121 {
122         Ecore_Evas *resize_img_ee;
123
124         if (image == NULL) {
125                 thumb_err("Invalid parameter");
126                 return MS_MEDIA_ERR_INVALID_PARAMETER;
127         }
128         resize_img_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
129         if (!resize_img_ee) {
130                 thumb_err("ecore_evas_buffer_new failed");
131                 return MS_MEDIA_ERR_INTERNAL;
132         }
133
134         Evas *resize_img_e = ecore_evas_get(resize_img_ee);
135         if (!resize_img_e) {
136                 thumb_err("ecore_evas_get failed");
137                 ecore_evas_free(resize_img_ee);
138                 return MS_MEDIA_ERR_INTERNAL;
139         }
140
141         Evas_Object *source_img = evas_object_image_add(resize_img_e);
142         if (!source_img) {
143                 thumb_err("evas_object_image_add failed");
144                 ecore_evas_free(resize_img_ee);
145                 return MS_MEDIA_ERR_INTERNAL;
146         }
147
148         evas_object_image_size_set(source_img, thumb_info->origin_width, thumb_info->origin_height);
149         evas_object_image_colorspace_set(source_img, EVAS_COLORSPACE_ARGB8888);
150         evas_object_image_fill_set(source_img, 0, 0, thumb_info->origin_width, thumb_info->origin_height);
151         evas_object_image_filled_set(source_img, EINA_TRUE);
152
153         evas_object_image_data_set(source_img, (int *)image);
154         evas_object_image_data_update_add(source_img, 0, 0, thumb_info->origin_width, thumb_info->origin_height);
155
156         if (thumb_info->origin_width * thumb_info->origin_height > THUMB_MAX_ALLOWED_MEM_FOR_THUMB) {
157                 thumb_warn("This is too large image. so this's scale is going to be down");
158                 evas_object_image_load_scale_down_set(source_img, 10);
159         }
160
161         ecore_evas_resize(resize_img_ee, thumb_width, thumb_height);
162
163         evas_object_image_load_size_set(source_img, thumb_width, thumb_height);
164         evas_object_image_fill_set(source_img, 0, 0, thumb_width, thumb_height);
165         evas_object_image_filled_set(source_img, EINA_TRUE);
166
167         evas_object_resize(source_img, thumb_width, thumb_height);
168         evas_object_show(source_img);
169
170         /* Set alpha from original */
171         thumb_info->alpha = evas_object_image_alpha_get(source_img);
172         if (thumb_info->alpha)
173                 ecore_evas_alpha_set(resize_img_ee, EINA_TRUE);
174
175         /* Create target buffer and copy origin resized img to it */
176         Ecore_Evas *target_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
177         if (!target_ee) {
178                 thumb_err("ecore_evas_buffer_new failed");
179                 ecore_evas_free(resize_img_ee);
180                 return MS_MEDIA_ERR_INTERNAL;
181         }
182
183         Evas *target_evas = ecore_evas_get(target_ee);
184         if (!target_evas) {
185                 thumb_err("ecore_evas_get failed");
186                 ecore_evas_free(resize_img_ee);
187                 ecore_evas_free(target_ee);
188                 return MS_MEDIA_ERR_INTERNAL;
189         }
190
191         Evas_Object *ret_image = evas_object_image_add(target_evas);
192         evas_object_image_size_set(ret_image, thumb_width, thumb_height);
193         evas_object_image_fill_set(ret_image, 0, 0, thumb_width, thumb_height);
194         evas_object_image_filled_set(ret_image, EINA_TRUE);
195
196         evas_object_image_data_set(ret_image, (int *)ecore_evas_buffer_pixels_get(resize_img_ee));
197         evas_object_image_data_update_add(ret_image, 0, 0, thumb_width, thumb_height);
198
199         unsigned int buf_size = 0;
200         if (mm_util_get_image_size(MM_UTIL_IMG_FMT_BGRA8888, thumb_width, thumb_height, &buf_size) < 0) {
201                 thumb_err("mm_util_get_image_size failed");
202
203                 ecore_evas_free(resize_img_ee);
204                 ecore_evas_free(target_ee);
205
206                 return MS_MEDIA_ERR_INTERNAL;
207         }
208
209         thumb_info->size = buf_size;
210         thumb_info->width = thumb_width;
211         thumb_info->height = thumb_height;
212         thumb_info->data = malloc(buf_size);
213         if (thumb_info->data == NULL) {
214                 thumb_err("Failed to allocate memory");
215                 ecore_evas_free(resize_img_ee);
216                 ecore_evas_free(target_ee);
217
218                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
219         }
220
221         void *image_data = evas_object_image_data_get(ret_image, EINA_TRUE);
222         if (image_data != NULL) {
223                 memcpy(thumb_info->data, image_data, buf_size);
224         } else {
225                 thumb_err("image_data is NULL. evas_object_image_data_get failed");
226         }
227
228         ecore_evas_free(target_ee);
229         ecore_evas_free(resize_img_ee);
230
231         thumb_dbg("_media_thumb_resize_video_with_evas success");
232
233         return MS_MEDIA_ERR_NONE;
234 }
235
236 int _media_thumb_rotate_argb(unsigned char *source, const unsigned int size, int format, int *ori_width, int *ori_height)
237 {
238         int dpp = 0; /* data per pixel */
239         int x = 0, y = 0;
240         int i = 0;
241         int width = 0, height = 0;
242         unsigned char *temp_buf = NULL;
243
244         if (format == MM_UTIL_JPEG_FMT_BGRA8888) {
245                 dpp = 4;
246         } else if (format == MM_UTIL_JPEG_FMT_RGB888) {
247                 dpp = 3;
248         } else {
249                 thumb_err("Invalid parameter");
250                 return MS_MEDIA_ERR_INVALID_PARAMETER;
251         }
252
253         temp_buf = malloc(size);
254         if (temp_buf == NULL) {
255                 thumb_err("Failed to allocate memory");
256                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
257         }
258         /* initialize */
259         memset(temp_buf, 0x00, size);
260         width = *ori_width;
261         height = *ori_height;
262
263         /* rotate image to 90 degree clockwise */
264         for (y = 0; y < height; y++) {
265                 for (x = 0; x < width; x++) {
266                         for (i = 0; i < dpp; i++) {
267                                 temp_buf[(x * height + (height - y - 1)) * dpp + i] = source[(y * width + x) * dpp + i];
268                         }
269                 }
270         }
271
272         /* copy image from temp buffer to original buffer */
273         memcpy(source, temp_buf, size);
274         SAFE_FREE(temp_buf);
275
276         /* swap width & height due to rotate 90 degree */
277         *ori_width = height;
278         *ori_height = width;
279
280         return MS_MEDIA_ERR_NONE;
281 }
282
283 int _media_thumb_rotate_thumb(unsigned char *data, int size, int *width, int *height, int orientation, int format)
284 {
285         int err = MS_MEDIA_ERR_NONE;
286         int i = 0, count = 0;
287
288         if (orientation == MM_UTIL_ROTATE_90) {
289                 count = 1;
290         } else if (orientation == MM_UTIL_ROTATE_180) {
291                 count = 2;
292         } else if (orientation == MM_UTIL_ROTATE_270) {
293                 count = 3;
294         }
295
296         for (i = 0; i < count; i++) {
297                 err = _media_thumb_rotate_argb(data, size, format, width, height);
298                 if (err != MS_MEDIA_ERR_NONE) {
299                         thumb_err("Failed to rotate video thumbnail %d", err);
300                         return err;
301                 }
302 //              thumb_dbg("[%d rotate] width:%d, height:%d", (i + 1) * 90, thumb_info->width, thumb_info->height);
303         }
304
305         thumb_dbg("_media_thumb_rotate_thumb success");
306         return MS_MEDIA_ERR_NONE;
307 }
308 #endif
309
310 int _media_thumb_get_proper_thumb_size(int orig_w, int orig_h,
311                                                                 int *thumb_w, int *thumb_h)
312 {
313         BOOL portrait = FALSE;
314         double ratio;
315
316         if (orig_w < orig_h) {
317                 portrait = TRUE;
318         }
319
320         /* Set smaller length to default size */
321         if (portrait) {
322                 if (orig_w < *thumb_w)
323                         *thumb_w = orig_w;
324                 ratio = (double)orig_h / (double)orig_w;
325                 *thumb_h = *thumb_w * ratio;
326         } else {
327                 if (orig_h < *thumb_h)
328                         *thumb_h = orig_h;
329                 ratio = (double)orig_w / (double)orig_h;
330                 *thumb_w = *thumb_h * ratio;
331         }
332
333         /** CAUTION :: The width of RGB888 raw data has to be rounded by 8 **/
334         *thumb_w = MEDIA_THUMB_ROUND_UP_8(*thumb_w);
335
336         thumb_dbg("proper thumb w: %d h: %d", *thumb_w, *thumb_h);
337
338         return MS_MEDIA_ERR_NONE;
339 }
340
341 int _media_thumb_get_exif_info(ExifData *ed, char *buf, int max_size, int *value, int ifdtype, long tagtype)
342 {
343         ExifEntry *entry;
344         ExifIfd ifd;
345         ExifTag tag;
346
347         if (ed == NULL) {
348                 return MS_MEDIA_ERR_INVALID_PARAMETER;
349         }
350
351         ifd = ifdtype;
352         tag = tagtype;
353
354         entry = exif_content_get_entry(ed->ifd[ifd], tag);
355         if (entry) {
356                 if (tag == EXIF_TAG_ORIENTATION ||
357                                 tag == EXIF_TAG_PIXEL_X_DIMENSION ||
358                                 tag == EXIF_TAG_PIXEL_Y_DIMENSION) {
359
360                         if (value == NULL) {
361                                 thumb_err("value is NULL");
362                                 return MS_MEDIA_ERR_INVALID_PARAMETER;
363                         }
364
365                         ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
366                         short exif_value = exif_get_short(entry->data, mByteOrder);
367                         *value = (int)exif_value;
368                 } else {
369                         /* Get the contents of the tag in human-readable form */
370                         if (buf == NULL) {
371                                 thumb_err("buf is NULL");
372                                 return MS_MEDIA_ERR_INVALID_PARAMETER;
373                         }
374                         exif_entry_get_value(entry, buf, max_size);
375                         buf[strlen(buf)] = '\0';
376                 }
377         }
378
379         return MS_MEDIA_ERR_NONE;
380 }
381
382 static int _media_thumb_get_data_from_exif(ExifData *ed,
383                                                                                                 void **thumb_data,
384                                                                                                 int *thumb_size,
385                                                                                                 int *thumb_width,
386                                                                                                 int *thumb_height,
387                                                                                                 int *origin_width,
388                                                                                                 int *origin_height)
389 {
390         ExifEntry *entry;
391         ExifIfd ifd;
392         ExifTag tag;
393
394         ExifByteOrder byte_order = exif_data_get_byte_order(ed);
395
396         ifd = EXIF_IFD_1;
397         tag = EXIF_TAG_COMPRESSION;
398
399         entry = exif_content_get_entry(ed->ifd[ifd], tag);
400
401         if (entry) {
402                 /* Get the contents of the tag in human-readable form */
403                 ExifShort value = exif_get_short(entry->data, byte_order);
404                 //thumb_dbg("%s: %d", exif_tag_get_name_in_ifd(tag,ifd), value);
405
406                 if (value == 6) {
407                         thumb_dbg("There's jpeg thumb in this image");
408                 } else {
409                         thumb_dbg("There's NO jpeg thumb in this image");
410                         return MS_MEDIA_ERR_INVALID_PARAMETER;
411                 }
412         } else {
413                 thumb_dbg("entry is NULL");
414                 return MS_MEDIA_ERR_INVALID_PARAMETER;
415         }
416
417         /* copy the real thumbnail data from exif data */
418         if (ed->data && ed->size) {
419                 //thumb_dbg("Size: %d, thumb: 0x%x", ed->size, ed->data);
420                 *thumb_data = (char *)malloc(ed->size);
421
422                 if (*thumb_data == NULL) {
423                         thumb_dbg("malloc failed!");
424                         return MS_MEDIA_ERR_INVALID_PARAMETER;
425                 }
426
427                 memcpy(*thumb_data, (void *)ed->data, ed->size);
428                 *thumb_size = ed->size;
429         } else {
430                 thumb_dbg("data is NULL");
431                 return MS_MEDIA_ERR_INVALID_PARAMETER;
432         }
433
434         /* Get width and height of thumbnail */
435         tag = EXIF_TAG_IMAGE_WIDTH;
436         entry = exif_content_get_entry(ed->ifd[ifd], tag);
437
438         if (entry) {
439                 /* Get the contents of the tag in human-readable form */
440                 char width[10] = {0,};
441                 exif_entry_get_value(entry, width, 10);
442
443                 *thumb_width = atoi(width);
444         } else {
445                 thumb_warn("EXIF_TAG_IMAGE_WIDTH does not exist");
446                 *thumb_width = 0;
447         }
448
449         tag = EXIF_TAG_IMAGE_LENGTH;
450         entry = exif_content_get_entry(ed->ifd[ifd], tag);
451         if (entry) {
452                 /* Get the contents of the tag in human-readable form */
453                 char height[10] = {0, };
454                 exif_entry_get_value(entry, height, 10);
455
456                 *thumb_height = atoi(height);
457         } else {
458                 thumb_warn("EXIF_TAG_IMAGE_LENGTH does not exist");
459                 *thumb_height = 0;
460         }
461
462         thumb_dbg("thumb width : height [%d:%d]", *thumb_width, *thumb_height);
463
464         /* Get width and height of original image from exif */
465         ifd = EXIF_IFD_EXIF;
466         tag = EXIF_TAG_PIXEL_X_DIMENSION;
467         entry = exif_content_get_entry(ed->ifd[ifd], tag);
468
469         if (entry) {
470                 char width[10] = {0,};
471                 exif_entry_get_value(entry, width, 10);
472
473                 *origin_width = atoi(width);
474         } else {
475                 thumb_warn("EXIF_TAG_PIXEL_X_DIMENSION does not exist");
476                 *origin_width = 0;
477         }
478
479         tag = EXIF_TAG_PIXEL_Y_DIMENSION;
480         entry = exif_content_get_entry(ed->ifd[ifd], tag);
481
482         if (entry) {
483                 char height[10] = {0, };
484                 exif_entry_get_value(entry, height, 10);
485
486                 *origin_height = atoi(height);
487         } else {
488                 thumb_warn("EXIF_TAG_PIXEL_Y_DIMENSION does not exist");
489                 *origin_height = 0;
490         }
491
492         return MS_MEDIA_ERR_NONE;
493 }
494
495 int _media_thumb_get_thumb_from_exif(ExifData *ed,
496                                                                 const char *file_full_path,
497                                                                 const char *thumb_path,
498                                                                 int orientation,
499                                                                 int required_width,
500                                                                 int required_height,
501                                                                 media_thumb_info *thumb_info)
502 {
503         int err = MS_MEDIA_ERR_NONE;
504         int size = 0;
505         int thumb_width = 0;
506         int thumb_height = 0;
507         int origin_width = 0;
508         int origin_height = 0;
509         void *thumb = NULL;
510         bool is_rotated = (orientation == ROT_90 || orientation == ROT_180 || orientation == ROT_270) ? TRUE : FALSE;
511         mm_util_jpeg_yuv_data decoded = {0,};
512
513         if (ed == NULL) {
514                 return MS_MEDIA_ERR_INVALID_PARAMETER;
515         }
516
517         err = _media_thumb_get_data_from_exif(ed,
518                                                                                 &thumb,
519                                                                                 &size,
520                                                                                 &thumb_width,
521                                                                                 &thumb_height,
522                                                                                 &origin_width,
523                                                                                 &origin_height);
524
525         if (err != MS_MEDIA_ERR_NONE) {
526                 thumb_err("There is no exif data");
527                 return err;
528         }
529
530         thumb_dbg("thumb width : height [%d:%d]", thumb_width, thumb_height);
531         thumb_dbg("origin width : height [%d:%d]", origin_width, origin_height);
532         thumb_info->origin_height = origin_height;
533         thumb_info->origin_width = origin_width;
534
535         if (thumb_width < required_width) {
536                 thumb_err("Thumb data in exif is too small");
537                 SAFE_FREE(thumb);
538                 return MS_MEDIA_ERR_INVALID_PARAMETER;
539         }
540
541         if (is_rotated) {
542                 err = mm_util_decode_from_jpeg_memory(&decoded, thumb, size, MM_UTIL_JPEG_FMT_RGB888);
543                 SAFE_FREE(thumb);
544                 if (err != MS_MEDIA_ERR_NONE) {
545                         thumb_err("mm_util_decode_from_jpeg_turbo_memory failed : %d", err);
546                         return err;
547                 }
548
549                 thumb_width = decoded.width;
550                 thumb_height = decoded.height;
551
552 #if THUMB_PERFORMANCE_ENHANCED
553                 int rot_type = MM_UTIL_ROTATE_0;
554                 if (orientation == ROT_90) {
555                         rot_type = MM_UTIL_ROTATE_90;
556                 } else if (orientation == ROT_180) {
557                         rot_type = MM_UTIL_ROTATE_180;
558                 } else if (orientation == ROT_270) {
559                         rot_type = MM_UTIL_ROTATE_270;
560                 }
561                 err = _media_thumb_rotate_thumb(decoded.data, decoded.size, &(decoded.width), &(decoded.height), rot_type, MM_UTIL_JPEG_FMT_RGB888);
562                 if (err != MS_MEDIA_ERR_NONE) {
563                         thumb_err("_media_thumb_rotate_thumb falied: %d", err);
564                         SAFE_FREE(thumb_info->data);
565                         return err;
566                 }
567                 //thumb_dbg("Width : %d, Height : %d", decoded.width, decoded.height);
568                 thumb_info->data = decoded.data;
569                 thumb_info->size = decoded.size;
570                 thumb_info->width = decoded.width;
571                 thumb_info->height = decoded.height;
572 #else
573                 /* Start to decode to rotate */
574                 unsigned char *rotated = NULL;
575                 unsigned int r_w = decoded.height;
576                 unsigned int r_h = decoded.width;
577                 unsigned int r_size = 0;
578                 mm_util_img_rotate_type rot_type = MM_UTIL_ROTATE_0;
579
580                 int i, rotate_cnt = 0;
581
582                 rot_type = MM_UTIL_ROTATE_90;
583                 if (orientation == ROT_90) {
584                         rotate_cnt = 1;
585                 } else if (orientation == ROT_180) {
586                         rotate_cnt = 2;
587                 } else if (orientation == ROT_270) {
588                         rotate_cnt = 3;
589                 }
590
591                 for (i = 0; i < rotate_cnt; i++) {
592                         if (i == 1) {
593                                 r_w = decoded.width;
594                                 r_h = decoded.height;
595                         }
596
597                         err = mm_util_get_image_size(MM_UTIL_IMG_FMT_RGB888, r_w, r_h, &r_size);
598                         if (err != MS_MEDIA_ERR_NONE) {
599                                 thumb_err("mm_util_get_image_size failed : %d", err);
600                                 SAFE_FREE(decoded.data);
601                                 return err;
602                         }
603
604                         rotated = (unsigned char *)malloc(r_size);
605                         err = mm_util_rotate_image(decoded.data, decoded.width, decoded.height,
606                                                                                 MM_UTIL_IMG_FMT_RGB888,
607                                                                                 rotated, &r_w, &r_h,
608                                                                                 rot_type);
609
610                         if (err != MS_MEDIA_ERR_NONE) {
611                                 thumb_err("mm_util_rotate_image failed : %d", err);
612                                 SAFE_FREE(decoded.data);
613                                 SAFE_FREE(rotated);
614                                 return err;
615                         } else {
616                                 thumb_err("mm_util_rotate_image succeed");
617                         }
618
619                         SAFE_FREE(decoded.data);
620                         decoded.data = rotated;
621                         decoded.width = r_w;
622                         decoded.height = r_h;
623                 }
624
625                 //thumb_dbg("Width : %d, Height : %d", r_w, r_h);
626                 thumb_info->data = rotated;
627                 thumb_info->size = r_size;
628                 thumb_info->width = r_w;
629                 thumb_info->height = r_h;
630 #endif
631         } else {
632                 /*in this case, just write raw data in file */
633                 thumb_dbg_slog("Thumb is :%s", thumb_path);
634
635                 int nwrite;
636                 int fd = open(thumb_path, O_RDWR | O_CREAT | O_EXCL | O_SYNC, 0644);
637                 if (fd < 0) {
638                         if (errno == EEXIST) {
639                                 thumb_err("thumb alread exist!");
640                         } else {
641                                 thumb_err("open failed");
642                                 SAFE_FREE(thumb);
643                                 return MS_MEDIA_ERR_INVALID_PARAMETER;
644                         }
645                 } else {
646                         nwrite = write(fd, thumb, size);
647                         if (nwrite < 0) {
648                                 thumb_err("write failed");
649                                 close(fd);
650
651                                 SAFE_FREE(thumb);
652                                 return MS_MEDIA_ERR_INVALID_PARAMETER;
653                         }
654                         close(fd);
655                 }
656
657                 SAFE_FREE(thumb);
658                 thumb_info->data = NULL;
659                 thumb_info->size = size;
660                 thumb_info->width = thumb_width;
661                 thumb_info->height = thumb_height;
662                 thumb_info->is_saved = TRUE;
663         }
664
665         return err;
666 }
667
668 int _media_thumb_resize_data(unsigned char *src_data,
669                                                         int src_width,
670                                                         int src_height,
671                                                         mm_util_img_format src_format,
672                                                         media_thumb_info *thumb_info,
673                                                         int dst_width,
674                                                         int dst_height)
675 {
676         int thumb_width = dst_width;
677         int thumb_height = dst_height;
678         unsigned int buf_size = 0;
679
680         if (mm_util_get_image_size(src_format, thumb_width, thumb_height, &buf_size) < 0) {
681                 thumb_err("Failed to get buffer size");
682                 return MS_MEDIA_ERR_INTERNAL;
683         }
684
685         thumb_dbg("mm_util_get_image_size : %d", buf_size);
686
687         unsigned char *dst = (unsigned char *)malloc(buf_size);
688
689         if (dst == NULL) {
690                 thumb_err("malloc fails");
691                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
692         }
693
694         if (mm_util_resize_image((unsigned char *)src_data, src_width,
695                         src_height, src_format,
696                         dst, (unsigned int *)&thumb_width,
697                         (unsigned int *)&thumb_height) < 0) {
698                 thumb_err("Failed to resize the thumbnails");
699
700                 SAFE_FREE(dst);
701
702                 return MS_MEDIA_ERR_INTERNAL;
703         }
704
705         thumb_info->size = buf_size;
706         thumb_info->width = thumb_width;
707         thumb_info->height = thumb_height;
708         thumb_info->data = malloc(buf_size);
709         if (thumb_info->data != NULL) {
710                 memcpy(thumb_info->data, dst, buf_size);
711         } else {
712                 thumb_err("malloc fails");
713                 SAFE_FREE(dst);
714                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
715         }
716         SAFE_FREE(dst);
717
718         return MS_MEDIA_ERR_NONE;
719 }
720
721 int _media_thumb_get_wh_with_evas(const char *origin_path, int *width, int *height)
722 {
723         /* using evas to get w/h */
724         Ecore_Evas *ee = ecore_evas_buffer_new(0, 0);
725         if (!ee) {
726                 thumb_err("ecore_evas_buffer_new fails");
727                 return MS_MEDIA_ERR_INTERNAL;
728         }
729
730         Evas *evas = ecore_evas_get(ee);
731         if (!evas) {
732                 thumb_err("ecore_evas_get fails");
733                 ecore_evas_free(ee);
734                 return MS_MEDIA_ERR_INTERNAL;
735         }
736
737         Evas_Object *image_object = evas_object_image_add(evas);
738         if (!image_object) {
739                 thumb_err("evas_object_image_add fails");
740                 ecore_evas_free(ee);
741                 return MS_MEDIA_ERR_INTERNAL;
742         }
743
744         evas_object_image_file_set(image_object, origin_path, NULL);
745         evas_object_image_size_get(image_object, width, height);
746
747         thumb_dbg("Width:%d, Height:%d", *width, *height);
748
749         ecore_evas_free(ee);
750
751         return MS_MEDIA_ERR_NONE;
752 }
753
754 int _media_thumb_decode_with_evas(const char *origin_path,
755                                         int thumb_width, int thumb_height,
756                                         media_thumb_info *thumb_info, int need_scale, int orientation)
757 {
758         Ecore_Evas *resize_img_ee;
759
760         resize_img_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
761         if (!resize_img_ee) {
762                 thumb_err("ecore_evas_buffer_new failed");
763                 return MS_MEDIA_ERR_INTERNAL;
764         }
765
766         Evas *resize_img_e = ecore_evas_get(resize_img_ee);
767         if (!resize_img_e) {
768                 thumb_err("ecore_evas_get failed");
769                 ecore_evas_free(resize_img_ee);
770                 return MS_MEDIA_ERR_INTERNAL;
771         }
772
773         Evas_Object *source_img = evas_object_image_add(resize_img_e);
774         if (!source_img) {
775                 thumb_err("evas_object_image_add failed");
776                 ecore_evas_free(resize_img_ee);
777                 return MS_MEDIA_ERR_INTERNAL;
778         }
779
780         evas_object_image_file_set(source_img, origin_path, NULL);
781
782         /* Get w/h of original image */
783         int width = 0;
784         int height = 0;
785
786         evas_object_image_size_get(source_img, &width, &height);
787         thumb_info->origin_width = width;
788         thumb_info->origin_height = height;
789         //thumb_dbg("origin width:%d, origin height:%d", width, height);
790
791         if ((need_scale == 1) && (width * height > THUMB_MAX_ALLOWED_MEM_FOR_THUMB)) {
792                 thumb_warn("This is too large image. so this's scale is going to be down");
793                 evas_object_image_load_scale_down_set(source_img, 10);
794         }
795
796         if (orientation != TRANSPOSE)
797                 evas_object_image_load_orientation_set(source_img, 1);
798
799         int rotated_orig_w = 0;
800         int rotated_orig_h = 0;
801
802         if (orientation == ROT_90 || orientation == ROT_270) {
803                 rotated_orig_w = height;
804                 rotated_orig_h = width;
805         } else {
806                 rotated_orig_w = width;
807                 rotated_orig_h = height;
808         }
809         //thumb_dbg("rotated - origin width:%d, origin height:%d", rotated_orig_w, rotated_orig_h);
810
811         int err = MS_MEDIA_ERR_NONE;
812
813         err = _media_thumb_get_proper_thumb_size(rotated_orig_w, rotated_orig_h, &thumb_width, &thumb_height);
814         if (err != MS_MEDIA_ERR_NONE) {
815                 thumb_err("_media_thumb_get_proper_thumb_size failed: %d", err);
816                 ecore_evas_free(resize_img_ee);
817                 return err;
818         }
819
820         ecore_evas_resize(resize_img_ee, thumb_width, thumb_height);
821
822         evas_object_image_load_size_set(source_img, thumb_width, thumb_height);
823         evas_object_image_fill_set(source_img, 0, 0, thumb_width, thumb_height);
824         evas_object_image_filled_set(source_img, 1);
825
826         evas_object_resize(source_img, thumb_width, thumb_height);
827         evas_object_show(source_img);
828
829         /* Set alpha from original */
830         thumb_info->alpha = evas_object_image_alpha_get(source_img);
831         if (thumb_info->alpha) ecore_evas_alpha_set(resize_img_ee, EINA_TRUE);
832
833         /* Create target buffer and copy origin resized img to it */
834         Ecore_Evas *target_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
835         if (!target_ee) {
836                 thumb_err("ecore_evas_buffer_new failed");
837                 ecore_evas_free(resize_img_ee);
838                 return MS_MEDIA_ERR_INTERNAL;
839         }
840
841         Evas *target_evas = ecore_evas_get(target_ee);
842         if (!target_evas) {
843                 thumb_err("ecore_evas_get failed");
844                 ecore_evas_free(resize_img_ee);
845                 ecore_evas_free(target_ee);
846                 return MS_MEDIA_ERR_INTERNAL;
847         }
848
849         Evas_Object *ret_image = evas_object_image_add(target_evas);
850         evas_object_image_size_set(ret_image, thumb_width, thumb_height);
851         evas_object_image_fill_set(ret_image, 0, 0, thumb_width, thumb_height);
852         evas_object_image_filled_set(ret_image, EINA_TRUE);
853
854         evas_object_image_data_set(ret_image, (int *)ecore_evas_buffer_pixels_get(resize_img_ee));
855         evas_object_image_data_update_add(ret_image, 0, 0, thumb_width, thumb_height);
856
857         unsigned int buf_size = 0;
858         if (mm_util_get_image_size(MM_UTIL_IMG_FMT_BGRA8888, thumb_width, thumb_height, &buf_size) < 0) {
859                 thumb_err("mm_util_get_image_size failed");
860
861                 ecore_evas_free(resize_img_ee);
862                 ecore_evas_free(target_ee);
863
864                 return MS_MEDIA_ERR_INTERNAL;
865         }
866         //thumb_dbg("mm_util_get_image_size : %d", buf_size);
867
868         thumb_info->size = buf_size;
869         thumb_info->width = thumb_width;
870         thumb_info->height = thumb_height;
871         thumb_info->data = malloc(buf_size);
872         if (thumb_info->data == NULL) {
873                 thumb_err("Failed to allocate memory");
874                 ecore_evas_free(resize_img_ee);
875                 ecore_evas_free(target_ee);
876
877                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
878         }
879
880         void *image_data = evas_object_image_data_get(ret_image, 1);
881         if (image_data != NULL) {
882                 memcpy(thumb_info->data, image_data, buf_size);
883         } else {
884                 thumb_err("image_data is NULL. evas_object_image_data_get failed");
885         }
886
887         ecore_evas_free(target_ee);
888         ecore_evas_free(resize_img_ee);
889
890         return err;
891 }
892
893 mm_util_img_format _media_thumb_get_format(media_thumb_format src_format)
894 {
895         switch (src_format) {
896         case MEDIA_THUMB_BGRA:
897                 return MM_UTIL_IMG_FMT_BGRA8888;
898         case MEDIA_THUMB_RGB888:
899                 return MM_UTIL_IMG_FMT_RGB888;
900         default:
901                 return MS_MEDIA_ERR_INVALID_PARAMETER;
902         }
903 }
904
905 int _media_thumb_convert_data(media_thumb_info *thumb_info,
906                                                         int thumb_width,
907                                                         int thumb_height,
908                                                         mm_util_img_format src_format,
909                                                         mm_util_img_format dst_format)
910 {
911         int err = MS_MEDIA_ERR_NONE;
912         unsigned int buf_size = 0;
913         unsigned char *src_data = thumb_info->data;
914         unsigned char *dst_data = NULL;
915
916         thumb_dbg("src format:%d, dst format:%d", src_format, dst_format);
917
918         if (mm_util_get_image_size(dst_format, thumb_width, thumb_height, &buf_size) < 0) {
919                 thumb_err("mm_util_get_image_size failed");
920                 return MS_MEDIA_ERR_INTERNAL;
921         }
922
923         thumb_dbg("mm_util_get_image_size : %d", buf_size);
924
925         dst_data = (unsigned char *)malloc(buf_size);
926
927         if (dst_data == NULL) {
928                 thumb_err("Failed to allocate memory");
929                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
930         }
931
932         if (src_format == MM_UTIL_IMG_FMT_RGB888 &&
933                 dst_format == MM_UTIL_IMG_FMT_BGRA8888) {
934
935                 int i = 0, j;
936                 for (j = 0; j < thumb_width * 3 * thumb_height;
937                                 j += 3) {
938                         dst_data[i++] = (src_data[j + 2]);
939                         dst_data[i++] = (src_data[j + 1]);
940                         dst_data[i++] = (src_data[j]);
941                         dst_data[i++] = 0x0;
942                 }
943
944         } else {
945                 err = mm_util_convert_colorspace(src_data,
946                                                 thumb_width,
947                                                 thumb_height,
948                                                 src_format,
949                                                 dst_data,
950                                                 dst_format);
951
952                 if (err < 0) {
953                         thumb_err("Failed to change from rgb888 to argb8888 %d", err);
954                         SAFE_FREE(dst_data);
955                         return MS_MEDIA_ERR_INTERNAL;
956                 }
957         }
958
959         SAFE_FREE(thumb_info->data);
960         thumb_info->data = dst_data;
961         thumb_info->size = buf_size;
962
963         thumb_dbg("_media_thumb_convert_data success");
964
965         return err;
966 }
967
968 int _media_thumb_convert_format(media_thumb_info *thumb_info,
969                                                         media_thumb_format src_format,
970                                                         media_thumb_format dst_format)
971 {
972         int err = MS_MEDIA_ERR_NONE;
973
974         if (src_format == dst_format) {
975                 //thumb_dbg("src_format == dst_format");
976                 return err;
977         }
978
979         mm_util_img_format src_mm_format;
980         mm_util_img_format dst_mm_format;
981
982         src_mm_format = _media_thumb_get_format(src_format);
983         dst_mm_format = _media_thumb_get_format(dst_format);
984
985         if ((int)src_mm_format == -1 || (int)dst_mm_format == -1) {
986                 thumb_err("Format is invalid");
987                 return MS_MEDIA_ERR_INVALID_PARAMETER;
988         }
989
990         err = _media_thumb_convert_data(thumb_info,
991                                         thumb_info->width,
992                                         thumb_info->height,
993                                         src_mm_format,
994                                         dst_mm_format);
995
996         if (err != MS_MEDIA_ERR_NONE) {
997                 thumb_err("media_thumb_convert_format failed : %d", err);
998                 return err;
999         }
1000
1001         return err;
1002 }
1003
1004 int _media_thumb_agif(const char *origin_path,
1005                                         int image_width,
1006                                         int image_height,
1007                                         int thumb_width,
1008                                         int thumb_height,
1009                                         media_thumb_format format,
1010                                         media_thumb_info *thumb_info)
1011 {
1012         int err = MS_MEDIA_ERR_NONE;
1013         unsigned int *thumb = NULL;
1014
1015         thumb = ImgGetFirstFrameAGIFAtSize(origin_path, image_width, image_height);
1016
1017         if (!thumb) {
1018                 thumb_err("Frame data is NULL!!");
1019                 return MS_MEDIA_ERR_INTERNAL;
1020         }
1021
1022         err = _media_thumb_get_proper_thumb_size(thumb_info->origin_width, thumb_info->origin_height, &thumb_width, &thumb_height);
1023         if (err != MS_MEDIA_ERR_NONE) {
1024                 thumb_err("_media_thumb_get_proper_thumb_size failed: %d", err);
1025                 SAFE_FREE(thumb);
1026                 return err;
1027         }
1028
1029         err = _media_thumb_resize_data((unsigned char *)thumb,
1030                                                                         image_width,
1031                                                                         image_height,
1032                                                                         MM_UTIL_IMG_FMT_RGB888,
1033                                                                         thumb_info,
1034                                                                         thumb_width,
1035                                                                         thumb_height);
1036
1037         if (err != MS_MEDIA_ERR_NONE) {
1038                 thumb_err("_media_thumb_resize_data failed: %d", err);
1039                 SAFE_FREE(thumb);
1040                 return err;
1041         }
1042
1043         SAFE_FREE(thumb);
1044
1045         err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_RGB888, format);
1046         if (err != MS_MEDIA_ERR_NONE) {
1047                 thumb_err("_media_thumb_convert_format falied: %d", err);
1048                 SAFE_FREE(thumb_info->data);
1049                 return err;
1050         }
1051
1052         return err;
1053 }
1054
1055 int _media_thumb_png(const char *origin_path,
1056                                         int thumb_width,
1057                                         int thumb_height,
1058                                         media_thumb_format format,
1059                                         media_thumb_info *thumb_info)
1060 {
1061         int err = MS_MEDIA_ERR_NONE;
1062         err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
1063
1064         if (err != MS_MEDIA_ERR_NONE) {
1065                 thumb_err("decode_with_evas failed : %d", err);
1066                 return err;
1067         }
1068
1069         err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
1070         if (err != MS_MEDIA_ERR_NONE) {
1071                 thumb_err("_media_thumb_convert_format falied: %d", err);
1072                 SAFE_FREE(thumb_info->data);
1073                 return err;
1074         }
1075
1076         return err;
1077 }
1078
1079 int _media_thumb_bmp(const char *origin_path,
1080                                         int thumb_width,
1081                                         int thumb_height,
1082                                         media_thumb_format format,
1083                                         media_thumb_info *thumb_info)
1084 {
1085         int err = MS_MEDIA_ERR_NONE;
1086         err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
1087
1088         if (err != MS_MEDIA_ERR_NONE) {
1089                 thumb_err("decode_with_evas failed : %d", err);
1090                 return err;
1091         }
1092
1093         err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
1094         if (err != MS_MEDIA_ERR_NONE) {
1095                 thumb_err("_media_thumb_convert_format falied: %d", err);
1096                 SAFE_FREE(thumb_info->data);
1097                 return err;
1098         }
1099
1100         return err;
1101 }
1102
1103 int _media_thumb_wbmp(const char *origin_path,
1104                                         int thumb_width,
1105                                         int thumb_height,
1106                                         media_thumb_format format,
1107                                         media_thumb_info *thumb_info)
1108 {
1109         int err = MS_MEDIA_ERR_NONE;
1110         err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
1111
1112         if (err != MS_MEDIA_ERR_NONE) {
1113                 thumb_err("decode_with_evas failed : %d", err);
1114                 return err;
1115         }
1116
1117         err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
1118         if (err != MS_MEDIA_ERR_NONE) {
1119                 thumb_err("_media_thumb_convert_format falied: %d", err);
1120                 SAFE_FREE(thumb_info->data);
1121                 return err;
1122         }
1123
1124         return err;
1125 }
1126
1127 int _media_thumb_gif(const char *origin_path,
1128                                         int thumb_width,
1129                                         int thumb_height,
1130                                         media_thumb_format format,
1131                                         media_thumb_info *thumb_info)
1132 {
1133         int err = MS_MEDIA_ERR_NONE;
1134         err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
1135
1136         if (err != MS_MEDIA_ERR_NONE) {
1137                 thumb_err("decode_with_evas failed : %d", err);
1138                 return err;
1139         }
1140
1141         err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
1142         if (err != MS_MEDIA_ERR_NONE) {
1143                 thumb_err("_media_thumb_convert_format falied: %d", err);
1144                 SAFE_FREE(thumb_info->data);
1145                 return err;
1146         }
1147
1148         return err;
1149 }
1150
1151 int _media_thumb_jpeg(const char *origin_path,
1152                                         const char *thumb_path,
1153                                         int thumb_width,
1154                                         int thumb_height,
1155                                         media_thumb_format format,
1156                                         media_thumb_info *thumb_info)
1157 {
1158         int err = MS_MEDIA_ERR_NONE;
1159         int thumb_done = 0;
1160         int orientation = NORMAL;
1161         ExifData *ed = NULL;
1162
1163         if (!thumb_info->is_raw) {
1164                 /* Load an ExifData object from an EXIF file */
1165                 ed = exif_data_new_from_file(origin_path);
1166
1167                 if (ed) {
1168                         /* First, Get orientation from exif */
1169                         err = _media_thumb_get_exif_info(ed, NULL, 0, &orientation, EXIF_IFD_0, EXIF_TAG_ORIENTATION);
1170
1171                         if (err != MS_MEDIA_ERR_NONE) {
1172                                 thumb_warn("_media_thumb_get_exif_info failed");
1173                         }
1174
1175                         /* Second, Get thumb from exif */
1176                         err = _media_thumb_get_thumb_from_exif(ed, origin_path, thumb_path, orientation, thumb_width, thumb_height, thumb_info);
1177
1178                         if (err != MS_MEDIA_ERR_NONE) {
1179                                 thumb_dbg("_media_thumb_get_thumb_from_exif failed");
1180                         } else {
1181                                 thumb_done = 1;
1182                                 thumb_dbg("_media_thumb_get_thumb_from_exif succeed");
1183
1184                                 /* The case that original image's size is not in exif header. Use evas to get w/h */
1185                                 if (thumb_info->origin_width == 0 || thumb_info->origin_height == 0) {
1186                                         thumb_warn("original image's size is not in exif header. Use evas to get w/h");
1187                                         err = _media_thumb_get_wh_with_evas(origin_path, &(thumb_info->origin_width), &(thumb_info->origin_height));
1188                                         if (err != MS_MEDIA_ERR_NONE) {
1189                                                 thumb_err("Couldn't get w/h using evas : %s", origin_path);
1190                                         } else {
1191                                                 thumb_dbg("origin w : %d, origin h : %d", thumb_info->origin_width, thumb_info->origin_height);
1192                                         }
1193                                 }
1194
1195                                 if (thumb_info->is_saved == FALSE) {
1196                                         mm_util_img_format dst_format = _media_thumb_get_format(format);
1197
1198                                         err = _media_thumb_convert_data(thumb_info,
1199                                                                         thumb_info->width,
1200                                                                         thumb_info->height,
1201                                                                         MM_UTIL_IMG_FMT_RGB888,
1202                                                                         dst_format);
1203
1204                                         if (err != MS_MEDIA_ERR_NONE) {
1205                                                 thumb_err("_media_thumb_convert_data failed : %d", err);
1206                                                 exif_data_unref(ed);
1207                                                 return err;
1208                                         }
1209                                 }
1210                         }
1211
1212                         exif_data_unref(ed);
1213                 }
1214         } else {
1215                 ed = exif_data_new_from_file(origin_path);
1216                 if (ed) {
1217                         err = _media_thumb_get_exif_info(ed, NULL, 0, &orientation, EXIF_IFD_0, EXIF_TAG_ORIENTATION);
1218                         if (err != MS_MEDIA_ERR_NONE) {
1219                                 thumb_warn("_media_thumb_get_exif_info failed");
1220                         }
1221                         exif_data_unref(ed);
1222                 }
1223         }
1224
1225         if (!thumb_done) {
1226                 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, orientation);
1227
1228                 if (err != MS_MEDIA_ERR_NONE) {
1229                         thumb_err("decode_with_evas failed : %d", err);
1230                         return err;
1231                 }
1232
1233                 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
1234                 if (err != MS_MEDIA_ERR_NONE) {
1235                         thumb_err("_media_thumb_convert_format falied: %d", err);
1236                         SAFE_FREE(thumb_info->data);
1237                         return err;
1238                 }
1239         }
1240
1241         return err;
1242 }
1243
1244 int _media_thumb_image(const char *origin_path,
1245                                         const char *thumb_path,
1246                                         int thumb_width,
1247                                         int thumb_height,
1248                                         media_thumb_format format,
1249                                         media_thumb_info *thumb_info)
1250 {
1251         int err = MS_MEDIA_ERR_NONE;
1252         ImgCodecType image_type = 0;
1253         unsigned int origin_w = 0;
1254         unsigned int origin_h = 0;
1255
1256         err = ImgGetImageInfoForThumb(origin_path, &image_type, &origin_w, &origin_h);
1257
1258         if (err != MS_MEDIA_ERR_NONE) {
1259                 thumb_warn("Getting image info is failed err: %d", err);
1260         }
1261
1262         thumb_info->origin_width = origin_w;
1263         thumb_info->origin_height = origin_h;
1264
1265         if ((image_type != IMG_CODEC_JPEG) &&
1266                 (origin_w * origin_h > THUMB_MAX_ALLOWED_MEM_FOR_THUMB)) {
1267                 thumb_warn("This original image is too big");
1268                 return MS_MEDIA_ERR_THUMB_TOO_BIG;
1269         }
1270
1271         if (image_type == IMG_CODEC_AGIF) {
1272                 err = _media_thumb_agif(origin_path, origin_w, origin_h, thumb_width, thumb_height, format, thumb_info);
1273         } else if (image_type == IMG_CODEC_JPEG) {
1274                 err = _media_thumb_jpeg(origin_path, thumb_path, thumb_width, thumb_height, format, thumb_info);
1275         } else if (image_type == IMG_CODEC_PNG) {
1276                 err = _media_thumb_png(origin_path, thumb_width, thumb_height, format, thumb_info);
1277         } else if (image_type == IMG_CODEC_GIF) {
1278                 err = _media_thumb_gif(origin_path, thumb_width, thumb_height, format, thumb_info);
1279         } else if (image_type == IMG_CODEC_BMP) {
1280                 err = _media_thumb_bmp(origin_path, thumb_width, thumb_height, format, thumb_info);
1281         } else {
1282                 char file_ext[10];
1283                 err = _media_thumb_get_file_ext(origin_path, file_ext, sizeof(file_ext));
1284                 if (err != MS_MEDIA_ERR_NONE) {
1285                         thumb_warn("_media_thumb_get_file_ext failed");
1286                 } else {
1287                         if (strcasecmp(file_ext, "wbmp") == 0) {
1288                                 image_type = IMG_CODEC_WBMP;
1289                                 int wbmp_width = 0;
1290                                 int wbmp_height = 0;
1291
1292                                 err = _media_thumb_get_wh_with_evas(origin_path, &wbmp_width, &wbmp_height);
1293                                 if (err != MS_MEDIA_ERR_NONE) {
1294                                         thumb_err("_media_thumb_get_wh_with_evas in WBMP : %d", err);
1295                                         return err;
1296                                 }
1297
1298                                 if (wbmp_width * wbmp_height > THUMB_MAX_ALLOWED_MEM_FOR_THUMB) {
1299                                         thumb_warn("This original image is too big");
1300                                         return MS_MEDIA_ERR_THUMB_TOO_BIG;
1301                                 }
1302
1303                                 thumb_info->origin_width = wbmp_width;
1304                                 thumb_info->origin_height = wbmp_height;
1305
1306                                 err = _media_thumb_wbmp(origin_path, thumb_width, thumb_height, format, thumb_info);
1307
1308                                 return err;
1309                         }
1310                 }
1311
1312                 thumb_warn("Unsupported image type");
1313                 return MS_MEDIA_ERR_THUMB_UNSUPPORTED;
1314         }
1315
1316         return err;
1317 }
1318
1319 int _media_thumb_video(const char *origin_path,
1320                                         int thumb_width,
1321                                         int thumb_height,
1322                                         media_thumb_format format,
1323                                         media_thumb_info *thumb_info)
1324 {
1325         int err = MS_MEDIA_ERR_NONE;
1326
1327         MMHandleType content = (MMHandleType) NULL;
1328         void *frame = NULL;
1329         int video_track_num = 0;
1330         char *err_msg = NULL;
1331         int is_drm = 0;
1332         int size = 0;
1333         int width = 0;
1334         int height = 0;
1335         bool drm_type = FALSE;
1336
1337         is_drm = drm_type;
1338
1339         /* Get Content Tag attribute for orientatin */
1340         MMHandleType tag = (MMHandleType) NULL;
1341         char *p = NULL;
1342         int cdis_value = 0;
1343         err = mm_file_create_tag_attrs(&tag, origin_path);
1344         mm_util_img_rotate_type rot_type = MM_UTIL_ROTATE_0;
1345
1346         if (err == FILEINFO_ERROR_NONE) {
1347                 err = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_ROTATE, &p, &size, NULL);
1348                 if (err == FILEINFO_ERROR_NONE && size >= 0) {
1349                         if (p == NULL) {
1350                                 rot_type = MM_UTIL_ROTATE_0;
1351                         } else {
1352                                 if (strncmp(p, "90", size) == 0) {
1353                                         rot_type = MM_UTIL_ROTATE_90;
1354                                 } else if (strncmp(p, "180", size) == 0) {
1355                                         rot_type = MM_UTIL_ROTATE_180;
1356                                 } else if (strncmp(p, "270", size) == 0) {
1357                                         rot_type = MM_UTIL_ROTATE_270;
1358                                 } else {
1359                                         rot_type = MM_UTIL_ROTATE_0;
1360                                 }
1361                         }
1362                         thumb_dbg("There is tag rotate : %d", rot_type);
1363                 } else {
1364                         thumb_dbg("There is NOT tag rotate");
1365                         rot_type = MM_UTIL_ROTATE_0;
1366                         SAFE_FREE(err_msg);
1367                 }
1368
1369                 err = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_CDIS, &cdis_value, NULL);
1370                 if (err != FILEINFO_ERROR_NONE) {
1371                         cdis_value = 0;
1372                         SAFE_FREE(err_msg);
1373                 }
1374
1375         } else {
1376                 rot_type = MM_UTIL_ROTATE_0;
1377                 cdis_value = 0;
1378         }
1379
1380         err = mm_file_destroy_tag_attrs(tag);
1381         if (err != FILEINFO_ERROR_NONE) {
1382                 thumb_err("fail to free tag attr - err(%x)", err);
1383         }
1384
1385         if (cdis_value == 1) {
1386                 thumb_warn("This is CDIS vlaue 1");
1387                 err = mm_file_create_content_attrs_safe(&content, origin_path);
1388         } else {
1389                 err = mm_file_create_content_attrs(&content, origin_path);
1390         }
1391
1392         if (err != FILEINFO_ERROR_NONE) {
1393                 thumb_err("mm_file_create_content_attrs fails : %d", err);
1394                 return MS_MEDIA_ERR_INTERNAL;
1395         }
1396
1397         err = mm_file_get_attrs(content, &err_msg, MM_FILE_CONTENT_VIDEO_TRACK_COUNT, &video_track_num, NULL);
1398         if (err != FILEINFO_ERROR_NONE) {
1399                 thumb_err("mm_file_get_attrs fails : %s", err_msg);
1400                 SAFE_FREE(err_msg);
1401                 mm_file_destroy_content_attrs(content);
1402                 return MS_MEDIA_ERR_INTERNAL;
1403         }
1404
1405         /* MMF api handle both normal and DRM video */
1406         if (video_track_num > 0 || is_drm) {
1407
1408                 err = mm_file_get_attrs(content, &err_msg,
1409                                         MM_FILE_CONTENT_VIDEO_WIDTH,
1410                                         &width,
1411                                         MM_FILE_CONTENT_VIDEO_HEIGHT,
1412                                         &height,
1413                                         MM_FILE_CONTENT_VIDEO_THUMBNAIL, &frame, /* raw image is RGB888 format */
1414                                         &size, NULL);
1415
1416                 if (err != FILEINFO_ERROR_NONE) {
1417                         thumb_err("mm_file_get_attrs fails : %s", err_msg);
1418                         SAFE_FREE(err_msg);
1419                         mm_file_destroy_content_attrs(content);
1420                         return MS_MEDIA_ERR_INTERNAL;
1421                 }
1422
1423                 thumb_dbg("video width: %d", width);
1424                 thumb_dbg("video height: %d", height);
1425                 thumb_dbg("thumbnail size: %d", size);
1426                 thumb_dbg("frame: 0x%x", frame);
1427                 thumb_dbg("orientation: %d", rot_type);
1428
1429                 if (frame == NULL || width == 0 || height == 0) {
1430                         thumb_err("Failed to get frame data");
1431                         mm_file_destroy_content_attrs(content);
1432                         return MS_MEDIA_ERR_INTERNAL;
1433                 }
1434
1435                 thumb_info->origin_width = width;
1436                 thumb_info->origin_height = height;
1437
1438                 err = _media_thumb_get_proper_thumb_size(width, height, &thumb_width, &thumb_height);
1439 #if THUMB_PERFORMANCE_ENHANCED
1440                 unsigned int new_size = 0;
1441                 unsigned char *new_frame = NULL;
1442                 err = _media_thumb_convert_video(frame, size, &new_frame, &new_size, width, height, MM_UTIL_IMG_FMT_RGB888, MM_UTIL_IMG_FMT_BGRA8888);
1443                 if ((err != MS_MEDIA_ERR_NONE) || (new_frame == NULL)) {
1444                         thumb_err("_media_thumb_convert_video falied: %d", err);
1445                         mm_file_destroy_content_attrs(content);
1446                         SAFE_FREE(new_frame);
1447                         return err;
1448                 }
1449                 mm_file_destroy_content_attrs(content);
1450                 thumb_dbg("original size - width:%d, height:%d", width, height);
1451                 thumb_dbg("proper thumb size - width:%d, height:%d", thumb_width, thumb_height);
1452                 if (width > thumb_width || height > thumb_height) {
1453                         err = _media_thumb_resize_video_with_evas(new_frame, thumb_width, thumb_height, thumb_info);
1454                         if (err != MS_MEDIA_ERR_NONE) {
1455                                 thumb_err("_media_thumb_resize_video_with_evas falied: %d", err);
1456                                 SAFE_FREE(new_frame);
1457                                 return err;
1458                         }
1459                 } else {
1460                         thumb_info->size = new_size;
1461                         thumb_info->width = width;
1462                         thumb_info->height = height;
1463                         thumb_info->data = malloc(new_size);
1464                         if (thumb_info->data == NULL) {
1465                                 thumb_err("memory allcation failed");
1466                                 SAFE_FREE(new_frame);
1467                                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
1468                         }
1469                         memcpy(thumb_info->data, new_frame, new_size);
1470                 }
1471                 SAFE_FREE(new_frame);
1472
1473                 if (rot_type == MM_UTIL_ROTATE_90 || rot_type == MM_UTIL_ROTATE_180 || rot_type == MM_UTIL_ROTATE_270) {
1474                         err = _media_thumb_rotate_thumb(thumb_info->data, thumb_info->size, &(thumb_info->width), &(thumb_info->height), rot_type, MM_UTIL_JPEG_FMT_BGRA8888);
1475                         if (err != MS_MEDIA_ERR_NONE) {
1476                                 thumb_err("_media_thumb_rotate_thumb falied: %d", err);
1477                                 SAFE_FREE(thumb_info->data);
1478                                 return err;
1479                         }
1480                 }
1481 #else
1482                 if (width > thumb_width || height > thumb_height) {
1483                         err = _media_thumb_resize_data(frame,
1484                                                                                 width,
1485                                                                                 height,
1486                                                                                 MM_UTIL_IMG_FMT_RGB888,
1487                                                                                 thumb_info,
1488                                                                                 thumb_width,
1489                                                                                 thumb_height);
1490
1491                         if (err != MS_MEDIA_ERR_NONE) {
1492                                 thumb_err("_media_thumb_resize_data failed - %d", err);
1493                                 SAFE_FREE(thumb_info->data);
1494                                 mm_file_destroy_content_attrs(content);
1495                                 return err;
1496                         }
1497                 } else {
1498                         thumb_info->size = size;
1499                         thumb_info->width = width;
1500                         thumb_info->height = height;
1501                         thumb_info->data = malloc(size);
1502                         if (thumb_info->data == NULL) {
1503                                 thumb_err("memory allcation failed");
1504                                 mm_file_destroy_content_attrs(content);
1505                                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
1506                         }
1507                         memcpy(thumb_info->data, frame, size);
1508                 }
1509
1510                 mm_file_destroy_content_attrs(content);
1511                 if (rot_type == MM_UTIL_ROTATE_90 || rot_type == MM_UTIL_ROTATE_180 || rot_type == MM_UTIL_ROTATE_270) {
1512                         /* Start to decode to rotate */
1513                         unsigned char *rotated = NULL;
1514                         unsigned int r_w = thumb_info->height;
1515                         unsigned int r_h = thumb_info->width;
1516                         unsigned int r_size = 0;
1517
1518                         if (rot_type == MM_UTIL_ROTATE_180) {
1519                                 r_w = thumb_info->width;
1520                                 r_h = thumb_info->height;
1521                         }
1522
1523                         err = mm_util_get_image_size(MM_UTIL_IMG_FMT_RGB888, r_w, r_h, &r_size);
1524                         if (err != FILEINFO_ERROR_NONE) {
1525                                 thumb_err("mm_util_get_image_size failed : %d", err);
1526                                 SAFE_FREE(thumb_info->data);
1527                                 return err;
1528                         }
1529
1530                         //thumb_dbg("Size of Rotated : %d", r_size);
1531                         rotated = (unsigned char *)malloc(r_size);
1532                         err = mm_util_rotate_image(thumb_info->data, thumb_info->width, thumb_info->height,
1533                                                                                 MM_UTIL_IMG_FMT_RGB888,
1534                                                                                 rotated, &r_w, &r_h,
1535                                                                                 rot_type);
1536
1537                         if (err != FILEINFO_ERROR_NONE) {
1538                                 thumb_err("mm_util_rotate_image failed : %d", err);
1539                                 SAFE_FREE(thumb_info->data);
1540                                 SAFE_FREE(rotated);
1541                                 return err;
1542                         } else {
1543                                 thumb_dbg("mm_util_rotate_image succeed");
1544                         }
1545
1546                         SAFE_FREE(thumb_info->data);
1547                         thumb_info->data = rotated;
1548                         thumb_info->size = r_size;
1549                         thumb_info->width = r_w;
1550                         thumb_info->height = r_h;
1551                 }
1552                 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_RGB888, format);
1553                 if (err != MS_MEDIA_ERR_NONE) {
1554                         thumb_err("_media_thumb_convert_format falied: %d", err);
1555                         SAFE_FREE(thumb_info->data);
1556                         return err;
1557                 }
1558 #endif
1559         } else {
1560                 thumb_dbg("no contents information");
1561                 frame = NULL;
1562                 mm_file_destroy_content_attrs(content);
1563
1564                 return MS_MEDIA_ERR_INTERNAL;
1565         }
1566
1567         return err;
1568 }
1569
1570 static char* _media_thumb_mmc_get_path(uid_t uid)
1571 {
1572         int ret = 0;
1573         char *result_path = NULL;
1574
1575         ret = tzplatform_set_user(uid);
1576         if (ret != 0) {
1577                 thumb_err("Invalid UID[%d]", uid);
1578                 return NULL;
1579         } else {
1580                 const char *result = tzplatform_mkpath(TZ_USER_SHARE, "media/.thumb/mmc");
1581                 result_path = strndup(result, strlen(result));
1582                 tzplatform_reset_user();
1583         }
1584
1585         return result_path;
1586 }
1587
1588 static char* _media_thumb_phone_get_path(uid_t uid)
1589 {
1590         int ret = 0;
1591         char *result_path = NULL;
1592
1593         ret = tzplatform_set_user(uid);
1594         if (ret != 0) {
1595                 thumb_err("Invalid UID[%d]", uid);
1596                 return NULL;
1597         } else {
1598                 const char *result = tzplatform_mkpath(TZ_USER_SHARE, "media/.thumb/phone");
1599                 result_path = strndup(result, strlen(result));
1600                 tzplatform_reset_user();
1601         }
1602
1603         return result_path;
1604 }
1605
1606 int _media_thumb_get_hash_name(const char *file_full_path,
1607                                  char *thumb_hash_path, size_t max_thumb_path, uid_t uid)
1608 {
1609         char *hash_name = NULL;
1610         /*char *thumb_dir = NULL;*/
1611         char file_ext[255] = { 0 };
1612         char *get_path = NULL;
1613         int ret_len = 0;
1614         media_thumb_store_type store_type = -1;
1615
1616         if (file_full_path == NULL || thumb_hash_path == NULL || max_thumb_path <= 0) {
1617                 thumb_err("file_full_path==NULL || thumb_hash_path == NULL || max_thumb_path <= 0");
1618                 return MS_MEDIA_ERR_INVALID_PARAMETER;
1619         }
1620
1621         _media_thumb_get_file_ext(file_full_path, file_ext, sizeof(file_ext));
1622
1623         store_type = _media_thumb_get_store_type_by_path(file_full_path);
1624         /*if (store_type == THUMB_PHONE) {
1625                 thumb_dir = _media_thumb_phone_get_path(uid);
1626         } else if (store_type == THUMB_MMC) {
1627                 thumb_dir = _media_thumb_mmc_get_path(uid);
1628         } else {
1629                 thumb_dir = _media_thumb_phone_get_path(uid);
1630         }*/
1631
1632         hash_name = _media_thumb_generate_hash_name(file_full_path);
1633         if (hash_name == NULL) {
1634                 thumb_err("_media_thumb_generate_hash_name fail");
1635                 return MS_MEDIA_ERR_INTERNAL;
1636         }
1637
1638         if (store_type == THUMB_PHONE) {
1639                 get_path = _media_thumb_phone_get_path(uid);
1640                 if (get_path != NULL)
1641                         ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", get_path, file_ext, hash_name);
1642         } else if (store_type == THUMB_MMC) {
1643                 get_path = _media_thumb_mmc_get_path(uid);
1644                 if (get_path != NULL)
1645                         ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", get_path, file_ext, hash_name);
1646         } else {
1647                 get_path = _media_thumb_phone_get_path(uid);
1648                 if (get_path != NULL)
1649                         ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", get_path, file_ext, hash_name);
1650         }
1651
1652         SAFE_FREE(get_path);
1653
1654         if ((ret_len < 0) || (ret_len > (int)max_thumb_path)) {
1655                 thumb_err("invalid hash path ret_len[%d]", ret_len);
1656                 return MS_MEDIA_ERR_INTERNAL;
1657         }
1658         //thumb_dbg("thumb hash : %s", thumb_hash_path);
1659
1660         return MS_MEDIA_ERR_NONE;
1661 }
1662
1663
1664 int _media_thumb_save_to_file_with_evas(unsigned char *data,
1665                                                                                         int w,
1666                                                                                         int h,
1667                                                                                         int alpha,
1668                                                                                         char *thumb_path)
1669 {
1670         Ecore_Evas *ee = ecore_evas_buffer_new(w, h);
1671         if (ee == NULL) {
1672                 thumb_err("ecore_evas_buffer_new failed");
1673                 return MS_MEDIA_ERR_INTERNAL;
1674         }
1675
1676         Evas *evas = ecore_evas_get(ee);
1677         if (evas == NULL) {
1678                 thumb_err("ecore_evas_get failed");
1679                 ecore_evas_free(ee);
1680                 return MS_MEDIA_ERR_INTERNAL;
1681         }
1682
1683         Evas_Object *img = NULL;
1684         img = evas_object_image_add(evas);
1685
1686         if (img == NULL) {
1687                 thumb_err("evas_object_image_add failed");
1688                 ecore_evas_free(ee);
1689                 return MS_MEDIA_ERR_INTERNAL;
1690         }
1691
1692         evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
1693         evas_object_image_size_set(img, w, h);
1694         evas_object_image_fill_set(img, 0, 0, w, h);
1695
1696         if (alpha) evas_object_image_alpha_set(img, 1);
1697
1698         evas_object_image_data_set(img, data);
1699         evas_object_image_data_update_add(img, 0, 0, w, h);
1700
1701         if (evas_object_image_save(img, thumb_path, NULL,       "quality=90 compress=1")) {
1702                 thumb_dbg("evas_object_image_save success");
1703                 ecore_evas_free(ee);
1704
1705                 return MS_MEDIA_ERR_NONE;
1706         } else {
1707                 thumb_err("evas_object_image_save failed");
1708                 ecore_evas_free(ee);
1709                 return MS_MEDIA_ERR_INTERNAL;
1710         }
1711 }