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 "img-codec-parser.h"
29 #include <sys/types.h>
34 #include <mm_util_magick.h>
36 int _media_thumb_get_proper_thumb_size(int orig_w, int orig_h, int *thumb_w, int *thumb_h)
38 bool portrait = false;
44 /* Set smaller length to default size */
46 if (orig_w < *thumb_w)
48 ratio = (double)orig_h / (double)orig_w;
49 *thumb_h = *thumb_w * ratio;
51 if (orig_h < *thumb_h)
53 ratio = (double)orig_w / (double)orig_h;
54 *thumb_w = *thumb_h * ratio;
57 thumb_dbg("proper thumb w: %d h: %d", *thumb_w, *thumb_h);
59 return MS_MEDIA_ERR_NONE;
62 int _media_thumb_general(const char *origin_path, const char *thumb_path, int thumb_width, int thumb_height, media_thumb_info *thumb_info)
64 int err = MS_MEDIA_ERR_NONE;
65 mm_util_image_h img = NULL;
66 unsigned char *buf = NULL;
67 unsigned int width = 0;
68 unsigned int height = 0;
70 mm_util_magick_format format = MM_UTIL_IMG_FMT_NUM;
72 if (thumb_path != NULL) {
73 err = mm_util_resize_P_P(origin_path, thumb_width, thumb_height, thumb_path);
75 err = mm_util_resize_P_B(origin_path, thumb_width, thumb_height, MM_UTIL_IMG_FMT_BGRA8888, &img);
76 if (err != MM_UTIL_ERROR_NONE) {
77 thumb_err("mm_util_resize_P_B failed : %d", err);
78 return MS_MEDIA_ERR_INTERNAL;
81 mm_util_get_image(img, &buf, &width, &height, &size, &format);
82 thumb_info->data = calloc(1, size);
83 memcpy(thumb_info->data, buf, size);
84 thumb_info->size = size;
85 thumb_info->width = width;
86 thumb_info->height = height;
88 mm_util_destroy_handle(img);
94 int _media_thumb_image(const char *origin_path, char *thumb_path, int thumb_width, int thumb_height, media_thumb_info *thumb_info)
96 int err = MS_MEDIA_ERR_NONE;
97 ImgCodecType image_type = 0;
98 unsigned int origin_w = 0;
99 unsigned int origin_h = 0;
101 err = ImgGetImageInfo(origin_path, &image_type, &origin_w, &origin_h);
102 if (err != MS_MEDIA_ERR_NONE) {
103 thumb_warn("Getting image info is failed err: %d", err);
104 return MS_MEDIA_ERR_INTERNAL;
107 if ((image_type != IMG_CODEC_JPEG) && (origin_w * origin_h > THUMB_MAX_ALLOWED_MEM_FOR_THUMB)) {
108 thumb_warn("This original image is too big");
109 return MS_MEDIA_ERR_THUMB_TOO_BIG;
112 _media_thumb_get_proper_thumb_size(origin_w, origin_h, &thumb_width, &thumb_height);
114 if (image_type == IMG_CODEC_PNG) {
115 if (thumb_path != NULL) {
117 err = _media_thumb_get_file_ext(origin_path, file_ext, sizeof(file_ext));
118 if (strncasecmp(file_ext, "png", 3) == 0) {
119 int len = strlen(thumb_path);
120 thumb_path[len - 3] = 'p';
121 thumb_path[len - 2] = 'n';
122 thumb_path[len - 1] = 'g';
125 err = _media_thumb_general(origin_path, thumb_path, thumb_width, thumb_height, thumb_info);
126 } else if (image_type == IMG_CODEC_JPEG || image_type == IMG_CODEC_AGIF || image_type == IMG_CODEC_GIF || image_type == IMG_CODEC_BMP || image_type == IMG_CODEC_WBMP) {
127 err = _media_thumb_general(origin_path, thumb_path, thumb_width, thumb_height, thumb_info);
129 thumb_warn("Unsupported image type");
130 return MS_MEDIA_ERR_THUMB_UNSUPPORTED;
136 int _media_thumb_video(const char *origin_path, const char *thumb_path, int thumb_width, int thumb_height, media_thumb_info *thumb_info)
138 int err = MS_MEDIA_ERR_NONE;
140 MMHandleType content = (MMHandleType) NULL;
141 MMHandleType tag = (MMHandleType) NULL;
146 int video_track_num = 0;
147 char *err_msg = NULL;
151 mm_util_image_h img = NULL;
152 mm_util_image_h resize_img = NULL;
153 mm_util_image_h dst_img = NULL;
155 unsigned char *res_buf = NULL;
157 unsigned int res_width = 0;
158 unsigned int res_height = 0;
159 mm_util_magick_format res_format;
161 /* Get Content Tag attribute for orientation */
162 err = mm_file_create_tag_attrs(&tag, origin_path);
163 mm_util_magick_rotate_type rot_type = MM_UTIL_ROTATE_NUM;
165 if (err == FILEINFO_ERROR_NONE) {
166 err = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_ROTATE, &p, &size, NULL);
167 if (err == FILEINFO_ERROR_NONE && size >= 0) {
169 rot_type = MM_UTIL_ROTATE_0;
171 if (strncmp(p, "90", size) == 0)
172 rot_type = MM_UTIL_ROTATE_90;
173 else if (strncmp(p, "180", size) == 0)
174 rot_type = MM_UTIL_ROTATE_180;
175 else if (strncmp(p, "270", size) == 0)
176 rot_type = MM_UTIL_ROTATE_270;
178 rot_type = MM_UTIL_ROTATE_0;
180 thumb_dbg("There is tag rotate : %d", rot_type);
182 thumb_dbg("There is NOT tag rotate");
183 rot_type = MM_UTIL_ROTATE_0;
187 err = mm_file_get_attrs(tag, &err_msg, MM_FILE_TAG_CDIS, &cdis_value, NULL);
188 if (err != FILEINFO_ERROR_NONE) {
193 rot_type = MM_UTIL_ROTATE_0;
197 err = mm_file_destroy_tag_attrs(tag);
198 if (err != FILEINFO_ERROR_NONE) {
199 thumb_err("fail to free tag attr - err(%x)", err);
202 if (cdis_value == 1) {
203 thumb_warn("This is CDIS vlaue 1");
204 err = mm_file_create_content_attrs_safe(&content, origin_path);
206 err = mm_file_create_content_attrs(&content, origin_path);
209 if (err != FILEINFO_ERROR_NONE) {
210 thumb_err("mm_file_create_content_attrs fails : %d", err);
211 return MS_MEDIA_ERR_INTERNAL;
214 err = mm_file_get_attrs(content, &err_msg, MM_FILE_CONTENT_VIDEO_TRACK_COUNT, &video_track_num, NULL);
215 if (err != FILEINFO_ERROR_NONE) {
216 thumb_err("mm_file_get_attrs fails : %s", err_msg);
221 if (video_track_num > 0) {
222 err = mm_file_get_attrs(content, &err_msg,
223 MM_FILE_CONTENT_VIDEO_WIDTH,
225 MM_FILE_CONTENT_VIDEO_HEIGHT,
227 MM_FILE_CONTENT_VIDEO_THUMBNAIL, &frame, /* raw image is RGB888 format */
230 if (err != FILEINFO_ERROR_NONE) {
231 thumb_err("mm_file_get_attrs fails : %s", err_msg);
236 thumb_dbg("W[%d] H[%d] Size[%d] Frame[%p] Rotate[%d]", width, height, size, frame, rot_type);
237 if (frame == NULL || width == 0 || height == 0) {
238 thumb_err("Failed to get frame data");
242 err = _media_thumb_get_proper_thumb_size(width, height, &thumb_width, &thumb_height);
243 if (thumb_width <= 0 || thumb_height <= 0) {
244 thumb_err("Failed to get thumb size");
248 thumb_dbg("Origin:W[%d] H[%d] Proper:W[%d] H[%d]", width, height, thumb_width, thumb_height);
250 err = mm_util_create_handle(&img, (unsigned char *)frame, width, height, size, MM_UTIL_IMG_FMT_RGB888);
251 if (width > thumb_width || height > thumb_height) {
252 if (rot_type != MM_UTIL_ROTATE_0) {
253 if (STRING_VALID(thumb_path)) {
254 err = mm_util_resize_B_B(img, thumb_width, thumb_height, &resize_img);
255 if (err != MM_UTIL_ERROR_NONE)
257 err = mm_util_rotate_B_P(resize_img, rot_type, thumb_path);
259 err = mm_util_resize_B_B(img, thumb_width, thumb_height, &resize_img);
260 if (err != MM_UTIL_ERROR_NONE)
262 err = mm_util_rotate_B_B(resize_img, rot_type, &dst_img);
263 if (err != MM_UTIL_ERROR_NONE)
265 mm_util_get_image(dst_img, &res_buf, &res_width, &res_height, &res_size, &res_format);
266 thumb_info->data = calloc(1, res_size);
267 memcpy(thumb_info->data, res_buf, res_size);
268 thumb_info->size = res_size;
269 thumb_info->width = res_width;
270 thumb_info->height = res_height;
274 if (STRING_VALID(thumb_path)) {
275 err = mm_util_resize_B_P(img, thumb_width, thumb_height, thumb_path);
277 err = mm_util_resize_B_B(img, thumb_width, thumb_height, &resize_img);
278 if (err != MM_UTIL_ERROR_NONE)
280 mm_util_get_image(resize_img, &res_buf, &res_width, &res_height, &res_size, &res_format);
281 thumb_info->data = calloc(1, res_size);
282 memcpy(thumb_info->data, res_buf, res_size);
283 thumb_info->size = res_size;
284 thumb_info->width = res_width;
285 thumb_info->height = res_height;
290 if (rot_type != MM_UTIL_ROTATE_0) {
291 if (STRING_VALID(thumb_path)) {
292 err = mm_util_rotate_B_P(img, rot_type, thumb_path);
294 err = mm_util_rotate_B_B(img, rot_type, &dst_img);
295 if (err != MM_UTIL_ERROR_NONE)
297 mm_util_get_image(dst_img, &res_buf, &res_width, &res_height, &res_size, &res_format);
298 thumb_info->data = calloc(1, res_size);
299 memcpy(thumb_info->data, res_buf, res_size);
300 thumb_info->size = res_size;
301 thumb_info->width = res_width;
302 thumb_info->height = res_height;
306 if (STRING_VALID(thumb_path)) {
307 err = mm_util_resize_B_P(img, width, height, thumb_path);
309 thumb_info->data = calloc(1, size);
310 memcpy(thumb_info->data, frame, size);
311 thumb_info->size = size;
312 thumb_info->width = width;
313 thumb_info->height = height;
320 mm_util_destroy_handle(img);
321 mm_util_destroy_handle(resize_img);
322 mm_util_destroy_handle(dst_img);
323 mm_file_destroy_content_attrs(content);
325 if (err != MS_MEDIA_ERR_NONE)
326 return MS_MEDIA_ERR_INTERNAL;
328 return MS_MEDIA_ERR_NONE;
331 int _media_thumb_get_hash_name(const char *file_full_path, char *thumb_hash_path, size_t max_thumb_path, uid_t uid)
333 char *hash_name = NULL;
334 char file_ext[255] = { 0 };
335 char *get_path = NULL;
337 ms_user_storage_type_e storage_type = -1;
338 int ret = MS_MEDIA_ERR_NONE;
340 if (file_full_path == NULL || thumb_hash_path == NULL || max_thumb_path <= 0) {
341 thumb_err("file_full_path==NULL || thumb_hash_path == NULL || max_thumb_path <= 0");
342 return MS_MEDIA_ERR_INVALID_PARAMETER;
345 _media_thumb_get_file_ext(file_full_path, file_ext, sizeof(file_ext));
347 ret = ms_user_get_storage_type(uid, file_full_path, &storage_type);
348 if ((ret != MS_MEDIA_ERR_NONE) || ((storage_type != MS_USER_STORAGE_INTERNAL) && (storage_type != MS_USER_STORAGE_EXTERNAL))) {
349 thumb_err_slog("origin path(%s) is invalid. err : [%d] storage_type [%d]", file_full_path, ret, storage_type);
350 return MS_MEDIA_ERR_INVALID_PARAMETER;
353 hash_name = _media_thumb_generate_hash_name(file_full_path);
354 if (hash_name == NULL) {
355 thumb_err("_media_thumb_generate_hash_name fail");
356 return MS_MEDIA_ERR_INTERNAL;
359 ret = ms_user_get_thumb_store_path(uid, storage_type, &get_path);
360 if (get_path != NULL)
361 ret_len = snprintf(thumb_hash_path, max_thumb_path - 1, "%s/.%s-%s.jpg", get_path, file_ext, hash_name);
365 if ((ret_len < 0) || (ret_len > (int)max_thumb_path)) {
366 thumb_err("invalid hash path ret_len[%d]", ret_len);
367 return MS_MEDIA_ERR_INTERNAL;
370 return MS_MEDIA_ERR_NONE;