static __thread int transaction_ver = 0;
static __thread bool version_up = false;
-#define CTS_SECURITY_IMAGE_PERMISSION 0440
-#define CTS_IMAGE_ENCODE_QUALITY 50
+struct image_transform{
+ int ret;
+ uint64_t size;
+ void *buffer;
+ GCond cond;
+ GMutex mutex;
+};
+#define CTS_SECURITY_IMAGE_PERMISSION 0440
+#define CTS_IMAGE_ENCODE_QUALITY 50
+#define CTS_IMAGE_MAX_SIZE 1080
#define CTS_COMMIT_TRY_MAX 500000 // For 3second
+#define CTS_IMAGE_TRANSFORM_WAIT_TIME 500 * G_TIME_SPAN_MILLISECOND /* 0.5 sec */
int ctsvc_begin_trans(void)
{
return false;
}
-static image_util_rotation_e __ctsvc_get_rotation_info(const char *path)
+static image_util_rotation_e _ctsvc_image_get_rotation_info(const char *path)
{
ExifData *ed = NULL;
ExifEntry *entry;
exif_data_unref(ed);
switch(orientation) {
- case 1: // Top-left
+ case 1: /* Top-left */
rotation = IMAGE_UTIL_ROTATION_NONE;
break;
- case 2: // Top-right
+ case 2: /* Top-right */
rotation = IMAGE_UTIL_ROTATION_FLIP_HORZ;
break;
- case 3: // Bottom-right
+ case 3: /* Bottom-right */
rotation = IMAGE_UTIL_ROTATION_180;
break;
- case 4: // Bottom-left
+ case 4: /* Bottom-left */
rotation = IMAGE_UTIL_ROTATION_FLIP_VERT;
break;
- case 6: // Right-top
+ case 6: /* Right-top */
rotation = IMAGE_UTIL_ROTATION_90;
break;
- case 8: // Left-bottom
+ case 8: /* Left-bottom */
rotation = IMAGE_UTIL_ROTATION_270;
break;
- case 5: // Left-top
- case 7: // Right-bottom
+ case 5: /* Left-top */
+ case 7: /* Right-bottom */
case 0:
default:
break;
return rotation;
}
-static int image_size = 480;
typedef struct {
const char *src;
int ret;
}image_info;
-static bool __ctsvc_image_util_supported_jpeg_colorspace_cb(image_util_colorspace_e colorspace, void *user_data)
+static int _ctsvc_image_get_mimetype(image_util_colorspace_e colorspace,
+ int *p_mimetype)
{
- image_info *info = (image_info*)user_data;
- image_util_error_e ret;
- int width = 0, height = 0;
- unsigned int size_decode = 0;
- int resized_width, resized_height;
- unsigned char * img_target = 0;
- unsigned char * img_source = 0;
- int dest_fd;
- image_util_rotation_e rotation;
+ media_format_mimetype_e mimetype;
+ switch (colorspace) {
+ case IMAGE_UTIL_COLORSPACE_YUV422:
+ mimetype = MEDIA_FORMAT_422P;
+ break;
+ case IMAGE_UTIL_COLORSPACE_NV12:
+ mimetype = MEDIA_FORMAT_NV12;
+ break;
+ case IMAGE_UTIL_COLORSPACE_UYVY:
+ mimetype = MEDIA_FORMAT_UYVY;
+ break;
+ case IMAGE_UTIL_COLORSPACE_YUYV:
+ mimetype = MEDIA_FORMAT_YUYV;
+ break;
+ case IMAGE_UTIL_COLORSPACE_RGB565:
+ mimetype = MEDIA_FORMAT_RGB565;
+ break;
+ case IMAGE_UTIL_COLORSPACE_RGB888:
+ mimetype = MEDIA_FORMAT_RGB888;
+ break;
+ case IMAGE_UTIL_COLORSPACE_ARGB8888:
+ mimetype = MEDIA_FORMAT_ARGB;
+ break;
+ case IMAGE_UTIL_COLORSPACE_RGBA8888:
+ mimetype = MEDIA_FORMAT_RGBA;
+ break;
+ case IMAGE_UTIL_COLORSPACE_NV21:
+ mimetype = MEDIA_FORMAT_NV21;
+ break;
+ case IMAGE_UTIL_COLORSPACE_NV16:
+ mimetype = MEDIA_FORMAT_NV16;
+ break;
+ case IMAGE_UTIL_COLORSPACE_BGRA8888: /* not supported */
+ case IMAGE_UTIL_COLORSPACE_BGRX8888: /* not supported */
+ case IMAGE_UTIL_COLORSPACE_NV61: /* not supported */
+ case IMAGE_UTIL_COLORSPACE_YV12: /* not supported */
+ case IMAGE_UTIL_COLORSPACE_I420: /* not supported */
+ default:
+ return CONTACTS_ERROR_INVALID_PARAMETER;
+ }
+ *p_mimetype = mimetype;
+ return CONTACTS_ERROR_NONE;
+}
+
+static media_format_h _ctsvc_image_create_media_format(int mimetype, int width,
+ int height)
+{
+ int ret;
+ media_format_h fmt = NULL;
+
+ ret = media_format_create(&fmt);
+ if (MEDIA_FORMAT_ERROR_NONE != ret) {
+ CTS_ERR("media_format_create() Fail(%d)", ret);
+ return NULL;
+ }
+
+ ret = media_format_set_video_mime(fmt, mimetype);
+ if (MEDIA_FORMAT_ERROR_NONE != ret) {
+ CTS_ERR("media_format_set_video_mime() Fail(%d)", ret);
+ media_format_unref(fmt);
+ return NULL;
+ }
+
+ ret = media_format_set_video_width(fmt, width);
+ if (MEDIA_FORMAT_ERROR_NONE != ret) {
+ CTS_ERR("media_format_set_video_width() Fail(%d)", ret);
+ media_format_unref(fmt);
+ return NULL;
+ }
+
+ ret = media_format_set_video_height(fmt, height);
+ if (MEDIA_FORMAT_ERROR_NONE != ret) {
+ CTS_ERR("media_format_set_video_height() Fail(%d)", ret);
+ media_format_unref(fmt);
+ return NULL;
+ }
+
+ ret = media_format_set_video_avg_bps(fmt, 2000000); /* image_util guide */
+ if (MEDIA_FORMAT_ERROR_NONE != ret) {
+ CTS_ERR("media_format_set_video_avg_bps() Fail(%d)", ret);
+ media_format_unref(fmt);
+ return NULL;
+ }
+
+ ret = media_format_set_video_max_bps(fmt, 15000000); /* image_util guide */
+ if (MEDIA_FORMAT_ERROR_NONE != ret) {
+ CTS_ERR("media_format_set_video_max_bps() Fail(%d)", ret);
+ media_format_unref(fmt);
+ return NULL;
+ }
+
+ return fmt;
+}
- // temporary code
- if (colorspace == IMAGE_UTIL_COLORSPACE_YV12 || colorspace == IMAGE_UTIL_COLORSPACE_I420) {
+static int _ctsvc_image_packet_create_alloc_finalize_cb(media_packet_h packet,
+ int error_code, void *user_data)
+{
+ return MEDIA_PACKET_FINALIZE;
+}
+
+static media_packet_h _ctsvc_image_create_media_packet(media_format_h fmt,
+ void *buffer, unsigned int buffer_size)
+{
+ int ret;
+ void *mp_buffer = NULL;
+ media_packet_h packet = NULL;
+ uint64_t mp_buffer_size = 0;
+
+ RETV_IF(NULL == fmt, NULL);
+ RETV_IF(NULL == buffer, NULL);
+
+ ret = media_packet_create_alloc(fmt, _ctsvc_image_packet_create_alloc_finalize_cb,
+ NULL, &packet);
+ if (MEDIA_PACKET_ERROR_NONE != ret) {
+ CTS_ERR("media_packet_create_alloc() Fail(%d)", ret);
+ return NULL;
+ }
+
+ ret = media_packet_get_buffer_size(packet, &mp_buffer_size);
+ if (MEDIA_PACKET_ERROR_NONE != ret) {
+ CTS_ERR("media_packet_get_buffer_size() Fail(%d)", ret);
+ media_packet_destroy(packet);
+ return NULL;
+ }
+
+ ret = media_packet_get_buffer_data_ptr(packet, &mp_buffer);
+ if (MEDIA_PACKET_ERROR_NONE != ret) {
+ CTS_ERR("media_packet_get_buffer_data_ptr() Fail(%d)", ret);
+ media_packet_destroy(packet);
+ return NULL;
+ }
+
+ if (mp_buffer)
+ memcpy(mp_buffer, buffer, (int)buffer_size);
+
+ return packet;
+}
+
+static void _ctsvc_image_transform_completed_cb(media_packet_h *dst,
+ image_util_error_e error, void *user_data)
+{
+ int ret;
+ uint64_t size = 0;
+ void *buffer = 0;
+ struct image_transform *info = user_data;
+
+ if (NULL == info) {
+ media_packet_destroy(*dst);
+ return;
+ }
+
+ if (IMAGE_UTIL_ERROR_NONE == error) {
+ ret = media_packet_get_buffer_size(*dst, &size);
+ if (MEDIA_PACKET_ERROR_NONE != ret) {
+ CTS_ERR("media_packet_get_buffer_size() Fail(%d)", ret);
+ info->ret = CONTACTS_ERROR_SYSTEM;
+ media_packet_destroy(*dst);
+ g_mutex_lock(&info->mutex);
+ g_cond_signal(&info->cond);
+ g_mutex_unlock(&info->mutex);
+ return;
+ }
+
+ ret = media_packet_get_buffer_data_ptr(*dst, &buffer);
+ if (MEDIA_PACKET_ERROR_NONE != ret) {
+ CTS_ERR("media_packet_get_buffer_data_ptr() Fail(%d)", ret);
+ info->ret = CONTACTS_ERROR_SYSTEM;
+ media_packet_destroy(*dst);
+ g_mutex_lock(&info->mutex);
+ g_cond_signal(&info->cond);
+ g_mutex_unlock(&info->mutex);
+ return;
+ }
+
+ info->buffer = calloc(1, (int)size);
+ if (NULL == info->buffer) {
+ CTS_ERR("calloc() Fail");
+ info->ret = CONTACTS_ERROR_SYSTEM;
+ media_packet_destroy(*dst);
+ g_mutex_lock(&info->mutex);
+ g_cond_signal(&info->cond);
+ g_mutex_unlock(&info->mutex);
+ return;
+ }
+ memcpy(info->buffer, buffer, (int)size);
+ info->size = size;
+ info->ret = CONTACTS_ERROR_NONE;
+ }
+ else {
+ CTS_ERR("transform_run() Fail(%d)", error);
info->ret = CONTACTS_ERROR_SYSTEM;
- return true;
}
+ media_packet_destroy(*dst);
+ g_mutex_lock(&info->mutex);
+ g_cond_signal(&info->cond);
+ g_mutex_unlock(&info->mutex);
+}
- rotation = __ctsvc_get_rotation_info(info->src);
+static int _ctsvc_image_util_transform_run(transformation_h transform,
+ media_packet_h packet, void **p_buffer, uint64_t *p_size)
+{
+ gint64 end_time;
+ struct image_transform *info = NULL;
+
+ RETV_IF(NULL == transform, CONTACTS_ERROR_INVALID_PARAMETER);
+ RETV_IF(NULL == packet, CONTACTS_ERROR_INVALID_PARAMETER);
+
+ info = calloc(1, sizeof(struct image_transform));
+ if (NULL == info) {
+ CTS_ERR("calloc() Fail");
+ return CONTACTS_ERROR_OUT_OF_MEMORY;
+ }
- // load jpeg sample file
- CTS_DBG("colorspace %d src : %s, dest : %s", colorspace, info->src, info->dest);
- ret = image_util_decode_jpeg(info->src, colorspace, &img_source, &width, &height, &size_decode);
- if (ret!=IMAGE_UTIL_ERROR_NONE) {
+ g_cond_init(&info->cond);
+ g_mutex_init(&info->mutex);
+
+ g_mutex_lock(&info->mutex);
+ image_util_transform_run(transform, packet, _ctsvc_image_transform_completed_cb, info);
+
+ end_time = g_get_monotonic_time() + CTS_IMAGE_TRANSFORM_WAIT_TIME;
+ if (!g_cond_wait_until(&info->cond, &info->mutex, end_time)) {
+ /* timeout has passed */
+ CTS_ERR("g_cond_wait_until() return FALSE");
info->ret = CONTACTS_ERROR_SYSTEM;
- return true;
}
+ g_mutex_unlock(&info->mutex);
+ g_mutex_clear(&info->mutex);
+ g_cond_clear(&info->cond);
+
+ if (CONTACTS_ERROR_NONE != info->ret) {
+ CTS_ERR("image_util_transform_run() Fail(%d)", info->ret);
+ free(info->buffer);
+ free(info);
+ return CONTACTS_ERROR_SYSTEM;
+ }
+
+ *p_size = info->size;
+ *p_buffer = info->buffer;
+ free(info);
+
+ return CONTACTS_ERROR_NONE;
+}
-#if 0
- if (0>image_size) {
- int w,h;
- ecore_x_window_size_get(
- ecore_x_window_root_get(ecore_x_window_focus_get())
- , &w, &h);
+static int _ctsvc_image_rotate(media_packet_h packet, image_util_rotation_e rotation,
+ void **p_buffer, uint64_t *p_size)
+{
+ int ret;
+ transformation_h transform = NULL;
- if (w>h)
- image_size = h;
- else
- image_size = w;
+ ret = image_util_transform_create(&transform);
+ if (IMAGE_UTIL_ERROR_NONE != ret) {
+ CTS_ERR("image_util_transform_create() Fail(%d)", ret);
+ return CONTACTS_ERROR_SYSTEM;
+ }
+ ret = image_util_transform_set_rotation(transform, rotation);
+ if (IMAGE_UTIL_ERROR_NONE != ret) {
+ CTS_ERR("image_util_transform_set_rotation() Fail(%d)", ret);
+ image_util_transform_destroy(transform);
+ return CONTACTS_ERROR_SYSTEM;
}
-#endif
- if (image_size < width || image_size < height) {
- // image resize
- if (image_size<=0 || width <=0 || height <= 0) {
- free(img_source);
- CTS_ERR("image size error(%d)", image_size);
+ ret = _ctsvc_image_util_transform_run(transform, packet, p_buffer, p_size);
+
+ image_util_transform_destroy(transform);
+ return ret;
+}
+
+static int _ctsvc_image_resize(media_packet_h packet, int width, int height,
+ void **p_buffer, uint64_t *p_size)
+{
+ int ret;
+ transformation_h transform = NULL;
+
+ ret = image_util_transform_create(&transform);
+ if (IMAGE_UTIL_ERROR_NONE != ret) {
+ CTS_ERR("image_util_transform_create() Fail(%d)", ret);
+ return CONTACTS_ERROR_SYSTEM;
+ }
+
+ ret = image_util_transform_set_resolution(transform, width, height);
+ if (IMAGE_UTIL_ERROR_NONE != ret) {
+ CTS_ERR("image_util_transform_set_resolution() Fail(%d)", ret);
+ image_util_transform_destroy(transform);
+ return CONTACTS_ERROR_SYSTEM;
+ }
+
+ ret = _ctsvc_image_util_transform_run(transform, packet, p_buffer, p_size);
+
+ image_util_transform_destroy(transform);
+
+ return ret;
+}
+
+static bool _ctsvc_image_util_supported_jpeg_colorspace_cb(
+ image_util_colorspace_e colorspace, void *user_data)
+{
+ int width = 0;
+ int height = 0;
+ int dest_fd = 0;
+ int mimetype = 0;
+ unsigned int size = 0;
+ void *buffer = NULL;
+ void *buffer_temp = NULL;
+ int ret;
+ image_util_rotation_e rotation;
+ image_info *info = user_data;
+
+ ret = _ctsvc_image_get_mimetype(colorspace, &mimetype);
+ if (CONTACTS_ERROR_NONE != ret) {
+ info->ret = CONTACTS_ERROR_SYSTEM;
+ return true;
+ }
+
+ ret = image_util_decode_jpeg(info->src, colorspace, (unsigned char **)&buffer, &width,
+ &height, &size);
+ if (IMAGE_UTIL_ERROR_NONE != ret) {
+ info->ret = CONTACTS_ERROR_SYSTEM;
+ return true;
+ }
+
+ rotation = _ctsvc_image_get_rotation_info(info->src);
+ if (IMAGE_UTIL_ROTATION_NONE != rotation) { /* need rotate */
+ media_format_h fmt;
+ media_packet_h packet;
+
+ fmt = _ctsvc_image_create_media_format(mimetype, width, height);
+ if (NULL == fmt) {
+ CTS_ERR("_ctsvc_image_create_media_format() Fail");
info->ret = CONTACTS_ERROR_SYSTEM;
+ free(buffer);
return false;
}
- if (height < width) {
- resized_width = image_size;
- resized_height = height*image_size/width;
+ packet = _ctsvc_image_create_media_packet(fmt, buffer, size);
+ if (NULL == packet) {
+ CTS_ERR("_ctsvc_image_create_media_packet() Fail");
+ media_format_unref(fmt);
+ info->ret = CONTACTS_ERROR_SYSTEM;
+ free(buffer);
+ return false;
}
- else {
- resized_height = image_size;
- resized_width = width*image_size/height;
+
+ ret = _ctsvc_image_rotate(packet, rotation, &buffer_temp, (uint64_t *)&size);
+
+ media_packet_destroy(packet);
+ media_format_unref(fmt);
+
+ if (CONTACTS_ERROR_NONE != ret) {
+ free(buffer);
+ info->ret = CONTACTS_ERROR_SYSTEM;
+ return false;
}
- if (resized_height%8)
- resized_height += 8 - (resized_height%8);
- if (resized_width%8)
- resized_width += 8 - (resized_width%8);
+ if (rotation == IMAGE_UTIL_ROTATION_90 || rotation == IMAGE_UTIL_ROTATION_270) {
+ int temp = width;
+ width = height;
+ height = temp;
+ }
+ free(buffer);
+ buffer = buffer_temp;
+ }
- CTS_DBG("size(%d, %d) -> resize(%d,%d)", width, height, resized_width, resized_height);
+ if (CTS_IMAGE_MAX_SIZE < width || CTS_IMAGE_MAX_SIZE < height) { /* need resize */
+ int resized_width;
+ int resized_height;
+ media_format_h fmt;
+ media_packet_h packet;
- image_util_calculate_buffer_size(resized_width, resized_height, colorspace, &size_decode);
+ /* set resize */
+ if (width>height) {
+ resized_width = CTS_IMAGE_MAX_SIZE;
+ resized_height = height * CTS_IMAGE_MAX_SIZE / width;
+ }
+ else {
+ resized_height = CTS_IMAGE_MAX_SIZE;
+ resized_width = width * CTS_IMAGE_MAX_SIZE / height;
+ }
+
+ if (resized_height % 8)
+ resized_height += (8 - (resized_height % 8));
- img_target = malloc(size_decode);
+ if (resized_width % 8)
+ resized_width += (8 - (resized_width % 8));
- // do resize
- ret = image_util_resize(img_target, &resized_width, &resized_height,
- img_source, width, height, colorspace);
- if (ret!=IMAGE_UTIL_ERROR_NONE) {
- CTS_ERR("image_util_resize Fail(%d)", ret);
- free(img_target);
- free(img_source);
+ fmt = _ctsvc_image_create_media_format(mimetype, width, height);
+ if (NULL == fmt) {
+ CTS_ERR("_ctsvc_image_create_media_format() Fail");
info->ret = CONTACTS_ERROR_SYSTEM;
+ free(buffer);
return false;
}
- free(img_source);
- }
- else {
- resized_width = width;
- resized_height = height;
- img_target = img_source;
- }
-
- // image rotation
- if (IMAGE_UTIL_ROTATION_NONE != rotation) {
- int rotated_width, rotated_height;
- unsigned char *img_rotate = 0;
- img_rotate = malloc(size_decode);
- ret= image_util_rotate(img_rotate, &rotated_width, &rotated_height,
- rotation, img_target, resized_width, resized_height, colorspace);
- free(img_target);
- if (IMAGE_UTIL_ERROR_NONE != ret) {
- CTS_ERR("image_util_rotate Fail(%d)", ret);
+
+ packet = _ctsvc_image_create_media_packet(fmt, buffer, size);
+ if (NULL == packet) {
+ CTS_ERR("_ctsvc_image_create_media_packet() Fail");
+ media_format_unref(fmt);
info->ret = CONTACTS_ERROR_SYSTEM;
- free(img_rotate);
+ free(buffer);
+ return false;
+ }
+
+ ret = _ctsvc_image_resize(packet, resized_width, resized_height, &buffer_temp,
+ (uint64_t *)&size);
+
+ media_packet_destroy(packet);
+ media_format_unref(fmt);
+
+ if (CONTACTS_ERROR_NONE != ret) {
+ free(buffer);
+ info->ret = -1;
return false;
}
- resized_width = rotated_width;
- resized_height = rotated_height;
- img_target = img_rotate;
+ free(buffer);
+ buffer = buffer_temp;
+
+ width = resized_width;
+ height = resized_height;
}
- // image encode
- ret = image_util_encode_jpeg(img_target, resized_width, resized_height, colorspace, CTS_IMAGE_ENCODE_QUALITY, info->dest);
- free(img_target);
- if (ret != IMAGE_UTIL_ERROR_NONE) {
+ ret = image_util_encode_jpeg(buffer, width, height, colorspace,
+ CTS_IMAGE_ENCODE_QUALITY, info->dest);
+ free(buffer);
+ if (IMAGE_UTIL_ERROR_NONE != ret) {
CTS_ERR("image_util_encode_jpeg Fail(%d)", ret);
info->ret = CONTACTS_ERROR_SYSTEM;
return false;
return false;
}
-static int __ctsvc_resize_and_copy_image(const char *src, const char *dest)
+static int _ctsvc_image_encode(const char *src, const char *dest)
{
int ret;
image_info info = {.src = src, .dest = dest, ret = CONTACTS_ERROR_SYSTEM};
- ret = image_util_foreach_supported_jpeg_colorspace(__ctsvc_image_util_supported_jpeg_colorspace_cb, &info);
+ ret = image_util_foreach_supported_jpeg_colorspace(
+ _ctsvc_image_util_supported_jpeg_colorspace_cb, &info);
- if (ret != IMAGE_UTIL_ERROR_NONE)
+ if (IMAGE_UTIL_ERROR_NONE != ret)
return CONTACTS_ERROR_SYSTEM;
return info.ret;
if (false == ctsvc_check_available_image_space())
return CONTACTS_ERROR_FILE_NO_SPACE;
- ret = __ctsvc_resize_and_copy_image(src, dest);
+ ret = _ctsvc_image_encode(src, dest);
if (CONTACTS_ERROR_NONE == ret) {
return ret;
}
else
- CTS_ERR("__ctsvc_resize_and_copy_image Fail(%d)", ret);
+ CTS_ERR("_ctsvc_image_encode Fail(%d)", ret);
src_fd = open(src, O_RDONLY);
RETVM_IF(src_fd < 0, CONTACTS_ERROR_SYSTEM, "System : Open(src:%s) Fail(%d)", src, errno);
else {
CTS_ERR("write() Fail(%d)", errno);
if (ENOSPC == errno)
- ret = CONTACTS_ERROR_FILE_NO_SPACE; // No space
+ ret = CONTACTS_ERROR_FILE_NO_SPACE; /* No space */
else
- ret = CONTACTS_ERROR_SYSTEM; // IO error
+ ret = CONTACTS_ERROR_SYSTEM; /* IO error */
close(src_fd);
close(dest_fd);
unlink(dest);