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>
51 #define MEDIA_THUMB_ROUND_UP_8(num) (((num)+7)&~7)
53 int _media_thumb_resize_data(unsigned char *src_data,
56 mm_util_img_format src_format,
57 media_thumb_info *thumb_info,
61 int _media_thumb_get_proper_thumb_size(int orig_w, int orig_h,
62 int *thumb_w, int *thumb_h)
64 BOOL portrait = FALSE;
67 if (orig_w < orig_h) {
71 /* Set smaller length to default size */
73 if (orig_w < *thumb_w)
75 ratio = (double)orig_h / (double)orig_w;
76 *thumb_h = *thumb_w * ratio;
78 if (orig_h < *thumb_h)
80 ratio = (double)orig_w / (double)orig_h;
81 *thumb_w = *thumb_h * ratio;
84 /** CAUTION :: The width of RGB888 raw data has to be rounded by 8 **/
85 *thumb_w = MEDIA_THUMB_ROUND_UP_8(*thumb_w);
87 thumb_dbg("proper thumb w: %d h: %d", *thumb_w, *thumb_h);
89 return MS_MEDIA_ERR_NONE;
92 int _media_thumb_get_exif_info(ExifData *ed, char *buf, int max_size, int *value,
93 int ifdtype, long tagtype)
100 return MS_MEDIA_ERR_INVALID_PARAMETER;
106 entry = exif_content_get_entry(ed->ifd[ifd], tag);
108 if (tag == EXIF_TAG_ORIENTATION ||
109 tag == EXIF_TAG_PIXEL_X_DIMENSION ||
110 tag == EXIF_TAG_PIXEL_Y_DIMENSION) {
113 thumb_err("value is NULL");
114 return MS_MEDIA_ERR_INVALID_PARAMETER;
117 ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
118 short exif_value = exif_get_short(entry->data, mByteOrder);
119 *value = (int)exif_value;
121 /* Get the contents of the tag in human-readable form */
123 thumb_err("buf is NULL");
124 return MS_MEDIA_ERR_INVALID_PARAMETER;
126 exif_entry_get_value(entry, buf, max_size);
127 buf[strlen(buf)] = '\0';
131 return MS_MEDIA_ERR_NONE;
134 static int _media_thumb_get_data_from_exif(ExifData *ed,
146 ExifByteOrder byte_order = exif_data_get_byte_order(ed);
149 tag = EXIF_TAG_COMPRESSION;
151 entry = exif_content_get_entry(ed->ifd[ifd], tag);
154 /* Get the contents of the tag in human-readable form */
155 ExifShort value = exif_get_short(entry->data, byte_order);
156 //thumb_dbg("%s: %d", exif_tag_get_name_in_ifd(tag,ifd), value);
159 thumb_dbg("There's jpeg thumb in this image");
161 thumb_dbg("There's NO jpeg thumb in this image");
162 return MS_MEDIA_ERR_INVALID_PARAMETER;
165 thumb_dbg("entry is NULL");
166 return MS_MEDIA_ERR_INVALID_PARAMETER;
169 /* copy the real thumbnail data from exif data */
170 if (ed->data && ed->size) {
171 //thumb_dbg("Size: %d, thumb: 0x%x", ed->size, ed->data);
172 *thumb_data = (char *)malloc(ed->size);
174 if (*thumb_data == NULL) {
175 thumb_dbg("malloc failed!");
176 return MS_MEDIA_ERR_INVALID_PARAMETER;
179 memcpy(*thumb_data, (void *)ed->data, ed->size);
180 *thumb_size = ed->size;
182 thumb_dbg("data is NULL");
183 return MS_MEDIA_ERR_INVALID_PARAMETER;
186 /* Get width and height of thumbnail */
187 tag = EXIF_TAG_IMAGE_WIDTH;
188 entry = exif_content_get_entry(ed->ifd[ifd], tag);
191 /* Get the contents of the tag in human-readable form */
192 char width[10] = {0,};
193 exif_entry_get_value(entry,width,10);
195 *thumb_width = atoi(width);
197 thumb_warn("EXIF_TAG_IMAGE_WIDTH does not exist");
201 tag = EXIF_TAG_IMAGE_LENGTH;
202 entry = exif_content_get_entry(ed->ifd[ifd], tag);
204 /* Get the contents of the tag in human-readable form */
205 char height[10] = {0,};
206 exif_entry_get_value(entry,height,10);
208 *thumb_height = atoi(height);
210 thumb_warn("EXIF_TAG_IMAGE_LENGTH does not exist");
214 thumb_dbg("thumb width : height [%d:%d]", *thumb_width, *thumb_height);
216 /* Get width and height of original image from exif */
218 tag = EXIF_TAG_PIXEL_X_DIMENSION;
219 entry = exif_content_get_entry(ed->ifd[ifd], tag);
222 char width[10] = {0,};
223 exif_entry_get_value(entry,width,10);
225 *origin_width = atoi(width);
227 thumb_warn("EXIF_TAG_PIXEL_X_DIMENSION does not exist");
231 tag = EXIF_TAG_PIXEL_Y_DIMENSION;
232 entry = exif_content_get_entry(ed->ifd[ifd], tag);
235 char height[10] = {0,};
236 exif_entry_get_value(entry,height,10);
238 *origin_height = atoi(height);
240 thumb_warn("EXIF_TAG_PIXEL_Y_DIMENSION does not exist");
244 return MS_MEDIA_ERR_NONE;
247 int _media_thumb_get_thumb_from_exif(ExifData *ed,
248 const char *file_full_path,
249 const char *thumb_path,
253 media_thumb_info *thumb_info)
255 int err = MS_MEDIA_ERR_NONE;
258 int thumb_height = 0;
259 int origin_width = 0;
260 int origin_height = 0;
262 bool is_rotated = (orientation == ROT_90 || orientation == ROT_180 || orientation == ROT_270) ? TRUE : FALSE;
263 mm_util_jpeg_yuv_data decoded = {0,};
266 return MS_MEDIA_ERR_INVALID_PARAMETER;
269 err = _media_thumb_get_data_from_exif(ed,
277 if (err != MS_MEDIA_ERR_NONE) {
278 thumb_err("There is no exif data");
282 thumb_dbg("thumb width : height [%d:%d]", thumb_width, thumb_height);
283 thumb_dbg("origin width : height [%d:%d]", origin_width, origin_height);
284 thumb_info->origin_height = origin_height;
285 thumb_info->origin_width = origin_width;
287 if (thumb_width < required_width) {
288 thumb_err("Thumb data in exif is too small");
290 return MS_MEDIA_ERR_INVALID_PARAMETER;
294 err = mm_util_decode_from_jpeg_memory(&decoded, thumb, size, MM_UTIL_JPEG_FMT_RGB888);
296 if (err != MS_MEDIA_ERR_NONE) {
297 thumb_err("mm_util_decode_from_jpeg_turbo_memory failed : %d", err);
301 thumb_width = decoded.width;
302 thumb_height = decoded.height;
305 /* Start to decode to rotate */
306 unsigned char *rotated = NULL;
307 unsigned int r_w = decoded.height;
308 unsigned int r_h = decoded.width;
309 unsigned int r_size = 0;
310 mm_util_img_rotate_type rot_type = MM_UTIL_ROTATE_0;
312 int i, rotate_cnt = 0;
314 rot_type = MM_UTIL_ROTATE_90;
315 if (orientation == ROT_90) {
317 } else if (orientation == ROT_180) {
319 } else if (orientation == ROT_270) {
323 for (i = 0; i < rotate_cnt; i++) {
326 r_h = decoded.height;
329 err = mm_util_get_image_size(MM_UTIL_IMG_FMT_RGB888, r_w, r_h, &r_size);
330 if (err != MS_MEDIA_ERR_NONE) {
331 thumb_err("mm_util_get_image_size failed : %d", err);
332 SAFE_FREE(decoded.data);
336 rotated = (unsigned char *)malloc(r_size);
337 err = mm_util_rotate_image(decoded.data, decoded.width, decoded.height,
338 MM_UTIL_IMG_FMT_RGB888,
342 if (err != MS_MEDIA_ERR_NONE) {
343 thumb_err("mm_util_rotate_image failed : %d", err);
344 SAFE_FREE(decoded.data);
348 thumb_err("mm_util_rotate_image succeed");
351 SAFE_FREE(decoded.data);
352 decoded.data = rotated;
354 decoded.height = r_h;
357 //thumb_dbg("Width : %d, Height : %d", r_w, r_h);
358 thumb_info->data = rotated;
359 thumb_info->size = r_size;
360 thumb_info->width = r_w;
361 thumb_info->height = r_h;
363 thumb_warn("Unknown orientation");
364 SAFE_FREE(decoded.data);
365 return MS_MEDIA_ERR_INVALID_PARAMETER;
368 /*in this case, just write raw data in file */
369 thumb_dbg_slog("Thumb is :%s", thumb_path);
372 int fd = open(thumb_path, O_RDWR | O_CREAT | O_EXCL | O_SYNC, 0644);
374 if (errno == EEXIST) {
375 thumb_err("thumb alread exist!");
377 thumb_err("open failed");
379 return MS_MEDIA_ERR_INVALID_PARAMETER;
382 nwrite = write(fd, thumb, size);
384 thumb_err("write failed");
388 return MS_MEDIA_ERR_INVALID_PARAMETER;
394 thumb_info->data = NULL;
395 thumb_info->size = size;
396 thumb_info->width = thumb_width;
397 thumb_info->height = thumb_height;
398 thumb_info->is_saved = TRUE;
404 int _media_thumb_resize_data(unsigned char *src_data,
407 mm_util_img_format src_format,
408 media_thumb_info *thumb_info,
412 int thumb_width = dst_width;
413 int thumb_height = dst_height;
414 unsigned int buf_size = 0;
416 if (mm_util_get_image_size(src_format, thumb_width, thumb_height, &buf_size) < 0) {
417 thumb_err("Failed to get buffer size");
418 return MS_MEDIA_ERR_INTERNAL;
421 thumb_dbg("mm_util_get_image_size : %d", buf_size);
423 unsigned char *dst = (unsigned char *)malloc(buf_size);
426 thumb_err("malloc fails");
427 return MS_MEDIA_ERR_OUT_OF_MEMORY;
430 if (mm_util_resize_image((unsigned char *)src_data, src_width,
431 src_height, src_format,
432 dst, (unsigned int *)&thumb_width,
433 (unsigned int *)&thumb_height) < 0) {
434 thumb_err("Failed to resize the thumbnails");
438 return MS_MEDIA_ERR_INTERNAL;
441 thumb_info->size = buf_size;
442 thumb_info->width = thumb_width;
443 thumb_info->height = thumb_height;
444 thumb_info->data = malloc(buf_size);
445 if(thumb_info->data != NULL) {
446 memcpy(thumb_info->data, dst, buf_size);
448 thumb_err("malloc fails");
450 return MS_MEDIA_ERR_OUT_OF_MEMORY;
454 return MS_MEDIA_ERR_NONE;
457 int _media_thumb_get_wh_with_evas(const char *origin_path, int *width, int *height)
459 /* using evas to get w/h */
460 Ecore_Evas *ee = ecore_evas_buffer_new(0, 0);
462 thumb_err("ecore_evas_buffer_new fails");
463 return MS_MEDIA_ERR_INTERNAL;
466 Evas *evas = ecore_evas_get(ee);
468 thumb_err("ecore_evas_get fails");
470 return MS_MEDIA_ERR_INTERNAL;
473 Evas_Object *image_object = evas_object_image_add(evas);
475 thumb_err("evas_object_image_add fails");
477 return MS_MEDIA_ERR_INTERNAL;
480 evas_object_image_file_set(image_object, origin_path, NULL);
481 evas_object_image_size_get(image_object, width, height);
483 thumb_dbg("Width:%d, Height:%d", *width, *height);
487 return MS_MEDIA_ERR_NONE;
490 int _media_thumb_decode_with_evas(const char *origin_path,
491 int thumb_width, int thumb_height,
492 media_thumb_info *thumb_info, int need_scale, int orientation)
494 Ecore_Evas *resize_img_ee;
496 resize_img_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
497 if (!resize_img_ee) {
498 thumb_err("ecore_evas_buffer_new failed");
499 return MS_MEDIA_ERR_INTERNAL;
502 Evas *resize_img_e = ecore_evas_get(resize_img_ee);
504 thumb_err("ecore_evas_get failed");
505 ecore_evas_free(resize_img_ee);
506 return MS_MEDIA_ERR_INTERNAL;
509 Evas_Object *source_img = evas_object_image_add(resize_img_e);
511 thumb_err("evas_object_image_add failed");
512 ecore_evas_free(resize_img_ee);
513 return MS_MEDIA_ERR_INTERNAL;
516 evas_object_image_file_set(source_img, origin_path, NULL);
518 /* Get w/h of original image */
522 evas_object_image_size_get(source_img, &width, &height);
523 thumb_info->origin_width = width;
524 thumb_info->origin_height = height;
525 //thumb_dbg("origin width:%d, origin height:%d", width, height);
527 if ((need_scale == 1) && (width * height > THUMB_MAX_ALLOWED_MEM_FOR_THUMB)) {
528 thumb_warn("This is too large image. so this's scale is going to be down");
529 evas_object_image_load_scale_down_set(source_img, 10);
532 if (orientation != TRANSPOSE)
533 evas_object_image_load_orientation_set(source_img, 1);
535 int rotated_orig_w = 0;
536 int rotated_orig_h = 0;
538 if (orientation == ROT_90 || orientation == ROT_270) {
539 rotated_orig_w = height;
540 rotated_orig_h = width;
542 rotated_orig_w = width;
543 rotated_orig_h = height;
545 //thumb_dbg("rotated - origin width:%d, origin height:%d", rotated_orig_w, rotated_orig_h);
547 int err = MS_MEDIA_ERR_NONE;
549 err = _media_thumb_get_proper_thumb_size(rotated_orig_w, rotated_orig_h, &thumb_width, &thumb_height);
550 if (err != MS_MEDIA_ERR_NONE) {
551 thumb_err("_media_thumb_get_proper_thumb_size failed: %d", err);
552 ecore_evas_free(resize_img_ee);
556 ecore_evas_resize(resize_img_ee, thumb_width, thumb_height);
558 evas_object_image_load_size_set(source_img, thumb_width, thumb_height);
559 evas_object_image_fill_set(source_img, 0, 0, thumb_width, thumb_height);
560 evas_object_image_filled_set(source_img, 1);
562 evas_object_resize(source_img, thumb_width, thumb_height);
563 evas_object_show(source_img);
565 /* Set alpha from original */
566 thumb_info->alpha = evas_object_image_alpha_get(source_img);
567 if (thumb_info->alpha) ecore_evas_alpha_set(resize_img_ee, EINA_TRUE);
569 /* Create target buffer and copy origin resized img to it */
570 Ecore_Evas *target_ee = ecore_evas_buffer_new(thumb_width, thumb_height);
572 thumb_err("ecore_evas_buffer_new failed");
573 ecore_evas_free(resize_img_ee);
574 return MS_MEDIA_ERR_INTERNAL;
577 Evas *target_evas = ecore_evas_get(target_ee);
579 thumb_err("ecore_evas_get failed");
580 ecore_evas_free(resize_img_ee);
581 ecore_evas_free(target_ee);
582 return MS_MEDIA_ERR_INTERNAL;
585 Evas_Object *ret_image = evas_object_image_add(target_evas);
586 evas_object_image_size_set(ret_image, thumb_width, thumb_height);
587 evas_object_image_fill_set(ret_image, 0, 0, thumb_width, thumb_height);
588 evas_object_image_filled_set(ret_image, EINA_TRUE);
590 evas_object_image_data_set(ret_image, (int *)ecore_evas_buffer_pixels_get(resize_img_ee));
591 evas_object_image_data_update_add(ret_image, 0, 0, thumb_width, thumb_height);
593 unsigned int buf_size = 0;
594 if (mm_util_get_image_size(MM_UTIL_IMG_FMT_BGRA8888, thumb_width, thumb_height, &buf_size) < 0) {
595 thumb_err("mm_util_get_image_size failed");
597 ecore_evas_free(resize_img_ee);
598 ecore_evas_free(target_ee);
600 return MS_MEDIA_ERR_INTERNAL;
602 //thumb_dbg("mm_util_get_image_size : %d", buf_size);
604 thumb_info->size = buf_size;
605 thumb_info->width = thumb_width;
606 thumb_info->height = thumb_height;
607 thumb_info->data = malloc(buf_size);
608 if (thumb_info->data == NULL) {
609 thumb_err("Failed to allocate memory" );
610 ecore_evas_free(resize_img_ee);
611 ecore_evas_free(target_ee);
613 return MS_MEDIA_ERR_OUT_OF_MEMORY;
616 void *image_data = evas_object_image_data_get(ret_image, 1);
617 if (image_data != NULL) {
618 memcpy(thumb_info->data, image_data, buf_size);
620 thumb_err("image_data is NULL. evas_object_image_data_get failed");
623 ecore_evas_free(target_ee);
624 ecore_evas_free(resize_img_ee);
629 mm_util_img_format _media_thumb_get_format(media_thumb_format src_format)
632 case MEDIA_THUMB_BGRA:
633 return MM_UTIL_IMG_FMT_BGRA8888;
634 case MEDIA_THUMB_RGB888:
635 return MM_UTIL_IMG_FMT_RGB888;
637 return MS_MEDIA_ERR_INVALID_PARAMETER;
641 int _media_thumb_convert_data(media_thumb_info *thumb_info,
644 mm_util_img_format src_format,
645 mm_util_img_format dst_format)
647 int err = MS_MEDIA_ERR_NONE;
648 unsigned int buf_size = 0;
649 unsigned char *src_data = thumb_info->data;
650 unsigned char *dst_data = NULL;
652 thumb_dbg("src format:%d, dst format:%d", src_format, dst_format);
654 if (mm_util_get_image_size(dst_format, thumb_width, thumb_height, &buf_size) < 0) {
655 thumb_err("mm_util_get_image_size failed");
656 return MS_MEDIA_ERR_INTERNAL;
659 thumb_dbg("mm_util_get_image_size : %d", buf_size);
661 dst_data = (unsigned char *)malloc(buf_size);
663 if (dst_data == NULL) {
664 thumb_err("Failed to allocate memory");
665 return MS_MEDIA_ERR_OUT_OF_MEMORY;
668 if (src_format == MM_UTIL_IMG_FMT_RGB888 &&
669 dst_format == MM_UTIL_IMG_FMT_BGRA8888) {
672 for (j = 0; j < thumb_width * 3 * thumb_height;
674 dst_data[i++] = (src_data[j + 2]);
675 dst_data[i++] = (src_data[j + 1]);
676 dst_data[i++] = (src_data[j]);
681 err = mm_util_convert_colorspace(src_data,
689 thumb_err("Failed to change from rgb888 to argb8888 %d", err);
691 return MS_MEDIA_ERR_INTERNAL;
695 SAFE_FREE(thumb_info->data);
696 thumb_info->data = dst_data;
697 thumb_info->size = buf_size;
699 thumb_dbg("_media_thumb_convert_data success");
704 int _media_thumb_convert_format(media_thumb_info *thumb_info,
705 media_thumb_format src_format,
706 media_thumb_format dst_format)
708 int err = MS_MEDIA_ERR_NONE;
710 if (src_format == dst_format) {
711 //thumb_dbg("src_format == dst_format");
715 mm_util_img_format src_mm_format;
716 mm_util_img_format dst_mm_format;
718 src_mm_format = _media_thumb_get_format(src_format);
719 dst_mm_format = _media_thumb_get_format(dst_format);
721 if ((int)src_mm_format == -1 || (int)dst_mm_format == -1) {
722 thumb_err("Format is invalid");
723 return MS_MEDIA_ERR_INVALID_PARAMETER;
726 err = _media_thumb_convert_data(thumb_info,
732 if (err != MS_MEDIA_ERR_NONE) {
733 thumb_err("media_thumb_convert_format failed : %d", err);
740 int _media_thumb_agif(const char *origin_path,
745 media_thumb_format format,
746 media_thumb_info *thumb_info)
748 int err = MS_MEDIA_ERR_NONE;
749 unsigned int *thumb = NULL;
751 thumb = ImgGetFirstFrameAGIFAtSize(origin_path, image_width, image_height);
754 thumb_err("Frame data is NULL!!");
755 return MS_MEDIA_ERR_INTERNAL;
758 err = _media_thumb_get_proper_thumb_size(thumb_info->origin_width, thumb_info->origin_height, &thumb_width, &thumb_height);
759 if (err != MS_MEDIA_ERR_NONE) {
760 thumb_err("_media_thumb_get_proper_thumb_size failed: %d", err);
765 err = _media_thumb_resize_data((unsigned char *)thumb,
768 MM_UTIL_IMG_FMT_RGB888,
773 if (err != MS_MEDIA_ERR_NONE) {
774 thumb_err("_media_thumb_resize_data failed: %d", err);
781 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_RGB888, format);
782 if (err != MS_MEDIA_ERR_NONE) {
783 thumb_err("_media_thumb_convert_format falied: %d", err);
784 SAFE_FREE(thumb_info->data);
791 int _media_thumb_png(const char *origin_path,
794 media_thumb_format format,
795 media_thumb_info *thumb_info)
797 int err = MS_MEDIA_ERR_NONE;
798 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
800 if (err != MS_MEDIA_ERR_NONE) {
801 thumb_err("decode_with_evas failed : %d", err);
805 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
806 if (err != MS_MEDIA_ERR_NONE) {
807 thumb_err("_media_thumb_convert_format falied: %d", err);
808 SAFE_FREE(thumb_info->data);
815 int _media_thumb_bmp(const char *origin_path,
818 media_thumb_format format,
819 media_thumb_info *thumb_info)
821 int err = MS_MEDIA_ERR_NONE;
822 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
824 if (err != MS_MEDIA_ERR_NONE) {
825 thumb_err("decode_with_evas failed : %d", err);
829 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
830 if (err != MS_MEDIA_ERR_NONE) {
831 thumb_err("_media_thumb_convert_format falied: %d", err);
832 SAFE_FREE(thumb_info->data);
839 int _media_thumb_wbmp(const char *origin_path,
842 media_thumb_format format,
843 media_thumb_info *thumb_info)
845 int err = MS_MEDIA_ERR_NONE;
846 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
848 if (err != MS_MEDIA_ERR_NONE) {
849 thumb_err("decode_with_evas failed : %d", err);
853 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
854 if (err != MS_MEDIA_ERR_NONE) {
855 thumb_err("_media_thumb_convert_format falied: %d", err);
856 SAFE_FREE(thumb_info->data);
863 int _media_thumb_gif(const char *origin_path,
866 media_thumb_format format,
867 media_thumb_info *thumb_info)
869 int err = MS_MEDIA_ERR_NONE;
870 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, NORMAL);
872 if (err != MS_MEDIA_ERR_NONE) {
873 thumb_err("decode_with_evas failed : %d", err);
877 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
878 if (err != MS_MEDIA_ERR_NONE) {
879 thumb_err("_media_thumb_convert_format falied: %d", err);
880 SAFE_FREE(thumb_info->data);
887 int _media_thumb_jpeg(const char *origin_path,
888 const char *thumb_path,
891 media_thumb_format format,
892 media_thumb_info *thumb_info)
894 int err = MS_MEDIA_ERR_NONE;
897 int orientation = NORMAL;
899 /* Load an ExifData object from an EXIF file */
900 ed = exif_data_new_from_file(origin_path);
903 /* First, Get orientation from exif */
904 err = _media_thumb_get_exif_info(ed, NULL, 0, &orientation, EXIF_IFD_0, EXIF_TAG_ORIENTATION);
906 if (err != MS_MEDIA_ERR_NONE) {
907 thumb_warn("_media_thumb_get_exif_info failed");
910 /* Second, Get thumb from exif */
911 err = _media_thumb_get_thumb_from_exif(ed, origin_path, thumb_path, orientation, thumb_width, thumb_height, thumb_info);
913 if (err != MS_MEDIA_ERR_NONE) {
914 thumb_dbg("_media_thumb_get_thumb_from_exif failed");
917 thumb_dbg("_media_thumb_get_thumb_from_exif succeed");
919 /* The case that original image's size is not in exif header. Use evas to get w/h */
920 if (thumb_info->origin_width == 0 || thumb_info->origin_height == 0) {
921 thumb_warn("original image's size is not in exif header. Use evas to get w/h");
922 err = _media_thumb_get_wh_with_evas(origin_path, &(thumb_info->origin_width), &(thumb_info->origin_height));
923 if (err != MS_MEDIA_ERR_NONE) {
924 thumb_err("Couldn't get w/h using evas : %s", origin_path);
926 thumb_dbg("origin w : %d, origin h : %d", thumb_info->origin_width, thumb_info->origin_height);
930 if (thumb_info->is_saved == FALSE) {
931 mm_util_img_format dst_format = _media_thumb_get_format(format);
933 err = _media_thumb_convert_data(thumb_info,
936 MM_UTIL_IMG_FMT_RGB888,
939 if (err != MS_MEDIA_ERR_NONE) {
940 thumb_err("_media_thumb_convert_data failed : %d", err);
952 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, orientation);
954 if (err != MS_MEDIA_ERR_NONE) {
955 thumb_err("decode_with_evas failed : %d", err);
959 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
960 if (err != MS_MEDIA_ERR_NONE) {
961 thumb_err("_media_thumb_convert_format falied: %d", err);
962 SAFE_FREE(thumb_info->data);
970 int _media_thumb_jpeg_for_raw(const char *origin_path,
971 const char *thumb_path,
974 media_thumb_format format,
975 media_thumb_info *thumb_info)
977 int err = MS_MEDIA_ERR_NONE;
978 int orientation = NORMAL;
980 err = _media_thumb_decode_with_evas(origin_path, thumb_width, thumb_height, thumb_info, 1, orientation);
982 if (err != MS_MEDIA_ERR_NONE) {
983 thumb_err("decode_with_evas failed : %d", err);
987 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_BGRA, format);
988 if (err != MS_MEDIA_ERR_NONE) {
989 thumb_err("_media_thumb_convert_format falied: %d", err);
990 SAFE_FREE(thumb_info->data);
996 int _media_thumb_image(const char *origin_path,
997 const char *thumb_path,
1000 media_thumb_format format,
1001 media_thumb_info *thumb_info,
1004 int err = MS_MEDIA_ERR_NONE;
1005 ImgCodecType image_type = 0;
1006 unsigned int origin_w = 0;
1007 unsigned int origin_h = 0;
1009 err = ImgGetImageInfoForThumb(origin_path, &image_type, &origin_w, &origin_h);
1011 if (err != MS_MEDIA_ERR_NONE){
1012 thumb_warn("Getting image info is failed err: %d", err);
1015 thumb_info->origin_width = origin_w;
1016 thumb_info->origin_height = origin_h;
1018 //thumb_dbg("image type is %d, width:%d, height:%d", image_type, origin_w, origin_h);
1020 if ((image_type != IMG_CODEC_JPEG) &&
1021 (origin_w * origin_h > THUMB_MAX_ALLOWED_MEM_FOR_THUMB)) {
1022 thumb_warn("This original image is too big");
1023 return MS_MEDIA_ERR_THUMB_TOO_BIG;
1026 if (image_type == IMG_CODEC_AGIF) {
1027 err = _media_thumb_agif(origin_path, origin_w, origin_h, thumb_width, thumb_height, format, thumb_info);
1028 } else if (image_type == IMG_CODEC_JPEG) {
1029 if(is_req_raw == TRUE) {
1030 err = _media_thumb_jpeg_for_raw(origin_path, thumb_path, thumb_width, thumb_height, format, thumb_info);
1032 err = _media_thumb_jpeg(origin_path, thumb_path, thumb_width, thumb_height, format, thumb_info);
1034 } else if (image_type == IMG_CODEC_PNG) {
1035 err = _media_thumb_png(origin_path, thumb_width, thumb_height, format, thumb_info);
1036 } else if (image_type == IMG_CODEC_GIF) {
1037 err = _media_thumb_gif(origin_path, thumb_width, thumb_height, format, thumb_info);
1038 } else if (image_type == IMG_CODEC_BMP) {
1039 err = _media_thumb_bmp(origin_path, thumb_width, thumb_height, format, thumb_info);
1042 err = _media_thumb_get_file_ext(origin_path, file_ext, sizeof(file_ext));
1043 if (err != MS_MEDIA_ERR_NONE) {
1044 thumb_warn("_media_thumb_get_file_ext failed");
1046 if (strcasecmp(file_ext, "wbmp") == 0) {
1047 image_type = IMG_CODEC_WBMP;
1049 int wbmp_height = 0;
1051 err = _media_thumb_get_wh_with_evas(origin_path, &wbmp_width, &wbmp_height);
1052 if (err != MS_MEDIA_ERR_NONE) {
1053 thumb_err("_media_thumb_get_wh_with_evas in WBMP : %d", err);
1057 if (wbmp_width * wbmp_height > THUMB_MAX_ALLOWED_MEM_FOR_THUMB) {
1058 thumb_warn("This original image is too big");
1059 return MS_MEDIA_ERR_THUMB_TOO_BIG;
1062 thumb_info->origin_width = wbmp_width;
1063 thumb_info->origin_height = wbmp_height;
1065 err = _media_thumb_wbmp(origin_path, thumb_width, thumb_height, format, thumb_info);
1071 thumb_warn("Unsupported image type");
1072 return MS_MEDIA_ERR_INVALID_PARAMETER;
1078 int _media_thumb_video(const char *origin_path,
1081 media_thumb_format format,
1082 media_thumb_info *thumb_info)
1084 int err = MS_MEDIA_ERR_NONE;
1086 MMHandleType content = (MMHandleType) NULL;
1088 int video_track_num = 0;
1089 char *err_msg = NULL;
1094 bool drm_type = FALSE;
1098 /* Get Content Tag attribute for orientatin */
1099 MMHandleType tag = (MMHandleType) NULL;
1102 err = mm_file_create_tag_attrs(&tag, origin_path);
1103 mm_util_img_rotate_type rot_type = MM_UTIL_ROTATE_0;
1105 if (err == MM_ERROR_NONE) {
1106 err = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_ROTATE, &p, &size, NULL);
1107 if (err == MM_ERROR_NONE && size >= 0) {
1109 rot_type = MM_UTIL_ROTATE_0;
1111 if (strncmp(p, "90", size) == 0) {
1112 rot_type = MM_UTIL_ROTATE_90;
1113 } else if(strncmp(p, "180", size) == 0) {
1114 rot_type = MM_UTIL_ROTATE_180;
1115 } else if(strncmp(p, "270", size) == 0) {
1116 rot_type = MM_UTIL_ROTATE_270;
1118 rot_type = MM_UTIL_ROTATE_0;
1121 thumb_dbg("There is tag rotate : %d", rot_type);
1123 thumb_dbg("There is NOT tag rotate");
1124 rot_type = MM_UTIL_ROTATE_0;
1128 err = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_CDIS, &cdis_value, NULL);
1129 if (err != MM_ERROR_NONE) {
1135 rot_type = MM_UTIL_ROTATE_0;
1139 err = mm_file_destroy_tag_attrs(tag);
1140 if (err != MM_ERROR_NONE) {
1141 thumb_err("fail to free tag attr - err(%x)", err);
1144 if (cdis_value == 1) {
1145 thumb_warn("This is CDIS vlaue 1");
1146 err = mm_file_create_content_attrs_safe(&content, origin_path);
1148 err = mm_file_create_content_attrs(&content, origin_path);
1151 if (err != MM_ERROR_NONE) {
1152 thumb_err("mm_file_create_content_attrs fails : %d", err);
1153 return MS_MEDIA_ERR_INTERNAL;
1156 err = mm_file_get_attrs(content, &err_msg, MM_FILE_CONTENT_VIDEO_TRACK_COUNT, &video_track_num, NULL);
1157 if (err != MM_ERROR_NONE) {
1158 thumb_err("mm_file_get_attrs fails : %s", err_msg);
1160 mm_file_destroy_content_attrs(content);
1161 return MS_MEDIA_ERR_INTERNAL;
1164 /* MMF api handle both normal and DRM video */
1165 if (video_track_num > 0 || is_drm) {
1167 err = mm_file_get_attrs(content, &err_msg,
1168 MM_FILE_CONTENT_VIDEO_WIDTH,
1170 MM_FILE_CONTENT_VIDEO_HEIGHT,
1172 MM_FILE_CONTENT_VIDEO_THUMBNAIL, &frame, /* raw image is RGB888 format */
1175 if (err != MM_ERROR_NONE) {
1176 thumb_err("mm_file_get_attrs fails : %s", err_msg);
1178 mm_file_destroy_content_attrs(content);
1179 return MS_MEDIA_ERR_INTERNAL;
1182 thumb_dbg("video width: %d", width);
1183 thumb_dbg("video height: %d", height);
1184 thumb_dbg("thumbnail size=%d", size);
1185 thumb_dbg("frame = 0x%x", frame);
1187 if (frame == NULL || width == 0 || height == 0) {
1188 thumb_err("Failed to get frame data");
1189 mm_file_destroy_content_attrs(content);
1190 return MS_MEDIA_ERR_INTERNAL;
1193 thumb_info->origin_width = width;
1194 thumb_info->origin_height = height;
1196 err = _media_thumb_get_proper_thumb_size(width, height, &thumb_width, &thumb_height);
1198 if (width > thumb_width || height > thumb_height) {
1199 err = _media_thumb_resize_data(frame,
1202 MM_UTIL_IMG_FMT_RGB888,
1207 if (err != MS_MEDIA_ERR_NONE) {
1208 thumb_err("_media_thumb_resize_data failed - %d", err);
1209 SAFE_FREE(thumb_info->data);
1210 mm_file_destroy_content_attrs(content);
1214 thumb_info->size = size;
1215 thumb_info->width = width;
1216 thumb_info->height = height;
1217 thumb_info->data = malloc(size);
1218 if (thumb_info->data == NULL) {
1219 thumb_err("memory allcation failed" );
1220 mm_file_destroy_content_attrs(content);
1221 return MS_MEDIA_ERR_OUT_OF_MEMORY;
1223 memcpy(thumb_info->data, frame, size);
1226 mm_file_destroy_content_attrs(content);
1227 if (rot_type == MM_UTIL_ROTATE_90 || rot_type == MM_UTIL_ROTATE_180 || rot_type == MM_UTIL_ROTATE_270) {
1228 /* Start to decode to rotate */
1229 unsigned char *rotated = NULL;
1230 unsigned int r_w = thumb_info->height;
1231 unsigned int r_h = thumb_info->width;
1232 unsigned int r_size = 0;
1234 if (rot_type == MM_UTIL_ROTATE_180) {
1235 r_w = thumb_info->width;
1236 r_h = thumb_info->height;
1239 err = mm_util_get_image_size(MM_UTIL_IMG_FMT_RGB888, r_w, r_h, &r_size);
1240 if (err != MM_ERROR_NONE) {
1241 thumb_err("mm_util_get_image_size failed : %d", err);
1242 SAFE_FREE(thumb_info->data);
1246 //thumb_dbg("Size of Rotated : %d", r_size);
1247 rotated = (unsigned char *)malloc(r_size);
1248 err = mm_util_rotate_image(thumb_info->data, thumb_info->width, thumb_info->height,
1249 MM_UTIL_IMG_FMT_RGB888,
1250 rotated, &r_w, &r_h,
1253 if (err != MM_ERROR_NONE) {
1254 thumb_err("mm_util_rotate_image failed : %d", err);
1255 SAFE_FREE(thumb_info->data);
1259 thumb_dbg("mm_util_rotate_image succeed");
1262 SAFE_FREE(thumb_info->data);
1263 thumb_info->data = rotated;
1264 thumb_info->size = r_size;
1265 thumb_info->width = r_w;
1266 thumb_info->height = r_h;
1269 err = _media_thumb_convert_format(thumb_info, MEDIA_THUMB_RGB888, format);
1270 if (err != MS_MEDIA_ERR_NONE) {
1271 thumb_err("_media_thumb_convert_format falied: %d", err);
1272 SAFE_FREE(thumb_info->data);
1276 thumb_dbg("no contents information");
1278 mm_file_destroy_content_attrs(content);
1280 return MS_MEDIA_ERR_INTERNAL;
1286 static char* _media_thumb_mmc_get_path(uid_t uid)
1288 char *result_psswd = NULL;
1289 struct group *grpinfo = NULL;
1292 result_psswd = strdup(THUMB_MMC_PATH);
1293 grpinfo = getgrnam("users");
1294 if(grpinfo == NULL) {
1295 thumb_err("getgrnam(users) returns NULL !");
1303 struct passwd *userinfo = getpwuid(uid);
1304 if(userinfo == NULL) {
1305 thumb_err("getpwuid(%d) returns NULL !", uid);
1308 grpinfo = getgrnam("users");
1309 if(grpinfo == NULL) {
1310 thumb_err("getgrnam(users) returns NULL !");
1313 // Compare git_t type and not group name
1314 if (grpinfo->gr_gid != userinfo->pw_gid) {
1315 thumb_err("UID [%d] does not belong to 'users' group!", uid);
1318 asprintf(&result_psswd, "%s/share/media/.thumb/mmc", userinfo->pw_dir);
1321 return result_psswd;
1324 static char* _media_thumb_phone_get_path(uid_t uid)
1326 char *result_psswd = NULL;
1327 struct group *grpinfo = NULL;
1330 result_psswd = strdup(THUMB_PHONE_PATH);
1331 grpinfo = getgrnam("users");
1332 if(grpinfo == NULL) {
1333 thumb_err("getgrnam(users) returns NULL !");
1341 struct passwd *userinfo = getpwuid(uid);
1342 if(userinfo == NULL) {
1343 thumb_err("getpwuid(%d) returns NULL !", uid);
1346 grpinfo = getgrnam("users");
1347 if(grpinfo == NULL) {
1348 thumb_err("getgrnam(users) returns NULL !");
1351 // Compare git_t type and not group name
1352 if (grpinfo->gr_gid != userinfo->pw_gid) {
1353 thumb_err("UID [%d] does not belong to 'users' group!", uid);
1356 asprintf(&result_psswd, "%s/share/media/.thumb/phone", userinfo->pw_dir);
1359 return result_psswd;
1362 int _media_thumb_get_hash_name(const char *file_full_path,
1363 char *thumb_hash_path, size_t max_thumb_path, uid_t uid)
1365 char *hash_name = NULL;
1366 /*char *thumb_dir = NULL;*/
1367 char file_ext[255] = { 0 };
1369 media_thumb_store_type store_type = -1;
1371 if (file_full_path == NULL || thumb_hash_path == NULL
1372 || max_thumb_path <= 0) {
1374 ("file_full_path==NULL || thumb_hash_path == NULL || max_thumb_path <= 0");
1375 return MS_MEDIA_ERR_INVALID_PARAMETER;
1378 _media_thumb_get_file_ext(file_full_path, file_ext, sizeof(file_ext));
1380 store_type = _media_thumb_get_store_type_by_path(file_full_path);
1381 /*if (store_type == THUMB_PHONE) {
1382 thumb_dir = _media_thumb_phone_get_path(uid);
1383 } else if (store_type == THUMB_MMC) {
1384 thumb_dir = _media_thumb_mmc_get_path(uid);
1386 thumb_dir = _media_thumb_phone_get_path(uid);
1389 hash_name = _media_thumb_generate_hash_name(file_full_path);
1390 if(hash_name == NULL)
1392 thumb_err("_media_thumb_generate_hash_name fail");
1393 return MS_MEDIA_ERR_INTERNAL;
1396 if (store_type == THUMB_PHONE) {
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);
1398 } else if (store_type == THUMB_MMC) {
1399 ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", _media_thumb_mmc_get_path(uid), file_ext, hash_name);
1401 ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", _media_thumb_phone_get_path(uid), file_ext, hash_name);
1404 if ((ret_len < 0) || (ret_len > (int)max_thumb_path)) {
1405 thumb_err("invalid hash path ret_len[%d]", ret_len);
1406 return MS_MEDIA_ERR_INTERNAL;
1408 //thumb_dbg("thumb hash : %s", thumb_hash_path);
1410 return MS_MEDIA_ERR_NONE;
1414 int _media_thumb_save_to_file_with_evas(unsigned char *data,
1420 Ecore_Evas *ee = ecore_evas_buffer_new(w, h);
1422 thumb_err("ecore_evas_buffer_new failed");
1423 return MS_MEDIA_ERR_INTERNAL;
1426 Evas *evas = ecore_evas_get(ee);
1428 thumb_err("ecore_evas_get failed");
1429 ecore_evas_free(ee);
1430 return MS_MEDIA_ERR_INTERNAL;
1433 Evas_Object *img = NULL;
1434 img = evas_object_image_add(evas);
1437 thumb_err("evas_object_image_add failed");
1438 ecore_evas_free(ee);
1439 return MS_MEDIA_ERR_INTERNAL;
1442 evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
1443 evas_object_image_size_set(img, w, h);
1444 evas_object_image_fill_set(img, 0, 0, w, h);
1446 if (alpha) evas_object_image_alpha_set(img, 1);
1448 evas_object_image_data_set(img, data);
1449 evas_object_image_data_update_add(img, 0, 0, w, h);
1451 if (evas_object_image_save(img, thumb_path, NULL, "quality=90 compress=1")) {
1452 thumb_dbg("evas_object_image_save success");
1453 ecore_evas_free(ee);
1455 return MS_MEDIA_ERR_NONE;
1457 thumb_err("evas_object_image_save failed");
1458 ecore_evas_free(ee);
1459 return MS_MEDIA_ERR_INTERNAL;