/* * libmedia-thumbnail * * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include #include #if defined(USE_MEMORY_USAGE_REDUCTION) #include #include #include #endif #include "media-thumbnail.h" #include "media-thumbnail-debug.h" #define MAX_THUMB_SIZE 2000 #define MIME_TYPE_TIFF "image/tiff" #define MIME_TYPE_ASF "application/vnd.ms-asf" #define MIME_MAX_LEN 255 typedef enum { MEDIA_THUMB_INVALID = 0, MEDIA_THUMB_IMAGE, MEDIA_THUMB_VIDEO, } thumbnail_media_type_e; static void __get_rotation(const char *path, mm_util_rotate_type_e *rot_type) { int err = FILEINFO_ERROR_NONE; MMHandleType tag = (MMHandleType) NULL; char *p = NULL; int size = 0; mm_util_rotate_type_e _rot_type = MM_UTIL_ROTATE_0; /* Get Content Tag attribute for orientation */ err = mm_file_create_tag_attrs(&tag, path); if (err != FILEINFO_ERROR_NONE) return; err = mm_file_get_attrs(tag, MM_FILE_TAG_ROTATE, &p, &size, NULL); if (err == FILEINFO_ERROR_NONE && size >= 0 && p) { if (strncmp(p, "90", size) == 0) _rot_type = MM_UTIL_ROTATE_90; else if (strncmp(p, "180", size) == 0) _rot_type = MM_UTIL_ROTATE_180; else if (strncmp(p, "270", size) == 0) _rot_type = MM_UTIL_ROTATE_270; else _rot_type = MM_UTIL_ROTATE_0; thumb_dbg("There is tag rotate : %d", _rot_type); } *rot_type = _rot_type; mm_file_destroy_tag_attrs(tag); } static int __get_video_meta(const char *path, int *video_track_num, unsigned int *width, unsigned int *height, void **frame, size_t *frame_size) { int err = FILEINFO_ERROR_NONE; MMHandleType content = (MMHandleType) NULL; int _video_track_num = 0; unsigned int _width = 0; unsigned int _height = 0; size_t _frame_size = 0; void *_frame = NULL; void *_copied = NULL; err = mm_file_create_content_attrs(&content, path); thumb_retvm_if(err != FILEINFO_ERROR_NONE, THUMB_FAIL, "mm_file_create_content_attrs fails : %d", err); err = mm_file_get_attrs(content, MM_FILE_CONTENT_VIDEO_TRACK_COUNT, &_video_track_num, MM_FILE_CONTENT_VIDEO_WIDTH, &_width, MM_FILE_CONTENT_VIDEO_HEIGHT, &_height, MM_FILE_CONTENT_VIDEO_THUMBNAIL, &_frame, &_frame_size, /* raw image is RGB888 format */ NULL); if (err != FILEINFO_ERROR_NONE) { thumb_err("mm_file_get_attrs fails : %d", err); mm_file_destroy_content_attrs(content); return THUMB_FAIL; } *video_track_num = _video_track_num; if (_video_track_num == 0) { mm_file_destroy_content_attrs(content); return THUMB_OK; } if (!_frame || _width == 0 || _height == 0 || _frame_size == 0) { thumb_err("wrong video info W[%d] H[%d] Size[%zu] Frame[%p]", _width, _height, _frame_size, _frame); mm_file_destroy_content_attrs(content); return THUMB_FAIL; } _copied = malloc(_frame_size); if (!_copied) { thumb_err("allocation failed"); mm_file_destroy_content_attrs(content); return THUMB_FAIL; } *width = _width; *height = _height; *frame_size = _frame_size; memcpy(_copied, _frame, _frame_size); *frame = _copied; mm_file_destroy_content_attrs(content); return THUMB_OK; } static int __get_video_info(const char *path, int *video_track_num, unsigned int *width, unsigned int *height, void **frame, size_t *frame_size, mm_util_rotate_type_e *rot_type) { int err = THUMB_OK; mm_util_rotate_type_e _rot_type = MM_UTIL_ROTATE_0; __get_rotation(path, &_rot_type); err = __get_video_meta(path, video_track_num, width, height, frame, frame_size); if (rot_type) *rot_type = _rot_type; return err; } static void __media_thumb_get_proper_thumb_size(unsigned int origin_width, unsigned int origin_height, unsigned int *thumb_width, unsigned int *thumb_height) { double ratio = 0.0; thumb_retm_if(origin_width == 0, "Invalid origin_width"); thumb_retm_if(origin_height == 0, "Invalid origin_height"); thumb_retm_if(!thumb_width, "Invalid thumb_width"); thumb_retm_if(!thumb_height, "Invalid thumb_height"); thumb_dbg("origin thumb w: %d h: %d", *thumb_width, *thumb_height); /* Set smaller length to default size */ if (origin_width < origin_height) { if (origin_width < *thumb_width) *thumb_width = origin_width; ratio = (double)origin_height / (double)origin_width; *thumb_height = *thumb_width * ratio; } else { if (origin_height < *thumb_height) *thumb_height = origin_height; ratio = (double)origin_width / (double)origin_height; *thumb_width = *thumb_height * ratio; } thumb_dbg("proper thumb w: %d h: %d", *thumb_width, *thumb_height); } static int __get_video_thumb_to_file(unsigned int width, unsigned int height, void *frame, size_t frame_size, mm_util_rotate_type_e rot_type, const char *thumb_path, unsigned int thumb_width, unsigned int thumb_height) { int err = MM_UTIL_ERROR_NONE; mm_util_image_h img = NULL; mm_util_image_h resize_img = NULL; unsigned int thumb_w = thumb_width; unsigned int thumb_h = thumb_height; thumb_retvm_if(!thumb_path, THUMB_FAIL, "Invalid thumb_path"); __media_thumb_get_proper_thumb_size(width, height, &thumb_w, &thumb_h); thumb_retv_if(thumb_w == 0 || thumb_h == 0, THUMB_FAIL); err = mm_image_create_image(width, height, MM_UTIL_COLOR_RGB24, (unsigned char *)frame, frame_size, &img); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "fail to mm_image_create_image [%d]", err); if (width > thumb_w || height > thumb_h) { if (rot_type != MM_UTIL_ROTATE_0) { err = mm_util_resize_B_B(img, thumb_w, thumb_h, &resize_img); if (err != MM_UTIL_ERROR_NONE) goto ERROR; err = mm_util_rotate_B_P(resize_img, rot_type, thumb_path); } else { err = mm_util_resize_B_P(img, thumb_w, thumb_h, thumb_path); } } else { if (rot_type != MM_UTIL_ROTATE_0) err = mm_util_rotate_B_P(img, rot_type, thumb_path); else err = mm_util_resize_B_P(img, width, height, thumb_path); } ERROR: mm_image_destroy_image(img); mm_image_destroy_image(resize_img); return (err == MM_UTIL_ERROR_NONE) ? THUMB_OK : THUMB_FAIL; } static int __get_video_thumb_to_buffer(unsigned int width, unsigned int height, void *frame, size_t frame_size, unsigned int thumb_width, unsigned int thumb_height, mm_util_image_h *dst_img) { int err = MM_UTIL_ERROR_NONE; mm_util_image_h img = NULL; unsigned int thumb_w = thumb_width; unsigned int thumb_h = thumb_height; __media_thumb_get_proper_thumb_size(width, height, &thumb_w, &thumb_h); thumb_retv_if(thumb_w == 0 || thumb_h == 0, THUMB_FAIL); err = mm_image_create_image(width, height, MM_UTIL_COLOR_RGB24, (unsigned char *)frame, frame_size, &img); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "fail to mm_image_create_image [%d]", err); if (width > thumb_w || height > thumb_h) err = mm_util_resize_B_B(img, thumb_w, thumb_h, dst_img); else err = mm_image_clone_image(img, dst_img); mm_image_destroy_image(img); return (err == MM_UTIL_ERROR_NONE) ? THUMB_OK : THUMB_FAIL; } static int __check_path_validity(const char *path) { thumb_retvm_if(!path, THUMB_FAIL, "Invalid path"); if (access(path, R_OK) < 0) { if (errno == EACCES || errno == EPERM) { thumb_err("Fail to open path: Permission Denied [%s]", path); return THUMB_PERM; } else { thumb_err("Fail to open path: Invalid Path [%s]", path); return THUMB_FAIL; } } return THUMB_OK; } static int __check_thumb_path_validity(const char *path) { char dir_name[PATH_MAX + 1] = { 0, }; int len = 0; if (!path || strlen(path) == 0) { thumb_err("Invalid path"); return THUMB_FAIL; } strncpy(dir_name, path, PATH_MAX); len = strlen(dir_name); while (--len) { if (dir_name[len] == '/') { dir_name[len] = '\0'; break; } } if (len == 0) return THUMB_FAIL; if (access(dir_name, W_OK) != 0) { if (errno == EACCES || errno == EPERM) { thumb_err("No permission to write[%s]", dir_name); return THUMB_PERM; } else { thumb_err("Does not exists[%s]", dir_name); return THUMB_FAIL; } } return THUMB_OK; } static int __check_parameter_validity_for_file(const char *path, unsigned int width, unsigned int height, const char *thumb_path) { int err = THUMB_OK; thumb_retvm_if((width > MAX_THUMB_SIZE || width == 0), THUMB_FAIL, "Invalid width[%d]", width); thumb_retvm_if((height > MAX_THUMB_SIZE || height == 0), THUMB_FAIL, "Invalid height[%d]", height); /* Check path is accessible */ err = __check_path_validity(path); thumb_retvm_if(err != THUMB_OK, err, "Invalid path"); /* Check thumbnail path is writable */ err = __check_thumb_path_validity(thumb_path); thumb_retvm_if(err != THUMB_OK, err, "Invalid thumb_path"); return THUMB_OK; } static int __check_parameter_validity_for_buffer(const char *path, unsigned int width, unsigned int height, unsigned char **thumb_buffer, size_t *thumb_size, unsigned int *thumb_width, unsigned int *thumb_height) { thumb_retvm_if((width > MAX_THUMB_SIZE || width == 0), THUMB_FAIL, "Invalid width[%d]", width); thumb_retvm_if((height > MAX_THUMB_SIZE || height == 0), THUMB_FAIL, "Invalid height[%d]", height); thumb_retvm_if(!thumb_buffer || !thumb_size || !thumb_width || !thumb_height, THUMB_FAIL, "Invalid out param"); //Check path is accessible return __check_path_validity(path); } int create_video_thumbnail_to_file(const char *path, unsigned int width, unsigned int height, const char *thumb_path, bool auto_rotate) { int err = THUMB_OK; int video_track_num = 0; unsigned int video_width = 0; unsigned int video_height = 0; void *frame = NULL; size_t frame_size = 0; mm_util_rotate_type_e rot_type = MM_UTIL_ROTATE_NUM; err = __check_parameter_validity_for_file(path, width, height, thumb_path); thumb_retvm_if(err != THUMB_OK, err, "Invalid parameter"); //Get video info err = __get_video_info(path, &video_track_num, &video_width, &video_height, &frame, &frame_size, &rot_type); thumb_retvm_if(err != THUMB_OK, err, "fail to __get_video_info [%d]", err); thumb_retvm_if(video_track_num == 0, THUMB_OK, "No video track"); if (!auto_rotate) rot_type = MM_UTIL_ROTATE_0; //Extract thumbnail err = __get_video_thumb_to_file(video_width, video_height, frame, frame_size, rot_type, thumb_path, width, height); if (frame) free(frame); return err; } int create_video_thumbnail_to_buffer(const char *path, unsigned int width, unsigned int height, unsigned char **thumb_buffer, size_t *thumb_size, unsigned int *thumb_width, unsigned int *thumb_height) { int err = THUMB_OK; int video_track_num = 0; unsigned int video_w = 0; unsigned int video_h = 0; void *frame = NULL; size_t frame_size = 0; mm_util_image_h img = NULL; err = __check_parameter_validity_for_buffer(path, width, height, thumb_buffer, thumb_size, thumb_width, thumb_height); thumb_retvm_if(err != THUMB_OK, err, "Invalid parameter"); //Get video info err = __get_video_info(path, &video_track_num, &video_w, &video_h, &frame, &frame_size, NULL); thumb_retvm_if(err != THUMB_OK, err, "fail to __get_video_info [%d]", err); thumb_retvm_if(video_track_num == 0, THUMB_OK, "No video track"); //Extract thumbnail err = __get_video_thumb_to_buffer(video_w, video_h, frame, frame_size, width, height, &img); if (frame) free(frame); if (err != THUMB_OK) return err; err = mm_image_get_image(img, thumb_width, thumb_height, NULL, thumb_buffer, thumb_size); mm_image_destroy_image(img); return (err == MM_UTIL_ERROR_NONE) ? THUMB_OK : THUMB_FAIL; } static int __adjust_thumb_ratio(const char *path, unsigned int *width, unsigned int *height, unsigned int *image_w, unsigned int *image_h, mm_util_img_codec_type *image_type) { int err = MM_UTIL_ERROR_NONE; #if defined(ENABLE_IMAGE_SIZE_LIMITATION) const size_t image_size_limit[IMG_CODEC_UNKNOWN_TYPE] = { [IMG_CODEC_JPEG] = (4096 * 4096), [IMG_CODEC_PNG] = (3000 * 3000), [IMG_CODEC_GIF] = (3000 * 3000), }; #endif err = mm_util_extract_image_info(path, image_type, image_w, image_h); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_extract_image_info: %d", err); thumb_retvm_if(*image_type == IMG_CODEC_UNKNOWN_TYPE, THUMB_UNSUPPORTED, "Unsupported image codec"); #if defined(ENABLE_IMAGE_SIZE_LIMITATION) if ((*image_type == IMG_CODEC_JPEG) || (*image_type == IMG_CODEC_PNG) || (*image_type == IMG_CODEC_GIF)) if ((size_t)((*image_w) * (*image_h)) > image_size_limit[*image_type]) { thumb_err("Unsupported image size [%u x %u] limit [%zu]", *image_w, *image_h, image_size_limit[*image_type]); return THUMB_UNSUPPORTED; } #endif __media_thumb_get_proper_thumb_size(*image_w, *image_h, width, height); return THUMB_OK; } #if defined(USE_MEMORY_USAGE_REDUCTION) static mm_util_rotate_type_e __get_image_orientation(const char *path) { ExifData *ed = NULL; ExifEntry *entry = NULL; short orientation = 0; mm_util_rotate_type_e rotation = MM_UTIL_ROTATE_0; ed = exif_data_new_from_file(path); thumb_retvm_if(!ed, MM_UTIL_ROTATE_0, "no exif data"); entry = exif_data_get_entry(ed, EXIF_TAG_ORIENTATION); if (!entry) { thumb_info("no orientation entry"); exif_data_unref(ed); return MM_UTIL_ROTATE_0; } orientation = exif_get_short(entry->data, exif_data_get_byte_order(ed)); /* exif orientation * 0 - not available, 1- normal, 2 - hflip, 3 - rot_180, * 4 - vflip, 5 - transpose, 6 - rot_90, 7 - transverse, 8 - rot_270 */ switch (orientation) { case 3: rotation = MM_UTIL_ROTATE_180; break; case 6: rotation = MM_UTIL_ROTATE_90; break; case 8: rotation = MM_UTIL_ROTATE_270; break; default: thumb_warn("not supported orientation[%d], rotation will be 0", orientation); rotation = MM_UTIL_ROTATE_0; break; }; exif_data_unref(ed); thumb_info("orientation: %d, rotation: %d", orientation, rotation); return rotation; } static int __create_gif_thumbnail_to_file(const char *path, unsigned int thumb_w, unsigned int thumb_h, const char *thumb_path) { int err = MM_UTIL_ERROR_NONE; mm_util_image_h decode_image = NULL; err = mm_util_decode_from_gif_file(path, &decode_image); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_decode_from_gif_file failed : %d", err); err = mm_util_resize_B_P(decode_image, thumb_w, thumb_h, thumb_path); mm_image_destroy_image(decode_image); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_resize_B_P failed : %d", err); return THUMB_OK; } static int __create_gif_thumbnail_to_buffer(const char *path, unsigned int thumb_w, unsigned int thumb_h, mm_util_image_h *thumbnail) { int err = MM_UTIL_ERROR_NONE; mm_util_image_h decode_image = NULL; mm_util_image_h rgba_thumbnail = NULL; err = mm_util_decode_from_gif_file(path, &decode_image); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_decode_from_gif_file failed : %d", err); err = mm_util_resize_B_B(decode_image, thumb_w, thumb_h, &rgba_thumbnail); mm_image_destroy_image(decode_image); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_resize_B_B failed : %d", err); err = mm_util_convert_B_B(rgba_thumbnail, MM_UTIL_COLOR_BGRA, thumbnail); mm_image_destroy_image(rgba_thumbnail); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_convert_B_B failed : %d", err); return THUMB_OK; } static int __decode_jpeg_with_downscale(const char *path, size_t image_size, size_t thumb_size, mm_util_image_h *decode_image) { mm_util_jpeg_decode_downscale downscale = MM_UTIL_JPEG_DECODE_DOWNSCALE_1_1; // The downscale divide each width & height, so we should use squares 4(2*2), 16(4*4), 64(8*8). if ((image_size >= thumb_size * 4) && (image_size < thumb_size * 16)) downscale = MM_UTIL_JPEG_DECODE_DOWNSCALE_1_2; else if ((image_size >= thumb_size * 16) && (image_size < thumb_size * 64)) downscale = MM_UTIL_JPEG_DECODE_DOWNSCALE_1_4; else if (image_size >= thumb_size * 64) downscale = MM_UTIL_JPEG_DECODE_DOWNSCALE_1_8; thumb_info("downscale: %d", downscale); return mm_util_decode_from_jpeg_file(path, MM_UTIL_COLOR_BGRA, downscale, decode_image); } static int __create_jpeg_thumbnail_to_file(const char *path, size_t image_size, unsigned int thumb_w, unsigned int thumb_h, const char *thumb_path, bool auto_rotate) { int err = MM_UTIL_ERROR_NONE; mm_util_image_h decode_image = NULL; mm_util_image_h resize_image = NULL; mm_util_rotate_type_e rotation = __get_image_orientation(path); err = __decode_jpeg_with_downscale(path, image_size, (size_t)(thumb_w * thumb_h), &decode_image); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_decode_from_jpeg_file failed : %d", err); if (auto_rotate && (rotation != MM_UTIL_ROTATE_0)) { err = mm_util_resize_B_B(decode_image, thumb_w, thumb_h, &resize_image); mm_image_destroy_image(decode_image); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_resize_B_B failed : %d", err); err = mm_util_rotate_B_P(resize_image, rotation, thumb_path); mm_image_destroy_image(resize_image); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_rotate_B_P failed : %d", err); } else { err = mm_util_resize_B_P(decode_image, thumb_w, thumb_h, thumb_path); mm_image_destroy_image(decode_image); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_resize_B_P failed : %d", err); } return THUMB_OK; } static int __create_jpeg_thumbnail_to_buffer(const char *path, size_t image_size, unsigned int thumb_w, unsigned int thumb_h, mm_util_image_h *thumbnail) { int err = MM_UTIL_ERROR_NONE; mm_util_image_h decode_image = NULL; err = __decode_jpeg_with_downscale(path, image_size, (size_t)(thumb_w * thumb_h), &decode_image); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_decode_from_jpeg_file failed : %d", err); err = mm_util_resize_B_B(decode_image, thumb_w, thumb_h, thumbnail); mm_image_destroy_image(decode_image); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_resize_B_B failed : %d", err); return THUMB_OK; } #endif int create_image_thumbnail_to_file(const char *path, unsigned int width, unsigned int height, const char *thumb_path, bool auto_rotate) { int err = THUMB_OK; unsigned int image_w = 0; unsigned int image_h = 0; unsigned int thumb_w = width; unsigned int thumb_h = height; mm_util_img_codec_type image_type = 0; err = __check_parameter_validity_for_file(path, width, height, thumb_path); thumb_retvm_if(err != THUMB_OK, err, "Invalid parameter"); err = __adjust_thumb_ratio(path, &thumb_w, &thumb_h, &image_w, &image_h, &image_type); thumb_retvm_if(err != THUMB_OK, err, "__adjust_thumb_ratio failed"); #if defined(USE_MEMORY_USAGE_REDUCTION) if (image_type == IMG_CODEC_GIF) return __create_gif_thumbnail_to_file(path, thumb_w, thumb_h, thumb_path); else if (image_type == IMG_CODEC_JPEG) return __create_jpeg_thumbnail_to_file(path, (size_t)(image_w * image_h), thumb_w, thumb_h, thumb_path, auto_rotate); #endif if (auto_rotate) err = mm_util_resize_and_rotate_P_P(path, thumb_w, thumb_h, thumb_path); else err = mm_util_resize_P_P(path, thumb_w, thumb_h, thumb_path); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_resize_P_P failed : %d", err); return THUMB_OK; } int create_image_thumbnail_to_buffer(const char *path, unsigned int width, unsigned int height, unsigned char **thumb_buffer, size_t *thumb_size, unsigned int *thumb_width, unsigned int *thumb_height) { int err = THUMB_OK; unsigned int image_w = 0; unsigned int image_h = 0; unsigned int thumb_w = width; unsigned int thumb_h = height; mm_util_image_h img = NULL; mm_util_img_codec_type image_type = 0; err = __check_parameter_validity_for_buffer(path, width, height, thumb_buffer, thumb_size, thumb_width, thumb_height); thumb_retvm_if(err != THUMB_OK, err, "Invalid parameter"); err = __adjust_thumb_ratio(path, &thumb_w, &thumb_h, &image_w, &image_h, &image_type); thumb_retvm_if(err != THUMB_OK, err, "__adjust_thumb_ratio failed"); #if defined(USE_MEMORY_USAGE_REDUCTION) if (image_type == IMG_CODEC_GIF) { err = __create_gif_thumbnail_to_buffer(path, thumb_w, thumb_h, &img); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "__create_gif_thumbnail_to_buffer failed : %d", err); } else if (image_type == IMG_CODEC_JPEG) { err = __create_jpeg_thumbnail_to_buffer(path, (size_t)(image_w * image_h), thumb_w, thumb_h, &img); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "__create_jpeg_thumbnail_to_buffer failed : %d", err); } else #endif { err = mm_util_resize_P_B(path, thumb_w, thumb_h, MM_UTIL_COLOR_BGRA, &img); thumb_retvm_if(err != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_resize_P_B failed : %d", err); } err = mm_image_get_image(img, thumb_width, thumb_height, NULL, thumb_buffer, thumb_size); mm_image_destroy_image(img); return (err == MM_UTIL_ERROR_NONE) ? THUMB_OK : THUMB_FAIL; } static int __get_media_type(const char *path, thumbnail_media_type_e *media_type) { int ret = THUMB_OK; char mime[MIME_MAX_LEN] = {0,}; ret = __check_path_validity(path); thumb_retv_if(ret != THUMB_OK, ret); ret = aul_get_mime_from_file(path, mime, MIME_MAX_LEN); thumb_retvm_if(ret < 0, THUMB_FAIL, "aul_get_mime_from_file failed"); thumb_dbg("mime type : %s", mime); if (strstr(mime, "image") != NULL) { thumb_retvm_if(!strcmp(mime, MIME_TYPE_TIFF), THUMB_UNSUPPORTED, "Unsupported type"); *media_type = MEDIA_THUMB_IMAGE; return THUMB_OK; } if (strstr(mime, "video") != NULL) { *media_type = MEDIA_THUMB_VIDEO; return THUMB_OK; } if (strcmp(mime, MIME_TYPE_ASF) == 0) { *media_type = MEDIA_THUMB_VIDEO; return THUMB_OK; } return THUMB_UNSUPPORTED; } int create_thumbnail_to_buffer(const char *path, unsigned int width, unsigned int height, unsigned char **thumb_buffer, size_t *thumb_size, unsigned int *thumb_width, unsigned int *thumb_height) { int ret = THUMB_OK; thumbnail_media_type_e type = MEDIA_THUMB_INVALID; ret = __get_media_type(path, &type); thumb_retvm_if(ret != THUMB_OK, ret, "__get_media_type failed"); if (type == MEDIA_THUMB_IMAGE) return create_image_thumbnail_to_buffer(path, width, height, thumb_buffer, thumb_size, thumb_width, thumb_height); else return create_video_thumbnail_to_buffer(path, width, height, thumb_buffer, thumb_size, thumb_width, thumb_height); } int create_thumbnail_to_file(const char *path, unsigned int width, unsigned int height, const char *thumb_path) { int ret = THUMB_OK; regex_t regex; thumbnail_media_type_e type = MEDIA_THUMB_INVALID; ret = __get_media_type(path, &type); thumb_retvm_if(ret != THUMB_OK, ret, "__get_media_type failed"); if (type == MEDIA_THUMB_IMAGE) return create_image_thumbnail_to_file(path, width, height, thumb_path, false); if (regcomp(®ex, "[^/]\\.jpe?g$", REG_ICASE | REG_EXTENDED) != 0) { thumb_err("regcomp failed"); return THUMB_FAIL; } if (regexec(®ex, thumb_path, 0, NULL, 0) == REG_NOMATCH) { thumb_err("Unsupported path or extensions [%s]", thumb_path); return THUMB_FAIL; } regfree(®ex); return create_video_thumbnail_to_file(path, width, height, thumb_path, false); } int get_image_info(const char *path, unsigned int *width, unsigned int *height) { int ret = MM_UTIL_ERROR_NONE; ret = mm_util_extract_image_info(path, NULL, width, height); thumb_retvm_if(ret != MM_UTIL_ERROR_NONE, THUMB_FAIL, "mm_util_extract_image_info failed"); return THUMB_OK; }