diff options
Diffstat (limited to 'src/camera_utils.c')
-rwxr-xr-x | src/camera_utils.c | 1461 |
1 files changed, 1461 insertions, 0 deletions
diff --git a/src/camera_utils.c b/src/camera_utils.c new file mode 100755 index 0000000..903baec --- /dev/null +++ b/src/camera_utils.c @@ -0,0 +1,1461 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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://floralicense.org/license/ + * + * 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 <image_util.h> +#include <malloc.h> +#include <ctype.h> +#include "camera_utils.h" +#include "cam_debug.h" +#include "cam_error.h" +#include "cam_ta.h" +#include "cam_mm.h" +#include "cam_file.h" + +#define JPEG_8M_APPROXIMATELY_SIZE 2096000 +#define JPEG_W6M_APPROXIMATELY_SIZE 1699000 +#define JPEG_5M_APPROXIMATELY_SIZE 1436000 +#define JPEG_W4M_APPROXIMATELY_SIZE 1210000 +#define JPEG_3M_APPROXIMATELY_SIZE 849500 +#define JPEG_W2M_APPROXIMATELY_SIZE 693910 +#define JPEG_2M_APPROXIMATELY_SIZE 566000 +#define JPEG_1M_APPROXIMATELY_SIZE 283000 +#define JPEG_VGA_APPROXIMATELY_SIZE 135000 + +#define CLIPING(data) ((data) < 0 ? 0 : ((data) > 255) ? 255 : (data)) +/*#define SUPPORT_WINK //use wink library */ + +static void YuvToRgb(int Y, int U, int V, int *R, int *G, int *B) +{ + *B = CLIPING((76284 * (Y - 16) + 132252 * (U - 128)) >> 16); + *G = CLIPING((76284 * (Y - 16) - 53281 * (V - 128) - + 25625 * (U - 128)) >> 16); + *R = CLIPING((76284 * (Y - 16) + 104595 * (V - 128)) >> 16); +} + +/* #define SUPPORT_WINK */ +#define CAPTUERD_IMAGE_SAVE_PATH "/tmp/captured_image.jpg" + +#ifndef YUV422_SIZE +#define YUV422_SIZE(width, height) ((width) * (height) * 2) +#endif /* YUV422_SIZE */ + +#ifndef YUV420_SIZE +#define YUV420_SIZE(width, height) ((width) * (height) * 3 / 2) +#endif /* YUV420_SIZE */ + +#ifdef MAX_PATH +#define MAX_PATH 256 +#endif + +char *m_mmc_path = NULL; + +/*get the torchlight on/off value*/ +gboolean cam_utils_check_torchlight_status(void *data) +{ + struct appdata *ad = (struct appdata *)data; + cam_retv_if(ad == NULL, FALSE); + int ret = -1; /*error, success is 0*/ + int key_value = -1; + ret = vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TORCH_LIGHT, &key_value); /*ret [-1: error, 0:succes], key_value[on:1 , off:0]*/ + DEBUG_TRACE("VCONFKEY_SETAPPL_ACCESSIBILITY_TORCH_LIGHT is changed to %d", key_value); + if (ret == -1) { + DEBUG_TRACE("vconf_get_int failed"); + return FALSE; + } + if (key_value) { + /*torchlight is working*/ + ad->torchlight_on = TRUE; + } else { + ad->torchlight_on = FALSE; + } + return TRUE; +} + +/*get the battery warning low state*/ +gboolean cam_utils_check_battery_warning_low(void) +{ + int low_status = -1; + + if (!vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &low_status)) { + cam_debug(LOG_UI, "battery status low = %d", low_status); + if (low_status <= VCONFKEY_SYSMAN_BAT_WARNING_LOW) + return TRUE; + } else { + cam_warning(LOG_UI, "get setting failed %s", + VCONFKEY_SYSMAN_BATTERY_STATUS_LOW); + } + + return FALSE; +} +/*get the battery critical low state*/ +gboolean cam_utils_check_battery_critical_low(void) +{ + int low_status = -1; + + if (!vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &low_status)) { + cam_debug(LOG_UI, "battery status low = %d", low_status); + if (low_status <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW) + return TRUE; + } else { + cam_warning(LOG_UI, "get setting failed %s", + VCONFKEY_SYSMAN_BAT_CRITICAL_LOW); + } + + return FALSE; +} + + +gboolean cam_utils_check_call_running(void) +{ + int call_state = -1; + + if (!vconf_get_int(VCONFKEY_CALL_STATE, &call_state)) { + cam_debug(LOG_UI, "call state = %d", call_state); + if (call_state == VCONFKEY_CALL_OFF) + return FALSE; + } else { + cam_warning(LOG_UI, "get setting failed %s", + VCONFKEY_CALL_STATE); + } + + return TRUE; +} + +int cam_utils_get_battery_level(void) +{ + debug_fenter(LOG_SYS); + + gint battery_level = -1; + + /* VCONF_BATTERY_LEVEL or VCONFKEY_INDICATOR_MODULE_BATTERY */ + if (!vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &battery_level)) { + cam_info(LOG_SYS, "battery_level = %d", battery_level); + return battery_level; + } else { + cam_info(LOG_SYS, "get setting failed %s", + VCONFKEY_SYSMAN_BATTERY_CAPACITY); + } + + return battery_level; +} + +gint cam_utils_get_charging_status(void) +{ + debug_fenter(LOG_SYS); + + gint charging = -1; + + /* VCONF_BATTERY_CHARGE_NOW or VCONFKEY_INDICATOR_MODULE_CHARGE */ + if (!vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charging)) { + cam_info(LOG_SYS, "charging = %d", charging); + } else { + cam_info(LOG_SYS, "get setting failed %s", + VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW); + } + + return charging; +} + +guint64 cam_system_get_remain_rec_time(void *data) +{ + struct appdata *ad = (struct appdata *)data; + if (ad == NULL) { + return 0; + } + CamAppData *camapp = ad->camapp_handle; + if (camapp == NULL) { + return 0; + } + guint64 remain_time = 0; + + { + gint64 free_space = 0; + guint a_bitrate = 0, v_bitrate = 0; + gchar* target_path = (gchar*)cam_app_get_target_path(); + if (target_path == NULL) { + return 0; + } + free_space = cam_get_free_space(target_path); + + a_bitrate = cam_app_get_aenc_bitrate(ad); + v_bitrate = cam_app_get_venc_bitrate(ad, camapp->video_quality); + + remain_time = + (guint64)((free_space * 8) / (a_bitrate + v_bitrate)); + + } + return remain_time; +} + +gint64 cam_system_get_still_count_by_resolution(void *data) +{ + debug_fenter(LOG_CAM); + + struct appdata *ad = (struct appdata *)data; + if (ad == NULL) { + return 0; + } + CamAppData *camapp = ad->camapp_handle; + if (camapp == NULL) { + return 0; + } + + gint64 free_space = 0; + gint64 remained_count = 0; + gint64 avg_file_size = -1; + gchar* target_path = (gchar*)cam_app_get_target_path(); + if (target_path == NULL) { + return 0; + } + free_space = cam_get_free_space(target_path); + DEBUG_TRACE("FREE SPACE =%d", free_space); + free_space = (free_space - STILL_MINIMAL_SPACE); + + /* TODO: Quality factor should be calculated later! + */ + switch (camapp->photo_resolution) { + case CAM_RESOLUTION_3264x2448: + case CAM_RESOLUTION_3264x2176: + avg_file_size = JPEG_8M_APPROXIMATELY_SIZE; + break; + + case CAM_RESOLUTION_3264x1960: + case CAM_RESOLUTION_3264x1836: + avg_file_size = JPEG_W6M_APPROXIMATELY_SIZE; + break; + + case CAM_RESOLUTION_2800x1920: + case CAM_RESOLUTION_2560x1920: + avg_file_size = JPEG_5M_APPROXIMATELY_SIZE; + break; + + case CAM_RESOLUTION_2560x1536: + avg_file_size = JPEG_W4M_APPROXIMATELY_SIZE; + break; + + case CAM_RESOLUTION_2560x1440: + case CAM_RESOLUTION_2048x1536: + avg_file_size = JPEG_3M_APPROXIMATELY_SIZE; + break; + + case CAM_RESOLUTION_2048x1152: + avg_file_size = JPEG_W2M_APPROXIMATELY_SIZE; + break; + + case CAM_RESOLUTION_1920x1080: + case CAM_RESOLUTION_1600x1200: + case CAM_RESOLUTION_1392x1392: + avg_file_size = JPEG_2M_APPROXIMATELY_SIZE; + break; + + case CAM_RESOLUTION_1280x720: + case CAM_RESOLUTION_1280x960: + avg_file_size = JPEG_1M_APPROXIMATELY_SIZE; + break; + + case CAM_RESOLUTION_SVGA: + avg_file_size = 150 * 1024 * 2; + break; + + case CAM_RESOLUTION_WVGA: + avg_file_size = 130 * 1024 * 2; + break; + + case CAM_RESOLUTION_VGA: + avg_file_size = JPEG_VGA_APPROXIMATELY_SIZE; + break; + + case CAM_RESOLUTION_WQVGA: + avg_file_size = 100 * 1024 * 2; + break; + + case CAM_RESOLUTION_QVGA: + avg_file_size = 100 * 1024 * 1.5; + break; + + case CAM_RESOLUTION_CIF: + avg_file_size = 25 * 1024 * 2; + break; + + default: + cam_critical(LOG_CAM, "unhandled resolution:%dx%d", HIWORD(camapp->photo_resolution), LOWORD(camapp->photo_resolution)); + return -1; + } + + remained_count = free_space / avg_file_size; + DEBUG_TRACE("FREE SPACE =%d", free_space); + DEBUG_TRACE("avg_file_size =%d", avg_file_size); + DEBUG_TRACE("remained_count =%d", remained_count); + + return (int)MAX(remained_count, 0); +} + +gint64 cam_get_free_space(const gchar *path) +{ + struct statfs fs; + if (-1 == statfs(path, &fs)) + return -1; + return (gint64) fs.f_bsize * fs.f_bavail; +} + + +gboolean cam_utils_set_guide_rect_color(void *data) { + + struct appdata *ad = (struct appdata *)data; + CamAppData *camapp = NULL; + + cam_retv_if(ad == NULL, FALSE); + camapp = ad->camapp_handle; + cam_retv_if(camapp == NULL, FALSE); + + DEBUG_TRACE(" "); + + int capture_video_format = CAMERA_PIXEL_FORMAT_INVALID; + cam_mm_get_video_source_format(NULL, &capture_video_format); + DEBUG_TRACE("capture_video_format =%d", capture_video_format); + + switch (capture_video_format) { + case CAMERA_PIXEL_FORMAT_INVALID: + { + cam_debug(LOG_UI,"can not set preview format & shapshot format"); + } + return FALSE; + case CAMERA_PIXEL_FORMAT_UYVY: + /*case MM_PIXEL_FORMAT_ITLV_JPEG_UYVY:*//*TODO:there is no this value in capi*/ + { + camapp->guide_rect_green = UYVY_GUIDE_RECT_GREEN; + camapp->guide_rect_orange = UYVY_GUIDE_RECT_ORANGE; + camapp->guide_rect_red = UYVY_GUIDE_RECT_RED; + camapp->guide_rect_white = UYVY_GUIDE_RECT_WHITE; + } + break; + case CAMERA_PIXEL_FORMAT_YUYV: + { + camapp->guide_rect_green= YUYV_GUIDE_RECT_GREEN; + camapp->guide_rect_orange= YUYV_GUIDE_RECT_ORANGE; + camapp->guide_rect_red= YUYV_GUIDE_RECT_RED; + camapp->guide_rect_white = YUYV_GUIDE_RECT_WHITE; + } + break; + default: + cam_debug(LOG_UI,"can not set preview format & shapshot format"); + return FALSE; + } + return TRUE; +} + + + + +gint64 cam_get_capacity_space(const gchar *path) +{ + struct statfs fs; + if (-1 == statfs(path, &fs)) + return -1; + return (gint64) fs.f_bsize * fs.f_blocks; +} + + + +void +cam_utils_draw_guide_rectangle(void *data, void *frame, int x_org, int y_org, + int width, int height) +{ + struct appdata *ad = (struct appdata *)data; + CamAppData *camapp = NULL; + + cam_retm_if(ad == NULL, "appdata is NULL"); + camapp = ad->camapp_handle; + cam_retm_if(camapp == NULL, "cam_handle is NULL"); + + int left, right, top, bottom, offset, y; + int xStart, xEnd, draw_width; + + if (width == 0 && height == 0) { + cam_debug(LOG_UI, " width,height of rectangle are zero"); + return; + } + + left = 2 * (x_org / 2); /* to draw on YUV422 or YUV420, we must start at even x */ + right = left + 2 * (width / 2); + top = y_org; + bottom = y_org + height; + + int preview_w = 0; /* make sure this is even */ + int preview_h = 0; + gboolean ret = FALSE; + + ret = cam_mm_get_video_size( &preview_w, &preview_h); + cam_ret_if(ret == FALSE || preview_w == 0 || preview_h == 0); + + xStart = MAX(left, 0); + xEnd = MIN(right, preview_w); + + draw_width = xEnd - xStart; /* for top and bottom */ + if (draw_width <= 0) + return; + + int line_thickness = FIT_TO_RESOLUTION(2, 4); /* make sure this is even */ + +#if 0 + int frame_size = preview_w * preview_h; + + guchar guide_rect_colorY = + (guchar) ((camapp->guide_rect_color >> 8) & 0xFF); + guchar guide_rect_colorU = (guchar) ((camapp->guide_rect_color) & 0xFF); + guchar guide_rect_colorV = + (guchar) ((camapp->guide_rect_color >> 16) & 0xFF); + + top = 2 * (top / 2); /* to draw on YUV420, we must start at even y */ + bottom = 2 * (bottom / 2); + + /* top */ + for (y = MAX(top, 0); y < top + line_thickness && y < preview_h; y += 2) { /* line_thickness, and preview_h must be even */ + offset = y * preview_w + xStart; + memset(((guchar *) frame) + offset, guide_rect_colorY, + draw_width); + memset(((guchar *) frame) + offset + preview_w, + guide_rect_colorY, draw_width); + offset = y * preview_w / 4 + xStart / 2; + memset(((guchar *) frame) + frame_size + offset, + guide_rect_colorU, draw_width / 2); + memset(((guchar *) frame) + frame_size + frame_size / 4 + + offset, guide_rect_colorV, draw_width / 2); + } + + /* bottom */ + for (y = MAX(bottom - line_thickness, 0); + y < bottom && y < preview_h; y += 2) { + offset = y * preview_w + xStart; + memset(((guchar *) frame) + offset, guide_rect_colorY, + draw_width); + memset(((guchar *) frame) + offset + preview_w, + guide_rect_colorY, draw_width); + offset = y * preview_w / 4 + xStart / 2; + memset(((guchar *) frame) + frame_size + offset, + guide_rect_colorU, draw_width / 2); + memset(((guchar *) frame) + frame_size + frame_size / 4 + + offset, guide_rect_colorV, draw_width / 2); + } + + /* left */ + if (left + line_thickness > 0 && left < preview_w) { + draw_width = MIN(MIN(line_thickness, line_thickness + left), preview_w - left); /* now calculated for left */ + for (y = MAX(top, 0); y < bottom && y < preview_h; y += 2) { + offset = y * preview_w + xStart; + memset(((guchar *) frame) + offset, guide_rect_colorY, + draw_width); + memset(((guchar *) frame) + offset + preview_w, + guide_rect_colorY, draw_width); + offset = y * preview_w / 4 + xStart / 2; + memset(((guchar *) frame) + frame_size + offset, + guide_rect_colorU, draw_width / 2); + memset(((guchar *) frame) + frame_size + + frame_size / 4 + offset, guide_rect_colorV, + draw_width / 2); + } + } + /* right */ + if (right > 0 && right - line_thickness < preview_w) { + draw_width = MIN(MIN(line_thickness, right), preview_w - right + line_thickness); /* now calculated for right */ + for (y = MAX(top, 0); y < bottom && y < preview_h; y += 2) { + offset = y * preview_w + MAX(right - line_thickness, 0); + memset(((guchar *) frame) + offset, guide_rect_colorY, + draw_width); + memset(((guchar *) frame) + offset + preview_w, + guide_rect_colorY, draw_width); + offset = + y * preview_w / 4 + MAX(right - line_thickness, + 0) / 2; + memset(((guchar *) frame) + frame_size + offset, + guide_rect_colorU, draw_width / 2); + memset(((guchar *) frame) + frame_size + + frame_size / 4 + offset, guide_rect_colorV, + draw_width / 2); + } + } +#else + + int x; + + /* top */ + for (y = top; y < top + line_thickness && y < preview_h; y++) { + if (y < 0) + continue; + offset = y * preview_w + xStart; + for (x = 0; x < draw_width; x += 2) { + ((gulong *) frame)[(offset + x) / 2] = + camapp->guide_rect_color; + } + } + + /* bottom */ + for (y = bottom - line_thickness; y < bottom && y < preview_h; y++) { + if (y < 0) + continue; + offset = y * preview_w + xStart; + for (x = 0; x < draw_width; x += 2) { + ((gulong *) frame)[(offset + x) / 2] = + camapp->guide_rect_color; + } + } + + /* left */ + if (left + line_thickness >= 0 && left < preview_w) { + draw_width = MIN(MIN(line_thickness, line_thickness + left), preview_w - left); /* now calculated for left */ + for (y = MAX(top, 0); y < bottom && y < preview_h; y++) { + offset = y * preview_w + xStart; + for (x = 0; x < draw_width; x += 2) { + ((gulong *) frame)[(offset + x) / 2] = + camapp->guide_rect_color; + } + } + } + /* right */ + if (right >= 0 && right - line_thickness < preview_w) { + draw_width = MIN(MIN(line_thickness, right), preview_w - right + line_thickness); /* now calculated for right */ + for (y = MAX(top, 0); y < bottom && y < preview_h; y++) { + offset = y * preview_w + MAX(right - line_thickness, 0); + for (x = 0; x < draw_width; x += 2) { + ((gulong *) frame)[(offset + x) / 2] = + camapp->guide_rect_color; + } + } + } +#endif + +} + +void +cam_utils_convert_YUYV_to_UYVY(unsigned char *dst, unsigned char *src, + gint length) +{ + int i = 0; + + memset(dst, 0x00, length); + memcpy(dst, src + 1, length - 1); + + for (i = 0; i < length; i++) { + if (!(i % 2)) { + dst[i + 1] = src[i]; + } + } + +} + +void cam_utils_convert_UYVY_to_YUYV(char *dst, char *src, gint length) +{ + int i = 0; + + memset(dst, 0x00, length); + memcpy((char *)dst + 1, (char *)src, length - 1); + + for (i = 0; i < length; i++) { + if ((i % 2)) { /* even */ + dst[i - 1] = src[i]; + } + } + +} + +#if 1 + +void +cam_utils_convert_YUYV_to_YUV420P(unsigned char *pInBuf, unsigned char *pOutBuf, + int width, int height) +{ + unsigned char *pInY, *pInU, *pInV; + unsigned char *pOutY, *pOutU, *pOutV; + + int nRowIters = height / 2; + int nColIters = width / 2; + + int rows, cols; + + pInY = pInBuf; + pInU = pInBuf + 1; + pInV = pInBuf + 3; + pOutY = pOutBuf; + pOutU = pOutBuf + width * height; + pOutV = pOutBuf + width * height * 5 / 4; + + /* Iterate over half the number of rows, because inside there are 2 loops on columns */ + for (rows = 0; rows < nRowIters; rows++) { + /* Even rows + Iterate over half the number of columns, copy 2 pixels each time */ + for (cols = 0; cols < nColIters; cols++) { + /* Copy Y of first pixel */ + *pOutY = *pInY; + pOutY++; + pInY += 2; + /* Copy Y of second pixel */ + *pOutY = *pInY; + pOutY++; + pInY += 2; + /* Copy U of all 4 pixels */ + *pOutU = *pInU; + pOutU++; + pInU += 4; + /* Copy V of all 4 pixels */ + *pOutV = *pInV; + pOutV++; + pInV += 4; + } + /* Odd rows + Iterate over half the number of columns, copy 2 pixels each time */ + for (cols = 0; cols < nColIters; cols++) { + /* Copy Y of third pixel */ + *pOutY = *pInY; + pOutY++; + pInY += 2; + /* Copy Y of fourth pixel */ + *pOutY = *pInY; + pOutY++; + pInY += 2; + } + /* Skip U, V of third, fourth pixel */ + pInU += width * 2; + pInV += width * 2; + } +} + +#else + +void +cam_utils_convert_YUYV_to_YUV420P(byte *src, byte *dst, gint width, gint height) +{ + int i = 0; + int YUYV_length = 0, YUV420P_length = 0; + int temp_length = 0, temp_length2 = 0; + int pos_u = 0, pos_v = 0; + + /* cam_debug( LOG_UI, " start" ); */ + + temp_length = width * height; + temp_length2 = temp_length >> 2; + YUYV_length = temp_length << 1; + YUV420P_length = (temp_length * 3) >> 1; + + /* + cam_debug( LOG_UI, " size[%dx%d], length YUYV[%d],YUV420P[%d]", + width, height, YUYV_length, YUV420P_length ); + */ + + if (dst == NULL) { + cam_critical(LOG_SYS, " dst is NULL"); + return; + } + + for (i = 0; i < temp_length; i++) { + /* Y data */ + dst[i] = src[i << 1]; + + if (i % (width << 1) < width) { + if (i % 2 == 0) { + /* U data */ + dst[temp_length + pos_u] = src[(i << 1) + 1]; + pos_u++; + } else { + /* V data */ + dst[temp_length + temp_length2 + pos_v] = + src[(i << 1) + 1]; + pos_v++; + } + } + } +} + +#endif + +void *cam_utils_YUV422_to_ARGB(byte *frame, int width, int height) +{ + /* source yuv is FOURCC YUYV, sampling format YUV 422 . + yuv422 format + Byte Ordering (lowest byte) Y0, U0, Y1, V0 */ + byte *frame_argb = malloc(width * height * 4); /* for ARGB */ + + if (frame_argb == NULL) { + return NULL; + } + memset(frame_argb,0,width * height * 4); + + int i = 0, j = 0; /* row, column */ + int y, u, v; + int r, g, b; + unsigned long pixel_idx = 0, rgb_index = 0; + short v_idx = 0; + short u_idx = 0; + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + + if (j % 2) { /* odd */ + v_idx = -1; + u_idx = 1; + /* u_idx = -1; v_idx = 1; */ + } else { + v_idx = 1; + u_idx = 3; + /* u_idx = 1; v_idx = 3; */ + } + + y = frame[pixel_idx]; + v = frame[pixel_idx + v_idx]; + u = frame[pixel_idx + u_idx]; + + YuvToRgb(y, u, v, &r, &g, &b); + + /* ARGB */ + frame_argb[rgb_index++] = (byte)CLIPING(r); + frame_argb[rgb_index++] = (byte)CLIPING(g); + frame_argb[rgb_index++] = (byte)CLIPING(b); + frame_argb[rgb_index++] = 0xff; + + pixel_idx += 2; /* yuv422, 4byte is 2 pixel */ + } + } + + return (void *)frame_argb; +} + +void *cam_utils_IYUV_to_ARGB(byte *frame, int width, int height) +{ + /* source yuv is FOURCC IYUV or I420, sampling format YUV 420. */ + /* IYUV format is http://www.fourcc.org/yuv.php#IYUV */ + + byte *frame_argb = malloc(width * height * 4); /* for ARGB */ + if (frame_argb == NULL) { + return NULL; + } + memset(frame_argb,0,width * height * 4); + + int h = 0, w = 0; /* row, column */ + int y, u, v; + int r, g, b; + unsigned long rgb_index = 0; /* ,pixel_idx=0; */ + int idx = 0; + + for (h = 0; h < height; h++) { + for (w = 0; w < width; w++) { + + y = frame[h * height + w]; + u = frame[(width * height) + idx]; + v = frame[(width * height) + ((width * height) / 4) + + idx]; + + if (w % 2) + idx++; + + YuvToRgb(y, u, v, &r, &g, &b); + + /* ARGB */ + frame_argb[rgb_index++] = (byte)CLIPING(r); + frame_argb[rgb_index++] = (byte)CLIPING(g); + frame_argb[rgb_index++] = (byte)CLIPING(b); + frame_argb[rgb_index++] = 0; + + } + + if ((w == width - 1) && (!(h % 2))) + idx -= width / 2; + } + + return (void *)frame_argb; +} + +gboolean +cam_utils_save_to_jpg_file(int storage_id, gchar *filename, void *frame, + int width, int height, GError **error) +{ + cam_debug(LOG_MM, " [%dx%d] %s", width, height, filename); + + int ret = CAMERA_ERROR_NONE; + + CAM_TA_ACUM_ITEM_BEGIN("cam_utils_check_mmc_for_writing", 0); + if (storage_id == CAM_STORAGE_EXTERNAL) { + if (!cam_utils_check_mmc_for_writing(error)) { + return FALSE; + } + } + CAM_TA_ACUM_ITEM_END("cam_utils_check_mmc_for_writing", 0); + + cam_debug(LOG_SYS, " \n\n\n\n\n START JPEG ENCODING \n\n\n\n\n"); + + CAM_TA_ACUM_ITEM_BEGIN("image_util_encode_jpeg", 0); + ret = image_util_encode_jpeg(frame, width, height, + IMAGE_UTIL_COLORSPACE_YUYV, 90, filename); + CAM_TA_ACUM_ITEM_END("image_util_encode_jpeg", 0); + + cam_debug(LOG_SYS, " \n\n\n\n\n END JPEG ENCODING \n\n\n\n\n"); + + if (ret != 0) { + cam_critical(LOG_MM, " image_util_encode_jpeg Failed [%x]", ret); + return FALSE; + } + + return TRUE; +} + +gboolean +cam_utils_save_to_jpg_memory(byte **memory, unsigned int *size, void *src_frame, + int width, int height) +{ + cam_debug(LOG_MM, " [%dx%d]", width, height); + + int ret = CAMERA_ERROR_NONE; + + cam_debug(LOG_SYS, " \n\n\n\n\n START JPEG ENCODING \n\n\n\n\n"); + + CAM_TA_ACUM_ITEM_BEGIN("image_util_encode_jpeg_to_memory", 0); + ret = image_util_encode_jpeg_to_memory(src_frame, width, height, + IMAGE_UTIL_COLORSPACE_YUYV, 90, (unsigned char **)memory, size); + CAM_TA_ACUM_ITEM_END("image_util_encode_jpeg_to_memory", 0); + + cam_debug(LOG_SYS, " \n\n\n\n\n END JPEG ENCODING \n\n\n\n\n"); + + if (ret != 0) { + cam_critical(LOG_MM, "image_util_encode_jpeg_to_memory Failed [%x]", ret); + return FALSE; + } + + return TRUE; +} + +void *cam_utils_load_temp_file(gchar *filepath, gint *pfilesize) +{ + struct stat fileinfo; + FILE *fp = NULL; + int ret; + + ret = stat(filepath, &fileinfo); + if (ret == -1) { + cam_critical(LOG_CAM, "can't get file infomation - error[%d]", ret); + return NULL; + } + + gint filesize = fileinfo.st_size; + if (filesize < 0) { + cam_critical(LOG_CAM, "can't get file infomation"); + return NULL; + } + + cam_debug(LOG_CAM, "temp file's file_path =%s, file_size =%d", + filepath, filesize); + + void *data = (void *)malloc(filesize); + + if (data == NULL) { + return NULL; + } + memset(data, 0, filesize); + + cam_debug(LOG_CAM, "data = %p ", data); + + if ((fp = fopen(filepath, "r")) == NULL) { + perror("fopen"); + if (data) + free(data); + + cam_critical(LOG_CAM, "can't open file infomation"); + return NULL; + } + if (fread(data, filesize, 1, fp) != 1) { + perror("fread"); + fclose(fp); + if (data) + free(data); + + cam_critical(LOG_CAM, "can't read file infomation"); + return NULL; + } + + *pfilesize = filesize; + + fclose(fp); + + return data; +} + +gboolean cam_utils_check_mmc_for_writing(GError **error) +{ + gint error_code = 0; + int mmc_state = -1; + const gchar *error_msg = NULL; + + if (!m_mmc_path) + m_mmc_path = (char *)cam_file_get_external_image_path(); + + if (!g_file_test(m_mmc_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { + error_code = CAM_ERROR_STORAGE_UNAVAILABLE; + error_msg = dgettext(PACKAGE, "IDS_CAM_BODY_UNABLE_TO_SAVE_NOT_ENOUGH_MEMORY"); + goto ERROR; + } + + if (!vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_state)) { + if (mmc_state == VCONFKEY_SYSMAN_MMC_REMOVED) { + error_code = CAM_ERROR_STORAGE_UNAVAILABLE; + error_msg = dgettext(PACKAGE, "IDS_CAM_POP_MEMORY_CARD_REMOVED"); + goto ERROR; + } + } + + return TRUE; + + ERROR: + + /* cam_set_error */ + if (error_msg) { + if (*error) { + *error = cam_error_new_literal(error_code, error_msg);/*note:fix warnning*/ + } + } + return FALSE; + +} + +gboolean cam_utils_check_mmc_for_inserted_stats(void *data) +{ + int mmc_state = -1; + g_return_val_if_fail(data, FALSE); + + struct appdata *ad = (struct appdata *)data; + cam_retv_if(ad == NULL, FALSE); + + CamAppData *camapp = NULL; + camapp = ad->camapp_handle; + + camapp = ad->camapp_handle; + cam_retv_if(camapp == NULL, FALSE); + + if (!vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_state)) { + if (mmc_state == VCONFKEY_SYSMAN_MMC_REMOVED + && camapp->storage == CAM_STORAGE_EXTERNAL) { + return FALSE; + } + } + + return TRUE; +} + +int cam_utils_check_mmc_status(void) +{ + int status = -1; + + if (!vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &status)) { + cam_warning(LOG_SYS, " Get MMC status failed"); + } + + return status; +} + +int cam_utils_get_storage_id_from_filepath(const char *filepath) +{ + char *strtemp = NULL; + + strtemp = (char *)cam_file_get_internal_image_path(); + + if (strtemp) { + if (!strncmp(filepath, strtemp, strlen(strtemp))) + return CAM_STORAGE_INTERNAL; + } + + strtemp = (char *)cam_file_get_external_image_path(); + if (strtemp) { + if (!strncmp(filepath, strtemp, strlen(strtemp))) + return CAM_STORAGE_EXTERNAL; + } + + return CAM_STORAGE_DCF; + +} + +gboolean +cam_utils_safety_file_copy(const char *dst, const char *src, GError **error) +{ + + gint error_code = 0; + const gchar *error_msg = NULL; + + FILE *fp_src = NULL; + FILE *fp_dst = NULL; + int ret; + + cam_debug(LOG_FILE, " dst file name = %s", dst); + cam_debug(LOG_FILE, " dst file name = %s", src); + + fp_src = fopen(src, "r"); + if (fp_src == NULL) { + error_code = CAM_ERROR_FILE_NOT_EXISTS; + error_msg = dgettext(PACKAGE, "IDS_CAM_BODY_UNABLE_TO_SAVE_NOT_ENOUGH_MEMORY"); + goto ERROR; + } else { + + cam_debug(LOG_FILE, "start check mmc"); + /* check mmc */ + if (cam_utils_get_storage_id_from_filepath(dst) == CAM_STORAGE_EXTERNAL) { + if (!cam_utils_check_mmc_for_writing(error)) + goto ERROR; + } + + cam_debug(LOG_FILE, "end check mmc"); + + fp_dst = fopen(dst, "wb"); + if (fp_dst == NULL) { + error_code = CAM_ERROR_FILE_REGISTER_FAILED; + error_msg = dgettext(PACKAGE, "IDS_CAM_BODY_UNABLE_TO_SAVE_NOT_ENOUGH_MEMORY"); + goto ERROR; + } else { + cam_debug(LOG_FILE, "start copy"); + /* copy */ + unsigned long filesize = 0; + unsigned long filecopyblocksize = 1024 * 512; + unsigned long copysize = 0; + struct stat fileinfo; + + void *buff = malloc(filecopyblocksize); /* 512k */ + if (buff == NULL) + goto ERROR; + + /* get source file size */ + ret = stat(src, &fileinfo); + if (ret == -1) { + cam_critical(LOG_CAM, "can't get file infomation - error[%d]", ret); + if (buff) { + free(buff); + buff = NULL; + } + goto ERROR; + } + + filesize = fileinfo.st_size; + cam_debug(LOG_FILE, "source file size %lu", filesize); + + if (filesize > 0) { + do { + if (filesize >= filecopyblocksize) { + copysize = filecopyblocksize; + } else { + copysize = filesize; + } + + cam_debug(LOG_FILE, "copy size %lu", copysize); + if (fread(buff, copysize, 1, fp_src) != 1) { + cam_debug(LOG_FILE, "read error!"); + if (buff) { + free(buff); + buff = NULL; + } + goto ERROR; + } + + if (buff && fwrite(buff, copysize, 1, fp_dst) != 1) { + cam_debug(LOG_FILE, "file read or write error"); + error_code = CAM_ERROR_FILE; + error_msg = dgettext(PACKAGE, "IDS_CAM_BODY_UNABLE_TO_SAVE_NOT_ENOUGH_MEMORY"); + if (buff) { + free(buff); + buff = NULL; + } + goto ERROR; + } + + filesize -= copysize; + } while (filesize > 0); + } else { + error_code = CAM_ERROR_PANORAMA_LIB; + error_msg = dgettext(PACKAGE, "IDS_CAM_BODY_FAILED_TO_BUILD_PANORAMIC_IMAGES_TRY_LATER"); + if (buff) { + free(buff); + buff = NULL; + } + goto ERROR; + } + + /* + + stat(filepath, &fileinfo); + + gint filesize = fileinfo.st_size; + + if (fwrite(g_result_panorama_image->bits, g_result_panorama_image->size, 1, fp) != 1) + { + free(camapp->filename); + camapp->filename = NULL; + } + */ + if (buff) { + free(buff); + buff = NULL; + } + /*fsync(fp_dst->_fileno);*//*block for increasing formance of shot-to-shot */ + fclose(fp_dst); + } + + fclose(fp_src); + + } + + return TRUE; + + ERROR: + + cam_debug(LOG_FILE, "file copy error, error number=%x", error_code); + + if (fp_dst) + fclose(fp_dst); + + if (fp_src) + fclose(fp_src); + + /* cam_set_error */ + if (error_msg) { + if (*error) { + *error = cam_error_new_literal(error_code, error_msg);/*note:fix warnning*/ + } + } + return FALSE; + +} + +static char *cam_utils_trim(char *str) +{ + char *i_buf = str; + + for (; *i_buf && isspace(*i_buf); ++i_buf) ; + + return i_buf; +} + +gboolean cam_utils_parse_args(int argc, char *argv[], CamExeArgs *args) +{ + int index = 0; + const char *delimiters = ","; + + if (args == NULL) + return FALSE; + for (index = 0; index < argc; index++) { + if (argv == NULL) + return FALSE; + + if (argv[index][0] == '-' && argv[index][1] != '\0') { + char *r_argv = strdup(cam_utils_trim((argv[index] + 2))); + switch (argv[index][1]) { +#if 0 + case 'd': /* daemon launch */ + { + args->launch_type = + CAM_LAUNCHING_MODE_DAEMON; + return TRUE; + } + break; + case 'h': /* help */ + { + args->launch_type = + CAM_LAUNCHING_MODE_HELP; + return TRUE; + } + break; +#endif + case 'v': /* review */ + { + args->review = TRUE; + } + break; + case 'r': /* resolution */ + { + if (r_argv) { + char *result = NULL; + char *save_string = NULL; + result = strtok_r(r_argv, delimiters,&save_string); + if (result != NULL) + args->width = atoi(result); + result = strtok_r(NULL, delimiters,&save_string); + if (result != NULL) + args->height = atoi(result); + } else { + return FALSE; + } + } + break; + case 'm': /* cam_mode */ + { + if (r_argv) { + if (0 == strcmp(r_argv, "IMAGE")) { + args->cam_mode = CAM_CAMERA_MODE; + } else if (0 == strcmp(r_argv, "VIDEO")) { + args->cam_mode = CAM_CAMCORDER_MODE; + } else { + if (r_argv != NULL) { + free(r_argv); + r_argv = NULL; + } + return FALSE; + } + } else { + return FALSE; + } + } + break; + case '-': /* launching appl.'s name */ + { + if (r_argv) { + char *qualifier_to_find = "calling-app="; + char *qualifier_field_start = NULL; + char *name = NULL; + + qualifier_field_start = strstr(r_argv, qualifier_to_find); + if (qualifier_field_start) { + qualifier_field_start += strlen(qualifier_to_find); + name = cam_utils_trim(qualifier_field_start); + args->caller = strdup(name); + } else { + cam_debug(LOG_SYS, "unknown arg : %s", argv[index]); + } + } else { + return FALSE; + } + } + break; + case 'l': /* size limit */ + { + if (r_argv) { + args->size_limit = atoi(r_argv); + } else { + return FALSE; + } + } + break; + default: /* unknown option */ + cam_debug(LOG_SYS, "Unknown Option : %c", + argv[index][1]); + break; + } + if (r_argv != NULL) { + free(r_argv); + r_argv = NULL; + } + } else { + cam_debug(LOG_SYS, "unknown arg : %s", argv[index]); + } + } + + cam_debug(LOG_SYS, "cam_mode : %d", args->cam_mode); + cam_debug(LOG_SYS, "resolution : [%dx%d]", args->width, args->height); + cam_debug(LOG_SYS, "limit : %d", args->size_limit); + cam_debug(LOG_SYS, "caller : %s", args->caller); + return TRUE; +} + +gboolean cam_utils_check_wide_resolution(int resol_w, int resol_h) +{ + if ((ABS((gfloat)((resol_w * 3.0) / (resol_h * 4.0)) - 1.0 ) < CAM_EPSINON ) + || (ABS((gfloat)((resol_w * 25.0) / (resol_h * 36.0)) - 1.0) < CAM_EPSINON)) { + cam_debug(LOG_UI, "Not Wide Resolution : [%d]x[%d]", resol_w, + resol_h); + return FALSE; + } + + return TRUE; +} + +gboolean cam_utils_check_fake_image_exist(const char *fake_image_path) +{ + if (!g_file_test(fake_image_path, G_FILE_TEST_EXISTS)) { + return FALSE; + } + + return TRUE; +} + +gboolean +cam_utils_image_rotate(char *src, int src_width, int src_height, char *dst, + int *dst_width, int *dst_height, int degree) +{ + + cam_retv_if(src == NULL || dst == NULL || src_width == 0 + || src_height == 0, FALSE); + cam_retv_if(degree != 0 && degree != 90 && degree != 180 + && degree != 270, FALSE); + + int i = 0; + int j = 0; + + int *from = (int *)src; + int *to = (int *)dst; + + if (degree == 0) { + *dst_width = src_width; + *dst_height = src_height; + memcpy(dst, src, src_width * src_height * 4); + return TRUE; + } + + for (j = 0; j < src_height; j++) { + for (i = 0; i < src_width; i++) { + + if (degree == 90) { + *dst_width = src_height; + *dst_height = src_width; + + *(to + i * src_height + (src_height - j)) = + *(from + j * src_width + i); + } else if (degree == 180) { + *dst_width = src_width; + *dst_height = src_height; + + *(to + (src_height - j) * src_width + + (src_width - i)) = +*(from + j * src_width + i); + } else if (degree == 270) { + *dst_width = src_height; + *dst_height = src_width; + + *(to + (src_width - i) * src_height + j) = + *(from + j * src_width + i); + } + + } + } + + return TRUE; + +} + + +void cam_utils_set_windows_xy_to_videos_xy(CamVideoRectangle src, + CamVideoRectangle *result, + void *data) +{ + cam_retm_if(data == NULL, "data is null"); + struct appdata *ad = (struct appdata *)data; + if (!ad || !result) + return; + switch (ad->camcorder_rotate) { + case CAMERA_ROTATION_NONE: + result->x = src.x - ad->preview_offset_x; + result->y = src.y - ad->preview_offset_y; + result->w = src.w; + result->h = src.h; + break; + case CAMERA_ROTATION_90: + result->x = ad->win_height - ad->preview_offset_y - src.x; + result->y = src.y - ad->preview_offset_y; + result->w = src.h; + result->h = src.w; + break; + case CAMERA_ROTATION_180: + result->x = ad->win_width - src.x - ad->preview_offset_x; + result->y = ad->win_height - src.y - ad->preview_offset_y; + result->w = src.w; + result->h = src.h; + break; + case CAMERA_ROTATION_270: + result->x = src.x - ad->preview_offset_y; + result->y = ad->win_width - src.y - ad->preview_offset_x; + result->w = src.h; + result->h = src.w; + break; + default: + DEBUG_TRACE("REACHE UN-REACHED CODES"); + } + DEBUG_TRACE("songfeng result->x %d result->y %d",result->x, result->y); + +} + + +void cam_utils_set_videos_xy_to_windows_xy(CamVideoRectangle src, + CamVideoRectangle *result, + void *data) +{ + cam_retm_if(data == NULL, "data is null"); + struct appdata *ad = (struct appdata *)data; + if (!ad || !result) + return; + + switch (ad->camcorder_rotate) { + case CAMERA_ROTATION_NONE: + /* + * win: (x,y) -------->x video:(x,y) -------->x(width) + * - - + * - - + * - - + * -y y(height) + */ + result->x = src.x + ad->preview_offset_x; + result->y = src.y + ad->preview_offset_y; + /*notes:here,result->w: horizontal;result->h:vertical*/ + result->w = src.w; + result->h = src.h; + break; + case CAMERA_ROTATION_90: + /* win: (x,y) -------->x video:(x,y) (height)y<----- + * - - + * - - + * - - + * -y x(width) + */ + result->x = ad->win_height - (src.y + ad->preview_offset_y + src.w); + result->y = src.x + ad->preview_offset_x; + /*notes:here,result->w: horizontal;result->h:vertical*/ + result->w = src.h; + result->h = src.w; + break; + case CAMERA_ROTATION_180: + /* win: (x,y) -------->x video:(x,y) y(height) + * - - + * - - + * - - + * -y (width)x<------ + */ + result->x = ad->win_width - (src.x + ad->preview_offset_x + src.w); + result->y = ad->win_height - (src.y + ad->preview_offset_y + src.h); + /*notes:here,result->w: horizontal;result->h:vertical*/ + result->w = src.w; + result->h = src.h; + break; + case CAMERA_ROTATION_270: + cam_critical(LOG_CAM, "CAMERA_ROTATION_270"); + /* win: (x,y) -------->x video:(x,y) x(width) + * - - + * - - + * - - + * -y -------------y(height) + */ + result->x = src.y + ad->preview_offset_y; + result->y = ad->win_width - (src.x + ad->preview_offset_x + src.w); + /*notes:here,result->w: horizontal;result->h:vertical*/ + result->w = src.h; + result->h = src.w; + break; + default: + DEBUG_TRACE("REACHE UN-REACHED CODES"); + } + +} + +gboolean cam_utils_request_main_pipe_handler(void *data, void *pipe_data, int cmd) +{ + struct appdata *ad = (struct appdata *)data; + cam_retvm_if(ad == NULL, FALSE, "appdata is NULL"); + Ecore_Pipe_Data_Info pipe_info = {0,}; + pipe_info.data = pipe_data; + pipe_info.cmd = cmd; + return ecore_pipe_write(ad->main_pipe, (void *)&pipe_info, sizeof(Ecore_Pipe_Data_Info)); + +} + +//end file |