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