4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hyunjun Ko <zzoon.ko@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include "media-thumb-debug.h"
23 #include "media-thumb-util.h"
24 #include "media-thumb-internal.h"
25 #include "media-thumb-ipc.h"
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"
35 #include <sys/types.h>
42 #include <mm_util_imgp.h>
43 #include <mm_util_jpeg.h>
45 #include <Ecore_Evas.h>
46 #include <libexif/exif-data.h>
50 #include <sys/smack.h>
52 #define GLOBAL_USER 0 //#define tzplatform_getenv(TZ_GLOBAL) //TODO
53 #define MEDIA_THUMB_ROUND_UP_8(num) (((num)+7)&~7)
55 int _media_thumb_resize_data(unsigned char *src_data,
58 mm_util_img_format src_format,
59 media_thumb_info *thumb_info,
63 int _media_thumb_get_proper_thumb_size(int orig_w, int orig_h,
64 int *thumb_w, int *thumb_h)
66 BOOL portrait = FALSE;
69 if (orig_w < orig_h) {
73 /* Set smaller length to default size */
75 if (orig_w < *thumb_w)
77 ratio = (double)orig_h / (double)orig_w;
78 *thumb_h = *thumb_w * ratio;
80 if (orig_h < *thumb_h)
82 ratio = (double)orig_w / (double)orig_h;
83 *thumb_w = *thumb_h * ratio;
86 /** CAUTION :: The width of RGB888 raw data has to be rounded by 8 **/
87 *thumb_w = MEDIA_THUMB_ROUND_UP_8(*thumb_w);
89 thumb_dbg("proper thumb w: %d h: %d", *thumb_w, *thumb_h);
91 return MS_MEDIA_ERR_NONE;
94 int _media_thumb_get_exif_info(ExifData *ed, char *buf, int max_size, int *value,
95 int ifdtype, long tagtype)
102 return MS_MEDIA_ERR_INVALID_PARAMETER;
108 entry = exif_content_get_entry(ed->ifd[ifd], tag);
110 if (tag == EXIF_TAG_ORIENTATION ||
111 tag == EXIF_TAG_PIXEL_X_DIMENSION ||
112 tag == EXIF_TAG_PIXEL_Y_DIMENSION) {
115 thumb_err("value is NULL");
116 return MS_MEDIA_ERR_INVALID_PARAMETER;
119 ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
120 short exif_value = exif_get_short(entry->data, mByteOrder);
121 *value = (int)exif_value;
123 /* Get the contents of the tag in human-readable form */
125 thumb_err("buf is NULL");
126 return MS_MEDIA_ERR_INVALID_PARAMETER;
128 exif_entry_get_value(entry, buf, max_size);
129 buf[strlen(buf)] = '\0';
133 return MS_MEDIA_ERR_NONE;
136 static int _media_thumb_get_data_from_exif(ExifData *ed,
148 ExifByteOrder byte_order = exif_data_get_byte_order(ed);
151 tag = EXIF_TAG_COMPRESSION;
153 entry = exif_content_get_entry(ed->ifd[ifd], tag);
156 /* Get the contents of the tag in human-readable form */
157 ExifShort value = exif_get_short(entry->data, byte_order);
158 //thumb_dbg("%s: %d", exif_tag_get_name_in_ifd(tag,ifd), value);
161 thumb_dbg("There's jpeg thumb in this image");
163 thumb_dbg("There's NO jpeg thumb in this image");
164 return MS_MEDIA_ERR_INVALID_PARAMETER;
167 thumb_dbg("entry is NULL");
168 return MS_MEDIA_ERR_INVALID_PARAMETER;
171 /* copy the real thumbnail data from exif data */
172 if (ed->data && ed->size) {
173 //thumb_dbg("Size: %d, thumb: 0x%x", ed->size, ed->data);
174 *thumb_data = (char *)malloc(ed->size);
176 if (*thumb_data == NULL) {
177 thumb_dbg("malloc failed!");
178 return MS_MEDIA_ERR_INVALID_PARAMETER;
181 memcpy(*thumb_data, (void *)ed->data, ed->size);
182 *thumb_size = ed->size;
184 thumb_dbg("data is NULL");
185 return MS_MEDIA_ERR_INVALID_PARAMETER;
188 /* Get width and height of thumbnail */
189 tag = EXIF_TAG_IMAGE_WIDTH;
190 entry = exif_content_get_entry(ed->ifd[ifd], tag);
193 /* Get the contents of the tag in human-readable form */
194 char width[10] = {0,};
195 exif_entry_get_value(entry,width,10);
197 *thumb_width = atoi(width);
199 thumb_warn("EXIF_TAG_IMAGE_WIDTH does not exist");
203 tag = EXIF_TAG_IMAGE_LENGTH;
204 entry = exif_content_get_entry(ed->ifd[ifd], tag);
206 /* Get the contents of the tag in human-readable form */
207 char height[10] = {0,};
208 exif_entry_get_value(entry,height,10);
210 *thumb_height = atoi(height);
212 thumb_warn("EXIF_TAG_IMAGE_LENGTH does not exist");
216 thumb_dbg("thumb width : height [%d:%d]", *thumb_width, *thumb_height);
218 /* Get width and height of original image from exif */
220 tag = EXIF_TAG_PIXEL_X_DIMENSION;
221 entry = exif_content_get_entry(ed->ifd[ifd], tag);
224 char width[10] = {0,};
225 exif_entry_get_value(entry,width,10);
227 *origin_width = atoi(width);
229 thumb_warn("EXIF_TAG_PIXEL_X_DIMENSION does not exist");
233 tag = EXIF_TAG_PIXEL_Y_DIMENSION;
234 entry = exif_content_get_entry(ed->ifd[ifd], tag);
237 char height[10] = {0,};
238 exif_entry_get_value(entry,height,10);
240 *origin_height = atoi(height);
242 thumb_warn("EXIF_TAG_PIXEL_Y_DIMENSION does not exist");
246 return MS_MEDIA_ERR_NONE;
249 int _media_thumb_get_thumb_from_exif(ExifData *ed,
250 const char *file_full_path,
251 const char *thumb_path,
255 media_thumb_info *thumb_info)
257 int err = MS_MEDIA_ERR_NONE;
260 int thumb_height = 0;
261 int origin_width = 0;
262 int origin_height = 0;
264 bool is_rotated = (orientation == ROT_90 || orientation == ROT_180 || orientation == ROT_270) ? TRUE : FALSE;
265 mm_util_jpeg_yuv_data decoded = {0,};
268 return MS_MEDIA_ERR_INVALID_PARAMETER;
271 err = _media_thumb_get_data_from_exif(ed,
279 if (err != MS_MEDIA_ERR_NONE) {
280 thumb_err("There is no exif data");
284 thumb_dbg("thumb width : height [%d:%d]", thumb_width, thumb_height);
285 thumb_dbg("origin width : height [%d:%d]", origin_width, origin_height);
286 thumb_info->origin_height = origin_height;
287 thumb_info->origin_width = origin_width;
289 if (thumb_width < required_width) {
290 thumb_err("Thumb data in exif is too small");
292 return MS_MEDIA_ERR_INVALID_PARAMETER;
296 err = mm_util_decode_from_jpeg_memory(&decoded, thumb, size, MM_UTIL_JPEG_FMT_RGB888);
298 if (err != MS_MEDIA_ERR_NONE) {
299 thumb_err("mm_util_decode_from_jpeg_turbo_memory failed : %d", err);
303 thumb_width = decoded.width;
304 thumb_height = decoded.height;
307 /* Start to decode to rotate */
308 unsigned char *rotated = NULL;
309 unsigned int r_w = decoded.height;
310 unsigned int r_h = decoded.width;
311 unsigned int r_size = 0;
312 mm_util_img_rotate_type rot_type = MM_UTIL_ROTATE_0;
314 int i, rotate_cnt = 0;
316 rot_type = MM_UTIL_ROTATE_90;
317 if (orientation == ROT_90) {
319 } else if (orientation == ROT_180) {
321 } else if (orientation == ROT_270) {
325 for (i = 0; i < rotate_cnt; i++) {
328 r_h = decoded.height;
331 err = mm_util_get_image_size(MM_UTIL_IMG_FMT_RGB888, r_w, r_h, &r_size);
332 if (err != MS_MEDIA_ERR_NONE) {
333 thumb_err("mm_util_get_image_size failed : %d", err);
334 SAFE_FREE(decoded.data);
338 rotated = (unsigned char *)malloc(r_size);
339 err = mm_util_rotate_image(decoded.data, decoded.width, decoded.height,
340 MM_UTIL_IMG_FMT_RGB888,
344 if (err != MS_MEDIA_ERR_NONE) {
345 thumb_err("mm_util_rotate_image failed : %d", err);
346 SAFE_FREE(decoded.data);
350 thumb_err("mm_util_rotate_image succeed");
353 SAFE_FREE(decoded.data);
354 decoded.data = rotated;
356 decoded.height = r_h;
359 //thumb_dbg("Width : %d, Height : %d", r_w, r_h);
360 thumb_info->data = rotated;
361 thumb_info->size = r_size;
362 thumb_info->width = r_w;
363 thumb_info->height = r_h;
365 thumb_warn("Unknown orientation");
366 SAFE_FREE(decoded.data);
367 return MS_MEDIA_ERR_INVALID_PARAMETER;
370 /*in this case, just write raw data in file */
371 thumb_dbg_slog("Thumb is :%s", thumb_path);
374 int fd = open(thumb_path, O_RDWR | O_CREAT | O_EXCL | O_SYNC, 0644);
376 if (errno == EEXIST) {
377 thumb_err("thumb alread exist!");
379 thumb_err("open failed");
381 return MS_MEDIA_ERR_INVALID_PARAMETER;
384 nwrite = write(fd, thumb, size);
386 thumb_err("write failed");
390 return MS_MEDIA_ERR_INVALID_PARAMETER;
396 thumb_info->data = NULL;
397 thumb_info->size = size;
398 thumb_info->width = thumb_width;
399 thumb_info->height = thumb_height;
400 thumb_info->is_saved = TRUE;
406 int _media_thumb_resize_data(unsigned char *src_data,
409 mm_util_img_format src_format,
410 media_thumb_info *thumb_info,
414 int thumb_width = dst_width;
415 int thumb_height = dst_height;
416 unsigned int buf_size = 0;
418 if (mm_util_get_image_size(src_format, thumb_width, thumb_height, &buf_size) < 0) {
419 thumb_err("Failed to get buffer size");
420 return MS_MEDIA_ERR_INTERNAL;
423 thumb_dbg("mm_util_get_image_size : %d", buf_size);
425 unsigned char *dst = (unsigned char *)malloc(buf_size);
427 if (mm_util_resize_image((unsigned char *)src_data, src_width,
428 src_height, src_format,
429 dst, (unsigned int *)&thumb_width,
430 (unsigned int *)&thumb_height) < 0) {
431 thumb_err("Failed to resize the thumbnails");
435 return MS_MEDIA_ERR_INTERNAL;
438 thumb_info->size = buf_size;
439 thumb_info->width = thumb_width;
440 thumb_info->height = thumb_height;
441 thumb_info->data = malloc(buf_size);
442 if(thumb_info->data != NULL) {
443 memcpy(thumb_info->data, dst, buf_size);
445 thumb_err("malloc fails");
446 return MS_MEDIA_ERR_OUT_OF_MEMORY;
450 return MS_MEDIA_ERR_NONE;
453 int _media_thumb_get_wh_with_evas(const char *origin_path, int *width, int *height)
455 /* using evas to get w/h */
456 Ecore_Evas *ee = ecore_evas_buffer_new(0, 0);
458 thumb_err("ecore_evas_buffer_new fails");
459 return MS_MEDIA_ERR_INTERNAL;
462 Evas *evas = ecore_evas_get(ee);
464 thumb_err("ecore_evas_get fails");
466 return MS_MEDIA_ERR_INTERNAL;
469 Evas_Object *image_object = evas_object_image_add(evas);
471 thumb_err("evas_object_image_add fails");
473 return MS_MEDIA_ERR_INTERNAL;
476 evas_object_image_file_set(image_object, origin_path, NULL);
477 evas_object_image_size_get(image_object, width, height);
479 thumb_dbg("Width:%d, Height:%d", *width, *height);
483 return MS_MEDIA_ERR_NONE;
486 int _media_thumb_decode_with_evas(const char *origin_path,
487 int thumb_width, int thumb_height,
488 media_thumb_info *thumb_info, int need_scale, int orientation)
490 Ecore_Evas *resize_img_ee;
492 resize_img_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
493 if (!resize_img_ee) {
494 thumb_err("ecore_evas_buffer_new failed");
495 return MS_MEDIA_ERR_INTERNAL;
498 Evas *resize_img_e = ecore_evas_get(resize_img_ee);
500 thumb_err("ecore_evas_get failed");
501 ecore_evas_free(resize_img_ee);
502 return MS_MEDIA_ERR_INTERNAL;
505 Evas_Object *source_img = evas_object_image_add(resize_img_e);
507 thumb_err("evas_object_image_add failed");
508 ecore_evas_free(resize_img_ee);
509 return MS_MEDIA_ERR_INTERNAL;
512 evas_object_image_file_set(source_img, origin_path, NULL);
514 /* Get w/h of original image */
518 evas_object_image_size_get(source_img, &width, &height);
519 thumb_info->origin_width = width;
520 thumb_info->origin_height = height;
521 //thumb_dbg("origin width:%d, origin height:%d", width, height);
523 if ((need_scale == 1) && (width * height > THUMB_MAX_ALLOWED_MEM_FOR_THUMB)) {
524 thumb_warn("This is too large image. so this's scale is going to be down");
525 evas_object_image_load_scale_down_set(source_img, 10);
528 if (orientation != TRANSPOSE)
529 evas_object_image_load_orientation_set(source_img, 1);
531 int rotated_orig_w = 0;
532 int rotated_orig_h = 0;
534 if (orientation == ROT_90 || orientation == ROT_270) {
535 rotated_orig_w = height;
536 rotated_orig_h = width;
538 rotated_orig_w = width;
539 rotated_orig_h = height;
541 //thumb_dbg("rotated - origin width:%d, origin height:%d", rotated_orig_w, rotated_orig_h);
543 int err = MS_MEDIA_ERR_NONE;
545 err = _media_thumb_get_proper_thumb_size(rotated_orig_w, rotated_orig_h, &thumb_width, &thumb_height);
546 if (err != MS_MEDIA_ERR_NONE) {
547 thumb_err("_media_thumb_get_proper_thumb_size failed: %d", err);
548 ecore_evas_free(resize_img_ee);
552 ecore_evas_resize(resize_img_ee, thumb_width, thumb_height);
554 evas_object_image_load_size_set(source_img, thumb_width, thumb_height);
555 evas_object_image_fill_set(source_img, 0, 0, thumb_width, thumb_height);
556 evas_object_image_filled_set(source_img, 1);
558 evas_object_resize(source_img, thumb_width, thumb_height);
559 evas_object_show(source_img);
561 /* Set alpha from original */
562 thumb_info->alpha = evas_object_image_alpha_get(source_img);
563 if (thumb_info->alpha) ecore_evas_alpha_set(resize_img_ee, EINA_TRUE);
565 /* Create target buffer and copy origin resized img to it */
566 Ecore_Evas *target_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
568 thumb_err("ecore_evas_buffer_new failed");
569 ecore_evas_free(resize_img_ee);
570 return MS_MEDIA_ERR_INTERNAL;
573 Evas *target_evas = ecore_evas_get(target_ee);
575 thumb_err("ecore_evas_get failed");
576 ecore_evas_free(resize_img_ee);
577 ecore_evas_free(target_ee);
578 return MS_MEDIA_ERR_INTERNAL;
581 Evas_Object *ret_image = evas_object_image_add(target_evas);
582 evas_object_image_size_set(ret_image, thumb_width, thumb_height);
583 evas_object_image_fill_set(ret_image, 0, 0, thumb_width, thumb_height);
584 evas_object_image_filled_set(ret_image, EINA_TRUE);
586 evas_object_image_data_set(ret_image, (int *)ecore_evas_buffer_pixels_get(resize_img_ee));
587 evas_object_image_data_update_add(ret_image, 0, 0, thumb_width, thumb_height);
589 unsigned int buf_size = 0;
590 if (mm_util_get_image_size(MM_UTIL_IMG_FMT_BGRA8888, thumb_width, thumb_height, &buf_size) < 0) {
591 thumb_err("mm_util_get_image_size failed");
593 ecore_evas_free(resize_img_ee);
594 ecore_evas_free(target_ee);
596 return MS_MEDIA_ERR_INTERNAL;
598 //thumb_dbg("mm_util_get_image_size : %d", buf_size);
600 thumb_info->size = buf_size;
601 thumb_info->width = thumb_width;
602 thumb_info->height = thumb_height;
603 thumb_info->data = malloc(buf_size);
604 if (thumb_info->data == NULL) {
605 thumb_err("Failed to allocate memory" );
606 ecore_evas_free(resize_img_ee);
607 ecore_evas_free(target_ee);
609 return MS_MEDIA_ERR_OUT_OF_MEMORY;
612 void *image_data = evas_object_image_data_get(ret_image, 1);
613 if (image_data != NULL) {
614 memcpy(thumb_info->data, image_data, buf_size);
616 thumb_err("image_data is NULL. evas_object_image_data_get failed");
619 ecore_evas_free(target_ee);
620 ecore_evas_free(resize_img_ee);
625 mm_util_img_format _media_thumb_get_format(media_thumb_format src_format)
628 case MEDIA_THUMB_BGRA:
629 return MM_UTIL_IMG_FMT_BGRA8888;
630 case MEDIA_THUMB_RGB888:
631 return MM_UTIL_IMG_FMT_RGB888;
633 return MS_MEDIA_ERR_INVALID_PARAMETER;
637 int _media_thumb_convert_data(media_thumb_info *thumb_info,
640 mm_util_img_format src_format,
641 mm_util_img_format dst_format)
643 int err = MS_MEDIA_ERR_NONE;
644 unsigned int buf_size = 0;
645 unsigned char *src_data = thumb_info->data;
646 unsigned char *dst_data = NULL;
648 thumb_dbg("src format:%d, dst format:%d", src_format, dst_format);
650 if (mm_util_get_image_size(dst_format, thumb_width, thumb_height, &buf_size) < 0) {
651 thumb_err("mm_util_get_image_size failed");
652 return MS_MEDIA_ERR_INTERNAL;
655 thumb_dbg("mm_util_get_image_size : %d", buf_size);
657 dst_data = (unsigned char *)malloc(buf_size);
659 if (dst_data == NULL) {
660 thumb_err("Failed to allocate memory");
661 return MS_MEDIA_ERR_OUT_OF_MEMORY;
664 if (src_format == MM_UTIL_IMG_FMT_RGB888 &&
665 dst_format == MM_UTIL_IMG_FMT_BGRA8888) {
668 for (j = 0; j < thumb_width * 3 * thumb_height;
670 dst_data[i++] = (src_data[j + 2]);
671 dst_data[i++] = (src_data[j + 1]);
672 dst_data[i++] = (src_data[j]);
677 err = mm_util_convert_colorspace(src_data,
685 thumb_err("Failed to change from rgb888 to argb8888 %d", err);
687 return MS_MEDIA_ERR_INTERNAL;
691 SAFE_FREE(thumb_info->data);
692 thumb_info->data = dst_data;
693 thumb_info->size = buf_size;
695 thumb_dbg("_media_thumb_convert_data success");
700 int _media_thumb_convert_format(media_thumb_info *thumb_info,
701 media_thumb_format src_format,
702 media_thumb_format dst_format)
704 int err = MS_MEDIA_ERR_NONE;
706 if (src_format == dst_format) {
707 //thumb_dbg("src_format == dst_format");
711 mm_util_img_format src_mm_format;
712 mm_util_img_format dst_mm_format;
714 src_mm_format = _media_thumb_get_format(src_format);
715 dst_mm_format = _media_thumb_get_format(dst_format);
717 if ((int)src_mm_format == -1 || (int)dst_mm_format == -1) {
718 thumb_err("Format is invalid");
719 return MS_MEDIA_ERR_INVALID_PARAMETER;
722 err = _media_thumb_convert_data(thumb_info,
728 if (err != MS_MEDIA_ERR_NONE) {
729 thumb_err("media_thumb_convert_format failed : %d", err);
736 int _media_thumb_agif(const char *origin_path,
741 media_thumb_format format,
742 media_thumb_info *thumb_info)
744 int err = MS_MEDIA_ERR_NONE;
745 unsigned int *thumb = NULL;
747 thumb = ImgGetFirstFrameAGIFAtSize(origin_path, image_width, image_height);
750 thumb_err("Frame data is NULL!!");
751 return MS_MEDIA_ERR_INTERNAL;
754 err = _media_thumb_get_proper_thumb_size(thumb_info->origin_width, thumb_info->origin_height, &thumb_width, &thumb_height);
755 if (err != MS_MEDIA_ERR_NONE) {
756 thumb_err("_media_thumb_get_proper_thumb_size failed: %d", err);
761 err = _media_thumb_resize_data((unsigned char *)thumb,
764 MM_UTIL_IMG_FMT_RGB888,
769 if (err != MS_MEDIA_ERR_NONE) {
770 thumb_err("_media_thumb_resize_data failed: %d", err);
777 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_RGB888, format);
778 if (err != MS_MEDIA_ERR_NONE) {
779 thumb_err("_media_thumb_convert_format falied: %d", err);
780 SAFE_FREE(thumb_info->data);
787 int _media_thumb_png(const char *origin_path,
790 media_thumb_format format,
791 media_thumb_info *thumb_info)
793 int err = MS_MEDIA_ERR_NONE;
794 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
796 if (err != MS_MEDIA_ERR_NONE) {
797 thumb_err("decode_with_evas failed : %d", err);
801 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
802 if (err != MS_MEDIA_ERR_NONE) {
803 thumb_err("_media_thumb_convert_format falied: %d", err);
804 SAFE_FREE(thumb_info->data);
811 int _media_thumb_bmp(const char *origin_path,
814 media_thumb_format format,
815 media_thumb_info *thumb_info)
817 int err = MS_MEDIA_ERR_NONE;
818 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
820 if (err != MS_MEDIA_ERR_NONE) {
821 thumb_err("decode_with_evas failed : %d", err);
825 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
826 if (err != MS_MEDIA_ERR_NONE) {
827 thumb_err("_media_thumb_convert_format falied: %d", err);
828 SAFE_FREE(thumb_info->data);
835 int _media_thumb_wbmp(const char *origin_path,
838 media_thumb_format format,
839 media_thumb_info *thumb_info)
841 int err = MS_MEDIA_ERR_NONE;
842 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
844 if (err != MS_MEDIA_ERR_NONE) {
845 thumb_err("decode_with_evas failed : %d", err);
849 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
850 if (err != MS_MEDIA_ERR_NONE) {
851 thumb_err("_media_thumb_convert_format falied: %d", err);
852 SAFE_FREE(thumb_info->data);
859 int _media_thumb_gif(const char *origin_path,
862 media_thumb_format format,
863 media_thumb_info *thumb_info)
865 int err = MS_MEDIA_ERR_NONE;
866 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
868 if (err != MS_MEDIA_ERR_NONE) {
869 thumb_err("decode_with_evas failed : %d", err);
873 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
874 if (err != MS_MEDIA_ERR_NONE) {
875 thumb_err("_media_thumb_convert_format falied: %d", err);
876 SAFE_FREE(thumb_info->data);
883 int _media_thumb_jpeg(const char *origin_path,
884 const char *thumb_path,
887 media_thumb_format format,
888 media_thumb_info *thumb_info)
890 int err = MS_MEDIA_ERR_NONE;
893 int orientation = NORMAL;
895 /* Load an ExifData object from an EXIF file */
896 ed = exif_data_new_from_file(origin_path);
899 /* First, Get orientation from exif */
900 err = _media_thumb_get_exif_info(ed, NULL, 0, &orientation, EXIF_IFD_0, EXIF_TAG_ORIENTATION);
902 if (err != MS_MEDIA_ERR_NONE) {
903 thumb_warn("_media_thumb_get_exif_info failed");
906 /* Second, Get thumb from exif */
907 err = _media_thumb_get_thumb_from_exif(ed, origin_path, thumb_path, orientation, thumb_width, thumb_height, thumb_info);
909 if (err != MS_MEDIA_ERR_NONE) {
910 thumb_dbg("_media_thumb_get_thumb_from_exif failed");
913 thumb_dbg("_media_thumb_get_thumb_from_exif succeed");
915 /* The case that original image's size is not in exif header. Use evas to get w/h */
916 if (thumb_info->origin_width == 0 || thumb_info->origin_height == 0) {
917 thumb_warn("original image's size is not in exif header. Use evas to get w/h");
918 err = _media_thumb_get_wh_with_evas(origin_path, &(thumb_info->origin_width), &(thumb_info->origin_height));
919 if (err != MS_MEDIA_ERR_NONE) {
920 thumb_err("Couldn't get w/h using evas : %s", origin_path);
922 thumb_dbg("origin w : %d, origin h : %d", thumb_info->origin_width, thumb_info->origin_height);
926 if (thumb_info->is_saved == FALSE) {
927 mm_util_img_format dst_format = _media_thumb_get_format(format);
929 err = _media_thumb_convert_data(thumb_info,
932 MM_UTIL_IMG_FMT_RGB888,
935 if (err != MS_MEDIA_ERR_NONE) {
936 thumb_err("_media_thumb_convert_data failed : %d", err);
948 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, orientation);
950 if (err != MS_MEDIA_ERR_NONE) {
951 thumb_err("decode_with_evas failed : %d", err);
955 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
956 if (err != MS_MEDIA_ERR_NONE) {
957 thumb_err("_media_thumb_convert_format falied: %d", err);
958 SAFE_FREE(thumb_info->data);
966 int _media_thumb_jpeg_for_raw(const char *origin_path,
967 const char *thumb_path,
970 media_thumb_format format,
971 media_thumb_info *thumb_info)
973 int err = MS_MEDIA_ERR_NONE;
974 int orientation = NORMAL;
976 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, orientation);
978 if (err != MS_MEDIA_ERR_NONE) {
979 thumb_err("decode_with_evas failed : %d", err);
983 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
984 if (err != MS_MEDIA_ERR_NONE) {
985 thumb_err("_media_thumb_convert_format falied: %d", err);
986 SAFE_FREE(thumb_info->data);
992 int _media_thumb_image(const char *origin_path,
993 const char *thumb_path,
996 media_thumb_format format,
997 media_thumb_info *thumb_info,
1000 int err = MS_MEDIA_ERR_NONE;
1001 ImgCodecType image_type = 0;
1002 unsigned int origin_w = 0;
1003 unsigned int origin_h = 0;
1005 err = ImgGetImageInfoForThumb(origin_path, &image_type, &origin_w, &origin_h);
1007 if (err != MS_MEDIA_ERR_NONE){
1008 thumb_warn("Getting image info is failed err: %d", err);
1011 thumb_info->origin_width = origin_w;
1012 thumb_info->origin_height = origin_h;
1014 //thumb_dbg("image type is %d, width:%d, height:%d", image_type, origin_w, origin_h);
1016 if ((image_type != IMG_CODEC_JPEG) &&
1017 (origin_w * origin_h > THUMB_MAX_ALLOWED_MEM_FOR_THUMB)) {
1018 thumb_warn("This original image is too big");
1019 return MS_MEDIA_ERR_THUMB_TOO_BIG;
1022 if (image_type == IMG_CODEC_AGIF) {
1023 err = _media_thumb_agif(origin_path, origin_w, origin_h, thumb_width, thumb_height, format, thumb_info);
1024 } else if (image_type == IMG_CODEC_JPEG) {
1025 if(is_req_raw == TRUE) {
1026 err = _media_thumb_jpeg_for_raw(origin_path, thumb_path, thumb_width, thumb_height, format, thumb_info);
1028 err = _media_thumb_jpeg(origin_path, thumb_path, thumb_width, thumb_height, format, thumb_info);
1030 } else if (image_type == IMG_CODEC_PNG) {
1031 err = _media_thumb_png(origin_path, thumb_width, thumb_height, format, thumb_info);
1032 } else if (image_type == IMG_CODEC_GIF) {
1033 err = _media_thumb_gif(origin_path, thumb_width, thumb_height, format, thumb_info);
1034 } else if (image_type == IMG_CODEC_BMP) {
1035 err = _media_thumb_bmp(origin_path, thumb_width, thumb_height, format, thumb_info);
1038 err = _media_thumb_get_file_ext(origin_path, file_ext, sizeof(file_ext));
1039 if (err != MS_MEDIA_ERR_NONE) {
1040 thumb_warn("_media_thumb_get_file_ext failed");
1042 if (strcasecmp(file_ext, "wbmp") == 0) {
1043 image_type = IMG_CODEC_WBMP;
1045 int wbmp_height = 0;
1047 err = _media_thumb_get_wh_with_evas(origin_path, &wbmp_width, &wbmp_height);
1048 if (err != MS_MEDIA_ERR_NONE) {
1049 thumb_err("_media_thumb_get_wh_with_evas in WBMP : %d", err);
1053 if (wbmp_width * wbmp_height > THUMB_MAX_ALLOWED_MEM_FOR_THUMB) {
1054 thumb_warn("This original image is too big");
1055 return MS_MEDIA_ERR_THUMB_TOO_BIG;
1058 thumb_info->origin_width = wbmp_width;
1059 thumb_info->origin_height = wbmp_height;
1061 err = _media_thumb_wbmp(origin_path, thumb_width, thumb_height, format, thumb_info);
1067 thumb_warn("Unsupported image type");
1068 return MS_MEDIA_ERR_INVALID_PARAMETER;
1074 int _media_thumb_video(const char *origin_path,
1077 media_thumb_format format,
1078 media_thumb_info *thumb_info)
1080 int err = MS_MEDIA_ERR_NONE;
1082 MMHandleType content = (MMHandleType) NULL;
1084 int video_track_num = 0;
1085 char *err_msg = NULL;
1090 bool drm_type = FALSE;
1094 /* Get Content Tag attribute for orientatin */
1095 MMHandleType tag = (MMHandleType) NULL;
1098 err = mm_file_create_tag_attrs(&tag, origin_path);
1099 mm_util_img_rotate_type rot_type = MM_UTIL_ROTATE_0;
1101 if (err == MM_ERROR_NONE) {
1102 err = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_ROTATE, &p, &size, NULL);
1103 if (err == MM_ERROR_NONE && size >= 0) {
1105 rot_type = MM_UTIL_ROTATE_0;
1107 if (strncmp(p, "90", size) == 0) {
1108 rot_type = MM_UTIL_ROTATE_90;
1109 } else if(strncmp(p, "180", size) == 0) {
1110 rot_type = MM_UTIL_ROTATE_180;
1111 } else if(strncmp(p, "270", size) == 0) {
1112 rot_type = MM_UTIL_ROTATE_270;
1114 rot_type = MM_UTIL_ROTATE_0;
1117 thumb_dbg("There is tag rotate : %d", rot_type);
1119 thumb_dbg("There is NOT tag rotate");
1120 rot_type = MM_UTIL_ROTATE_0;
1124 err = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_CDIS, &cdis_value, NULL);
1125 if (err != MM_ERROR_NONE) {
1131 rot_type = MM_UTIL_ROTATE_0;
1135 err = mm_file_destroy_tag_attrs(tag);
1136 if (err != MM_ERROR_NONE) {
1137 thumb_err("fail to free tag attr - err(%x)", err);
1140 if (cdis_value == 1) {
1141 thumb_warn("This is CDIS vlaue 1");
1142 err = mm_file_create_content_attrs_safe(&content, origin_path);
1144 err = mm_file_create_content_attrs(&content, origin_path);
1147 if (err != MM_ERROR_NONE) {
1148 thumb_err("mm_file_create_content_attrs fails : %d", err);
1149 return MS_MEDIA_ERR_INTERNAL;
1152 err = mm_file_get_attrs(content, &err_msg, MM_FILE_CONTENT_VIDEO_TRACK_COUNT, &video_track_num, NULL);
1153 if (err != MM_ERROR_NONE) {
1154 thumb_err("mm_file_get_attrs fails : %s", err_msg);
1156 mm_file_destroy_content_attrs(content);
1157 return MS_MEDIA_ERR_INTERNAL;
1160 /* MMF api handle both normal and DRM video */
1161 if (video_track_num > 0 || is_drm) {
1163 err = mm_file_get_attrs(content, &err_msg,
1164 MM_FILE_CONTENT_VIDEO_WIDTH,
1166 MM_FILE_CONTENT_VIDEO_HEIGHT,
1168 MM_FILE_CONTENT_VIDEO_THUMBNAIL, &frame, /* raw image is RGB888 format */
1171 if (err != MM_ERROR_NONE) {
1172 thumb_err("mm_file_get_attrs fails : %s", err_msg);
1174 mm_file_destroy_content_attrs(content);
1175 return MS_MEDIA_ERR_INTERNAL;
1178 thumb_dbg("video width: %d", width);
1179 thumb_dbg("video height: %d", height);
1180 thumb_dbg("thumbnail size=%d", size);
1181 thumb_dbg("frame = 0x%x", frame);
1183 if (frame == NULL || width == 0 || height == 0) {
1184 thumb_err("Failed to get frame data");
1185 mm_file_destroy_content_attrs(content);
1186 return MS_MEDIA_ERR_INTERNAL;
1189 thumb_info->origin_width = width;
1190 thumb_info->origin_height = height;
1192 err = _media_thumb_get_proper_thumb_size(width, height, &thumb_width, &thumb_height);
1194 if (width > thumb_width || height > thumb_height) {
1195 err = _media_thumb_resize_data(frame,
1198 MM_UTIL_IMG_FMT_RGB888,
1203 if (err != MS_MEDIA_ERR_NONE) {
1204 thumb_err("_media_thumb_resize_data failed - %d", err);
1205 SAFE_FREE(thumb_info->data);
1206 mm_file_destroy_content_attrs(content);
1210 thumb_info->size = size;
1211 thumb_info->width = width;
1212 thumb_info->height = height;
1213 thumb_info->data = malloc(size);
1214 if (thumb_info->data == NULL) {
1215 thumb_err("memory allcation failed" );
1216 mm_file_destroy_content_attrs(content);
1217 return MS_MEDIA_ERR_OUT_OF_MEMORY;
1219 memcpy(thumb_info->data, frame, size);
1222 mm_file_destroy_content_attrs(content);
1223 if (rot_type == MM_UTIL_ROTATE_90 || rot_type == MM_UTIL_ROTATE_180 || rot_type == MM_UTIL_ROTATE_270) {
1224 /* Start to decode to rotate */
1225 unsigned char *rotated = NULL;
1226 unsigned int r_w = thumb_info->height;
1227 unsigned int r_h = thumb_info->width;
1228 unsigned int r_size = 0;
1230 if (rot_type == MM_UTIL_ROTATE_180) {
1231 r_w = thumb_info->width;
1232 r_h = thumb_info->height;
1235 err = mm_util_get_image_size(MM_UTIL_IMG_FMT_RGB888, r_w, r_h, &r_size);
1236 if (err != MM_ERROR_NONE) {
1237 thumb_err("mm_util_get_image_size failed : %d", err);
1238 SAFE_FREE(thumb_info->data);
1242 //thumb_dbg("Size of Rotated : %d", r_size);
1243 rotated = (unsigned char *)malloc(r_size);
1244 err = mm_util_rotate_image(thumb_info->data, thumb_info->width, thumb_info->height,
1245 MM_UTIL_IMG_FMT_RGB888,
1246 rotated, &r_w, &r_h,
1249 if (err != MM_ERROR_NONE) {
1250 thumb_err("mm_util_rotate_image failed : %d", err);
1251 SAFE_FREE(thumb_info->data);
1255 thumb_dbg("mm_util_rotate_image succeed");
1258 SAFE_FREE(thumb_info->data);
1259 thumb_info->data = rotated;
1260 thumb_info->size = r_size;
1261 thumb_info->width = r_w;
1262 thumb_info->height = r_h;
1265 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_RGB888, format);
1266 if (err != MS_MEDIA_ERR_NONE) {
1267 thumb_err("_media_thumb_convert_format falied: %d", err);
1268 SAFE_FREE(thumb_info->data);
1272 thumb_dbg("no contents information");
1274 mm_file_destroy_content_attrs(content);
1276 return MS_MEDIA_ERR_INTERNAL;
1282 static char* _media_thumb_mmc_get_path(uid_t uid)
1284 char *result_psswd = NULL;
1285 struct group *grpinfo = NULL;
1288 result_psswd = strdup(THUMB_MMC_PATH);
1289 grpinfo = getgrnam("users");
1290 if(grpinfo == NULL) {
1291 thumb_err("getgrnam(users) returns NULL !");
1299 struct passwd *userinfo = getpwuid(uid);
1300 if(userinfo == NULL) {
1301 thumb_err("getpwuid(%d) returns NULL !", uid);
1304 grpinfo = getgrnam("users");
1305 if(grpinfo == NULL) {
1306 thumb_err("getgrnam(users) returns NULL !");
1309 // Compare git_t type and not group name
1310 if (grpinfo->gr_gid != userinfo->pw_gid) {
1311 thumb_err("UID [%d] does not belong to 'users' group!", uid);
1314 asprintf(&result_psswd, "%s/data/file-manager-service/.thumb/mmc", userinfo->pw_dir);
1317 return result_psswd;
1320 static char* _media_thumb_phone_get_path(uid_t uid)
1322 char *result_psswd = NULL;
1323 struct group *grpinfo = NULL;
1326 result_psswd = strdup(THUMB_PHONE_PATH);
1327 grpinfo = getgrnam("users");
1328 if(grpinfo == NULL) {
1329 thumb_err("getgrnam(users) returns NULL !");
1337 struct passwd *userinfo = getpwuid(uid);
1338 if(userinfo == NULL) {
1339 thumb_err("getpwuid(%d) returns NULL !", uid);
1342 grpinfo = getgrnam("users");
1343 if(grpinfo == NULL) {
1344 thumb_err("getgrnam(users) returns NULL !");
1347 // Compare git_t type and not group name
1348 if (grpinfo->gr_gid != userinfo->pw_gid) {
1349 thumb_err("UID [%d] does not belong to 'users' group!", uid);
1352 asprintf(&result_psswd, "%s/data/file-manager-service/.thumb/phone", userinfo->pw_dir);
1355 return result_psswd;
1358 int _media_thumb_get_hash_name(const char *file_full_path,
1359 char *thumb_hash_path, size_t max_thumb_path, uid_t uid)
1361 char *hash_name = NULL;
1362 /*char *thumb_dir = NULL;*/
1363 char file_ext[255] = { 0 };
1365 media_thumb_store_type store_type = -1;
1367 if (file_full_path == NULL || thumb_hash_path == NULL
1368 || max_thumb_path <= 0) {
1370 ("file_full_path==NULL || thumb_hash_path == NULL || max_thumb_path <= 0");
1371 return MS_MEDIA_ERR_INVALID_PARAMETER;
1374 _media_thumb_get_file_ext(file_full_path, file_ext, sizeof(file_ext));
1376 store_type = _media_thumb_get_store_type_by_path(file_full_path);
1377 /*if (store_type == THUMB_PHONE) {
1378 thumb_dir = _media_thumb_phone_get_path(uid);
1379 } else if (store_type == THUMB_MMC) {
1380 thumb_dir = _media_thumb_mmc_get_path(uid);
1382 thumb_dir = _media_thumb_phone_get_path(uid);
1385 hash_name = _media_thumb_generate_hash_name(file_full_path);
1386 if(hash_name == NULL)
1388 thumb_err("_media_thumb_generate_hash_name fail");
1389 return MS_MEDIA_ERR_INTERNAL;
1392 if (store_type == THUMB_PHONE) {
1393 ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", _media_thumb_phone_get_path(uid), file_ext, hash_name);
1394 } else if (store_type == THUMB_MMC) {
1395 ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", _media_thumb_mmc_get_path(uid), file_ext, hash_name);
1397 ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", _media_thumb_phone_get_path(uid), file_ext, hash_name);
1400 if ((ret_len < 0) || (ret_len > (int)max_thumb_path)) {
1401 thumb_err("invalid hash path ret_len[%d]", ret_len);
1402 return MS_MEDIA_ERR_INTERNAL;
1404 //thumb_dbg("thumb hash : %s", thumb_hash_path);
1406 return MS_MEDIA_ERR_NONE;
1410 int _media_thumb_save_to_file_with_evas(unsigned char *data,
1416 Ecore_Evas *ee = ecore_evas_buffer_new(w, h);
1418 thumb_err("ecore_evas_buffer_new failed");
1419 return MS_MEDIA_ERR_INTERNAL;
1422 Evas *evas = ecore_evas_get(ee);
1424 thumb_err("ecore_evas_get failed");
1425 ecore_evas_free(ee);
1426 return MS_MEDIA_ERR_INTERNAL;
1429 Evas_Object *img = NULL;
1430 img = evas_object_image_add(evas);
1433 thumb_err("evas_object_image_add failed");
1434 ecore_evas_free(ee);
1435 return MS_MEDIA_ERR_INTERNAL;
1438 evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
1439 evas_object_image_size_set(img, w, h);
1440 evas_object_image_fill_set(img, 0, 0, w, h);
1442 if (alpha) evas_object_image_alpha_set(img, 1);
1444 evas_object_image_data_set(img, data);
1445 evas_object_image_data_update_add(img, 0, 0, w, h);
1447 if (evas_object_image_save(img, thumb_path, NULL, "quality=90 compress=1")) {
1448 thumb_dbg("evas_object_image_save success");
1449 ecore_evas_free(ee);
1451 return MS_MEDIA_ERR_NONE;
1453 thumb_err("evas_object_image_save failed");
1454 ecore_evas_free(ee);
1455 return MS_MEDIA_ERR_INTERNAL;