nt9856x/code/application/source/cardv/SrcCode/UIApp/ExifVendor.c
2024-01-15 19:44:43 +08:00

730 lines
25 KiB
C
Executable File

/**
Exif sample code
Just sample code to show how to use exif lib.
@file ExifVendor.c
@ingroup Predefined_group_name
@note Nothing (or anything need to be mentioned).
Copyright Novatek Microelectronics Corp. 2019. All rights reserved.
*/
#include "PrjInc.h"
#include "ExifVendor.h"
#include "BinaryFormat.h"
#include <kwrap/type.h>
//#include <kwrap/debug.h>
#include <comm/hwclock.h>
#include <math.h>
#include "exif/ExifDef.h"
#include "ImageApp/ImageApp_MovieMulti.h"
#include "vendor_isp.h"
#define MAKERNOTEID 0x36353000
#define EXIF_MAKER "TC "
#define EXIF_SOFTWARE "R6.0"
#define __MODULE__ ExifVendor
#define __DBGLVL__ 2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER
#define __DBGFLT__ "*" //*=All, [mark]=CustomClass
#include <kwrap/debug.h>
static UINT32 m_uiPhotoQuality = 0;
static BOOL m_bCertified = FALSE;
UINT32 Imgexp = 0,Imgiso = 0; //sun chen@20240111
static const INT32 EV_NUMERATOR[(EV_SETTING_MAX)] = {
20,
17,
13,//
10,//
7,//
3,//
0,//
-3,//
-7,//
-10,//
-13,//
-17,//
-20//
};
typedef struct {
UINT32 MakerNoteCheckID;
UINT16 TestData1;
UINT16 TestData2;
char ExifBuf[SF_EXIF_MN_BUF_SIZE];
//Please reserve two word space to let capture flow save the screennail info.
UINT32 ScreennailOffset;
UINT32 ScreennailSize;
} SAMPLE_CODE_MAKER_NOTE, *PSAMPLE_CODE_MAKER_NOTE;
ER ExifCB(EXIF_EVENT event, PMEM_RANGE pBuffer, UINT32 uiRetParamNum, UINT32 *pParamArray)
{
//UINT32 i;
DBG_IND("event=%d, Buff Addr=0x%x, Size=0x%x, uiRetParamNum=%d\r\n", event, pBuffer->Addr, pBuffer->Size, uiRetParamNum);
if (CREATE_MAKERNOTE == event) {
SAMPLE_CODE_MAKER_NOTE MakerNoteSample = {0};
MakerNoteSample.MakerNoteCheckID = MAKERNOTEID;
#if (UI_FUNC == ENABLE)
MakerNoteSample.TestData1 = (UINT16)UI_GetData(FL_QUALITY);
#else
MakerNoteSample.TestData1 = (UINT16)QUALITY_FINE;
#endif
MakerNoteSample.TestData2 = 0xA5A5;
//PhotoStamp_get_isp_status(0,&MakerNoteSample.ExifBuf[0],SF_EXIF_MN_BUF_SIZE);
memcpy((void *)pBuffer->addr, (void *) &MakerNoteSample, sizeof(MakerNoteSample));
pBuffer->size = sizeof(MakerNoteSample);
} else if (PARSE_MAKERNOTE == event) {
//user could parse his own makenote data here
PSAMPLE_CODE_MAKER_NOTE pMakerNoteSample;
_ALIGNED(4) UINT8 AlignedBuf[sizeof(SAMPLE_CODE_MAKER_NOTE)];
//pBuffer->Addr may NOT be word-alignd!
if (pBuffer->addr & 0x3) {
memcpy((void *)AlignedBuf, (void *) pBuffer->addr, sizeof(SAMPLE_CODE_MAKER_NOTE));
pMakerNoteSample = (PSAMPLE_CODE_MAKER_NOTE)AlignedBuf;
} else {
pMakerNoteSample = (PSAMPLE_CODE_MAKER_NOTE)pBuffer->addr;
}
if (pMakerNoteSample->MakerNoteCheckID == MAKERNOTEID) {
DBG_MSG("MakerNote TestData1=0x%X, TestData2=0x%X\r\n", pMakerNoteSample->TestData1, pMakerNoteSample->TestData2);
m_bCertified = TRUE;
m_uiPhotoQuality = pMakerNoteSample->TestData1;
//If user wants to let playback decode screennal pic, the screennail info should be returned.
//pParamArray[0] is the offset of Screennail, which is from the start of JPEG file
//pParamArray[1] is the size of Screennail
if (2 == uiRetParamNum) {
pParamArray[0] = pMakerNoteSample->ScreennailOffset;
pParamArray[1] = pMakerNoteSample->ScreennailSize;
return E_OK;
}
} else {
m_bCertified = FALSE;
m_uiPhotoQuality = MAKERNOTEID;//It means that do NOT show the quality icon.
}
} else if (UPDATE_MAKERNOTE == event) {
//User could record screennail info here. pParamArray[0] is the ScreennailOffset and pParamArray[1] is the ScreennailSize.
if (2 == uiRetParamNum) {
SAMPLE_CODE_MAKER_NOTE MakerNoteSample = {0};
UINT32 Temp1, Temp2;
//to check if it's our makernote
Temp1 = Get32BitsData(pBuffer->addr, TRUE);
if (MAKERNOTEID == Temp1) {
DBG_IND("ScreennailOffset=0x%x, Size=0x%x\r\n", pParamArray[0], pParamArray[1]);
Temp1 = (UINT32)&MakerNoteSample.ScreennailOffset - (UINT32)&MakerNoteSample;
Temp2 = (UINT32)&MakerNoteSample.ScreennailSize - (UINT32)&MakerNoteSample;
Set32BitsData(pBuffer->addr + Temp1, pParamArray[0], TRUE);
Set32BitsData(pBuffer->addr + Temp2, pParamArray[1], TRUE);
return E_OK;
}
}
}
return E_SYS;
}
void ExifVendor_Write0thIFD(EXIF_HANDLE_ID HandleID)
{
UINT32 i;
CHAR ImageDescription[] = EXIF_IMAGE_DESCROPTOIN;
CHAR Maker[] = EXIF_MAKER;
CHAR Model[] = EXIF_MODEL_NAME;
UINT16 Orientation = 1;
UINT32 XResolution[2] = {72, 1};
UINT32 YResolution[2] = {72, 1};
UINT16 ResolutionUnit = 2;
CHAR SoftWare[] = EXIF_SOFTWARE;
CHAR DateTime[] = "2012:01:01 01:15:01";
UINT16 YCbCrPositioning = 2;
EXIF_SETTAG ZerothIFDTag[] = {
{EXIF_IFD_0TH, TAG_ID_IMAGE_DESCRIPTION, TAG_TYPE_ASCII, sizeof(ImageDescription), (UINT32)ImageDescription, sizeof(ImageDescription)},
{EXIF_IFD_0TH, TAG_ID_MAKE, TAG_TYPE_ASCII, sizeof(Maker), (UINT32)Maker, sizeof(Maker)},
{EXIF_IFD_0TH, TAG_ID_MODEL, TAG_TYPE_ASCII, sizeof(Model), (UINT32)Model, sizeof(Model)},
{EXIF_IFD_0TH, TAG_ID_ORIENTATION, TAG_TYPE_SHORT, 1, (UINT32) &Orientation, sizeof(Orientation)},
{EXIF_IFD_0TH, TAG_ID_X_RESOLUTION, TAG_TYPE_RATIONAL, 1, (UINT32)XResolution, sizeof(XResolution)},
{EXIF_IFD_0TH, TAG_ID_Y_RESOLUTION, TAG_TYPE_RATIONAL, 1, (UINT32)YResolution, sizeof(YResolution)},
{EXIF_IFD_0TH, TAG_ID_RESOLUTION_UNIT, TAG_TYPE_SHORT, 1, (UINT32) &ResolutionUnit, sizeof(ResolutionUnit)},
{EXIF_IFD_0TH, TAG_ID_SOFTWARE, TAG_TYPE_ASCII, sizeof(SoftWare), (UINT32)SoftWare, sizeof(SoftWare)},
{EXIF_IFD_0TH, TAG_ID_DATE_TIME, TAG_TYPE_ASCII, sizeof(DateTime), (UINT32)DateTime, sizeof(DateTime)},
{EXIF_IFD_0TH, TAG_ID_Y_CB_CR_POSITIONING, TAG_TYPE_SHORT, 1, (UINT32) &YCbCrPositioning, sizeof(YCbCrPositioning)},
};
// update datetime
{
struct tm DayTime = hwclock_get_time(TIME_ID_CURRENT);
//sprintf((char *)DateTime,"%04ld:%02ld:%02ld %02ld:%02ld:%02ld",DayTime.tm_year,DayTime.tm_mon,DayTime.tm_mday,DayTime.tm_hour,DayTime.tm_min,DayTime.tm_sec);
snprintf((char *)DateTime, sizeof(DateTime), "%04ld:%02ld:%02ld %02ld:%02ld:%02ld", DayTime.tm_year, DayTime.tm_mon, DayTime.tm_mday, DayTime.tm_hour, DayTime.tm_min, DayTime.tm_sec);
DBG_MSG("DateTime=%s\r\n", DateTime);
}
// write each exif data
for (i = 0; i < sizeof(ZerothIFDTag) / sizeof(EXIF_SETTAG); i++) {
EXIF_SetTag(HandleID, &ZerothIFDTag[i]);
}
}
void ExifVendor_WriteExifIFD(EXIF_HANDLE_ID HandleID)
{
UINT32 i;
UINT32 uiExposureTime[2] = {1, 32};
UINT32 uiFNumber[2] = {28, 10}; // F2.8
UINT32 uiISOSpeed = 100;
UINT16 uiExpProgram = ExpPrgNormal;
CHAR ExifVersion[] = {'0', '2', '2', '0'};
CHAR DateTimeOri[] = "2012:01:01 01:15:01";
CHAR DateTimeDigi[] = "2012:01:01 01:15:01";
CHAR ComponentCfg[] = {1, 2, 3, 0};
UINT32 uiShutterSpeed[2] = {50, 10};
UINT32 uiAperture[2] = {28, 10}; // F2.8
UINT32 uiBrightness[2] = {100, 100};// 100
UINT32 ExpoBias[2] = {0, 10};// 100
UINT32 MaxAperture[2] = {30, 10};// 30/10 = 3.0
UINT16 uiMeteringMode = 0;
UINT16 uiLightSource = 0;
UINT16 uiStrobeFlash = 0;
UINT32 FocalLen[2] = {30, 10};// 30/10 = 3.0
CHAR UserComment[20] = {0};
CHAR FlashPixelVersion[] = {'0', '1', '0', '0'};
UINT16 uiColorSpace = 1;
UINT16 uiPixelXDimension = 160;
UINT16 uiPixelYDimension = 120;
UINT16 uiSensingMethod = 2;
UINT32 uiFileSource = 3; // 3 means DSC
UINT32 uiSceneType = 1; // 1 means DSC recored this image
UINT16 uiCustomRendered = 0;
UINT16 uiExposureMode = 0;
UINT16 uiWhiteBalance = 0;
UINT32 uiDzoomRatio[2] = {100, 100};
UINT16 uiSceneCaptureType = 0;
UINT16 uiSharpness = 0;
UINT32 RecID;
//HD_RESULT hd_ret;
RecID = ImageApp_MovieMulti_VePort2Imglink(HandleID);
//sprintf(UserComment, "EXIF_HDL_ID_%d", HandleID+1);
snprintf(UserComment, sizeof(UserComment), "EXIF_HDL_ID_%d", HandleID + 1);
EXIF_SETTAG ExifIFDTag[] = {
{EXIF_IFD_EXIF, TAG_ID_EXPOSURE_TIME, TAG_TYPE_RATIONAL, 1, (UINT32) &uiExposureTime[0], sizeof(uiExposureTime)},
{EXIF_IFD_EXIF, TAG_ID_F_NUMBER, TAG_TYPE_RATIONAL, 1, (UINT32) &uiFNumber[0], sizeof(uiFNumber)},
{EXIF_IFD_EXIF, TAG_ID_EXPOSURE_PROGRAM, TAG_TYPE_SHORT, 1, (UINT32) &uiExpProgram, sizeof(uiExpProgram)},
{EXIF_IFD_EXIF, TAG_ID_ISO_SPEED_RATING, TAG_TYPE_SHORT, 1, (UINT32) &uiISOSpeed, sizeof(uiISOSpeed)},
{EXIF_IFD_EXIF, TAG_ID_EXIF_VERSION, TAG_TYPE_UNDEFINED, sizeof(ExifVersion), (UINT32) &ExifVersion[0], sizeof(ExifVersion)},
{EXIF_IFD_EXIF, TAG_ID_DATE_TIME_ORIGINAL, TAG_TYPE_ASCII, sizeof(DateTimeOri), (UINT32) &DateTimeOri[0], sizeof(DateTimeOri)},
{EXIF_IFD_EXIF, TAG_ID_DATA_TIME_DIGITIZED, TAG_TYPE_ASCII, sizeof(DateTimeDigi), (UINT32) &DateTimeDigi[0], sizeof(DateTimeDigi)},
{EXIF_IFD_EXIF, TAG_ID_COMPONENT_CONFIGURATION, TAG_TYPE_UNDEFINED, sizeof(ComponentCfg), (UINT32) &ComponentCfg[0], sizeof(ComponentCfg)},
{EXIF_IFD_EXIF, TAG_ID_SHUTTER_SPEED_VALUE, TAG_TYPE_SRATIONAL, 1, (UINT32) &uiShutterSpeed[0], sizeof(uiShutterSpeed)},
{EXIF_IFD_EXIF, TAG_ID_APERTURE_VALUE, TAG_TYPE_RATIONAL, 1, (UINT32) &uiAperture[0], sizeof(uiAperture)},
{EXIF_IFD_EXIF, TAG_ID_BRIGHTNESS, TAG_TYPE_SRATIONAL, 1, (UINT32) &uiBrightness[0], sizeof(uiBrightness)},
{EXIF_IFD_EXIF, TAG_ID_EXPOSURE_BIAS_VALUE, TAG_TYPE_SRATIONAL, 1, (UINT32) &ExpoBias[0], sizeof(ExpoBias)},
{EXIF_IFD_EXIF, TAG_ID_MAX_APERTURE_RATIO_VALUE, TAG_TYPE_RATIONAL, 1, (UINT32) &MaxAperture[0], sizeof(MaxAperture)},
{EXIF_IFD_EXIF, TAG_ID_METERING_MODE, TAG_TYPE_SHORT, 1, (UINT32) &uiMeteringMode, sizeof(uiMeteringMode)},
{EXIF_IFD_EXIF, TAG_ID_LIGHT_SOURCE, TAG_TYPE_SHORT, 1, (UINT32) &uiLightSource, sizeof(uiLightSource)},
{EXIF_IFD_EXIF, TAG_ID_FLASH, TAG_TYPE_SHORT, 1, (UINT32) &uiStrobeFlash, sizeof(uiStrobeFlash)},
{EXIF_IFD_EXIF, TAG_ID_FOCAL_LENGTH, TAG_TYPE_RATIONAL, 1, (UINT32) &FocalLen[0], sizeof(FocalLen)},
{EXIF_IFD_EXIF, TAG_ID_USER_COMMENT, TAG_TYPE_UNDEFINED, sizeof(UserComment), (UINT32) &UserComment[0], sizeof(UserComment)},
{EXIF_IFD_EXIF, TAG_ID_FLASH_PIX_VERSION, TAG_TYPE_UNDEFINED, sizeof(FlashPixelVersion), (UINT32) &FlashPixelVersion[0], sizeof(FlashPixelVersion)},
{EXIF_IFD_EXIF, TAG_ID_COLOR_SPACE, TAG_TYPE_SHORT, 1, (UINT32) &uiColorSpace, sizeof(uiColorSpace)},
{EXIF_IFD_EXIF, TAG_ID_PIXEL_X_DIMENSION, TAG_TYPE_SHORT, 1, (UINT32) &uiPixelXDimension, sizeof(uiPixelXDimension)},
{EXIF_IFD_EXIF, TAG_ID_PIXEL_Y_DIMENSION, TAG_TYPE_SHORT, 1, (UINT32) &uiPixelYDimension, sizeof(uiPixelYDimension)},
{EXIF_IFD_EXIF, TAG_ID_SENSING_METHOD, TAG_TYPE_SHORT, 1, (UINT32) &uiSensingMethod, sizeof(uiSensingMethod)},
{EXIF_IFD_EXIF, TAG_ID_FILE_SOURCE, TAG_TYPE_UNDEFINED, 1, (UINT32) &uiFileSource, sizeof(uiFileSource)},
{EXIF_IFD_EXIF, TAG_ID_SCENE_TYPE, TAG_TYPE_UNDEFINED, 1, (UINT32) &uiSceneType, sizeof(uiSceneType)},
{EXIF_IFD_EXIF, TAG_ID_CUSTOM_RENDERD, TAG_TYPE_SHORT, 1, (UINT32) &uiCustomRendered, sizeof(uiCustomRendered)},
{EXIF_IFD_EXIF, TAG_ID_EXPOSURE_MODE, TAG_TYPE_SHORT, 1, (UINT32) &uiExposureMode, sizeof(uiExposureMode)},
{EXIF_IFD_EXIF, TAG_ID_WHITE_BALANCE, TAG_TYPE_SHORT, 1, (UINT32) &uiWhiteBalance, sizeof(uiWhiteBalance)},
{EXIF_IFD_EXIF, TAG_ID_DZOOM_RATIO, TAG_TYPE_RATIONAL, 1, (UINT32) &uiDzoomRatio[0], sizeof(uiDzoomRatio)},
{EXIF_IFD_EXIF, TAG_ID_SCENE_CAPTURE_TYPE, TAG_TYPE_SHORT, 1, (UINT32) &uiSceneCaptureType, sizeof(uiSceneCaptureType)},
{EXIF_IFD_EXIF, TAG_ID_SHARPNESS, TAG_TYPE_SHORT, 1, (UINT32) &uiSharpness, sizeof(uiSharpness)}
};
/************** datetime **************/
{
struct tm DayTime = hwclock_get_time(TIME_ID_CURRENT);
//sprintf((char *)DateTimeOri,"%04ld:%02ld:%02ld %02ld:%02ld:%02ld",DayTime.tm_year,DayTime.tm_mon,DayTime.tm_mday,DayTime.tm_hour,DayTime.tm_min,DayTime.tm_sec);
snprintf((char *)DateTimeOri, sizeof(DateTimeOri), "%04ld:%02ld:%02ld %02ld:%02ld:%02ld", DayTime.tm_year, DayTime.tm_mon, DayTime.tm_mday, DayTime.tm_hour, DayTime.tm_min, DayTime.tm_sec);
//sprintf((char *)DateTimeDigi,"%04ld:%02ld:%02ld %02ld:%02ld:%02ld",DayTime.tm_year,DayTime.tm_mon,DayTime.tm_mday,DayTime.tm_hour,DayTime.tm_min,DayTime.tm_sec);
snprintf((char *)DateTimeDigi, sizeof(DateTimeDigi), "%04ld:%02ld:%02ld %02ld:%02ld:%02ld", DayTime.tm_year, DayTime.tm_mon, DayTime.tm_mday, DayTime.tm_hour, DayTime.tm_min, DayTime.tm_sec);
DBG_MSG("DateTimeOri=%s\r\n", DateTimeOri);
DBG_MSG("DateTimeDigi=%s\r\n", DateTimeDigi);
}
/************** photo w, h **************/
if (System_GetState(SYS_STATE_CURRMODE) == PRIMARY_MODE_MOVIE) {
uiPixelXDimension = MovieMapping_GetWidth(UI_GetData(FL_MOVIE_SIZE), RecID);
} else {
uiPixelXDimension = GetPhotoSizeWidth(UI_GetData(FL_PHOTO_SIZE));
}
//#NT#2016/08/30#Lincy Lin -begin
//#NT# Update correct image width in exif about sidebyside capture
if (UI_GetData(FL_CONTINUE_SHOT) == CONTINUE_SHOT_SIDE) {
uiPixelXDimension <<= 1;
}
//#NT#2016/08/30#Lincy Lin -end
if (System_GetState(SYS_STATE_CURRMODE) == PRIMARY_MODE_MOVIE) {
uiPixelYDimension = MovieMapping_GetHeight(UI_GetData(FL_MOVIE_SIZE), RecID);
} else {
uiPixelYDimension = GetPhotoSizeHeight(UI_GetData(FL_PHOTO_SIZE));
}
DBG_MSG("uiPixelXDimension=%d, uiPixelYDimension=%d\r\n", uiPixelXDimension, uiPixelYDimension);
/************** AE info **************/
{
UINT32 expo = 0;
float fexpo;
/*.............sun chen@20240111 start.................*/
//AET_STATUS_INFO status = {0};
#if 0//_TODO
AE_GetExifInfo(0, &uiISOSpeed, &expo, &uiAperture[0], &MaxAperture[0]);
#else
uiISOSpeed = 100;
expo = 1000000;
uiAperture[0] = 20;
MaxAperture[0] = 20;
#endif
//status.id=RecID;
/*if ((hd_ret = vendor_isp_init()) != HD_OK) {
DBG_ERR("vendor_isp_init() failed(%d)\r\n", hd_ret);
}
if ((hd_ret = vendor_isp_get_ae(AET_ITEM_STATUS, &status)) != HD_OK) {
DBG_ERR("vendor_isp_get_ae() failed(%d)\r\n", hd_ret);
}
if ((hd_ret = vendor_isp_uninit()) != HD_OK) {
DBG_ERR("vendor_isp_uninit() failed(%d)\r\n", hd_ret);
}*/
uiISOSpeed= Imgiso;//status.status_info.iso_gain[0];
expo= Imgexp;//status.status_info.expotime[0];
DBG_ERR("RecID=%d, uiISOSpeed=%d, expo=%d\r\n",RecID,uiISOSpeed,expo);
/*.............sun chen@20240111 end.................*/
uiFNumber[0] = uiAperture[0];
uiAperture[0] = 20 * log2((float)uiAperture[0] / 10);
MaxAperture[0] = 20 * log2((float)MaxAperture[0] / 10);
uiShutterSpeed[0] = -log2((float)expo / 1000000) * 10;
fexpo = (float)expo / 1000000;
if (fexpo > 1) {
// the value is integer
uiExposureTime[0] = fexpo * 10;
uiExposureTime[1] = 10;
} else {
uiExposureTime[0] = 1;
uiExposureTime[1] = 1 / fexpo;
}
DBG_MSG("uiFNumber =%d/%d uiAperture=%d/%d, MaxAperture=%d/%d \r\n", uiFNumber[0], uiFNumber[1], uiAperture[0], uiAperture[1], MaxAperture[0], MaxAperture[1]);
DBG_MSG("uiShutterSpeed=%d/%d\r\n", uiShutterSpeed[0], uiShutterSpeed[1]);
DBG_MSG("time = %d us ,uiExposureTime = %d/%d \r\n", expo, uiExposureTime[0], uiExposureTime[1]);
}
/************** ExposureMode **************/
switch (UI_GetData(FL_ModeIndex)) {
case DSC_MODE_PHOTO_AUTO:
uiExposureMode = AutoExposure;
break;
case DSC_MODE_PHOTO_MANUAL:
default:
uiExposureMode = ManualExposure;
break;
}
DBG_MSG("uiExposureMode = %d \r\n", uiExposureMode);
/************** ExposureProgram **************/
if (UI_GetData(FL_ModeIndex) == DSC_MODE_PHOTO_SCENE) {
switch (UI_GetData(FL_SCENE)) {
case SCENE_PORTRAIT:
case SCENE_LANDSCAPE:
case SCENE_NIGHTLANDSCAPE:
uiExpProgram = ExpPrgCreative;
break;
default:
uiExpProgram = ExpPrgNormal;
break;
}
} else {
switch (UI_GetData(FL_ModeIndex)) {
case DSC_MODE_PHOTO_PORTRAIT:
uiExpProgram = ExpPrgCreative;
break;
default:
uiExpProgram = ExpPrgNormal;
break;
}
}
DBG_MSG("uiExpProgram = %d \r\n", uiExpProgram);
/************** MeteringMode **************/
switch (UI_GetData(FL_METERING)) {
case METERING_CENTER:
uiMeteringMode = MeterCenterWeightedAvg;
break;
case METERING_SPOT:
uiMeteringMode = MeterSpot;
break;
case METERING_AIAE:
uiMeteringMode = MeterAverage;
break;
default:
uiMeteringMode = MeterUnknown;
break;
}
DBG_MSG("uiMeteringMode = %d \r\n", uiMeteringMode);
/************** EV **************/
{
ExpoBias[0] = EV_NUMERATOR[UI_GetData(FL_EV)];
DBG_MSG("ExpoBias = %d/%d \r\n", ExpoBias[0], ExpoBias[1]);
}
/************** light source **************/
switch (UI_GetData(FL_WB)) {
case WB_AUTO:
uiLightSource = LightUnknown;
break;
case WB_DAYLIGHT:
uiLightSource = LightFineWeather;
break;
case WB_CLOUDY :
uiLightSource = LightCloudyWeather;
break;
case WB_FLUORESCENT1:
uiLightSource = LightDayWhiteFluorescent;
break;
case WB_FLUORESCENT2:
uiLightSource = LightDaylightFluorescent;
break;
case WB_INCAND:
uiLightSource = LightTungsten;
break;
default:
uiLightSource = LightUnknown;
break;
}
DBG_MSG("uiLightSource = %d \r\n", uiLightSource);
/************** WB **************/
#if 0
if (UI_GetData(FL_WB) == WB_AUTO) {
uiWhiteBalance = AutoWhite;
} else {
uiWhiteBalance = ManualWhite;
}
#else
uiWhiteBalance = UI_GetData(FL_WB);
#endif
DBG_MSG("uiWhiteBalance = %d \r\n", uiWhiteBalance);
/************** Dzoom **************/
#if(PHOTO_MODE == ENABLE && DZOOM_FUNC == ENABLE)
// uiDzoomRatio[0] = PhotoExe_GetDZoomRatio();
uiDzoomRatio[0] = 50;
#endif
if (uiDzoomRatio[0] == 100) {
uiDzoomRatio[0] = 0; // 0 means Dzoom is not enable
}
DBG_MSG("uiDzoomRatio = %d/%d \r\n", uiDzoomRatio[0], uiDzoomRatio[1]);
/************** Flashlight **************/
uiStrobeFlash = 0;
switch (UI_GetData(FL_FLASH_MODE)) {
case FLASH_OFF:
uiStrobeFlash = StrobeFlashForceOFF;
break;
case FLASH_ON:
uiStrobeFlash = StrobeFlashForceON | StrobeFired;
break;
case FLASH_AUTO:
uiStrobeFlash = StrobeFlashAuto;
#if 0
if (CapInfo->Flash) {
uiStrobeFlash += StrobeFired;
}
#endif
break;
case FLASH_RED_EYE:
uiStrobeFlash = StrobeFlashAutoRedEye;
#if 0
if (CapInfo->Flash) {
uiStrobeFlash += StrobeFired;
}
#endif
break;
case FLASH_SLOW_FLASH_EYE:
uiStrobeFlash = StrobeFlashForceONRedEye;
break;
case FLASH_SLOW_FLASH:
uiStrobeFlash = StrobeFlashNightStrobe;
break;
default:
uiStrobeFlash = StrobeFlashAuto;
break;
}
DBG_MSG("uiStrobeFlash = 0x%x \r\n", uiStrobeFlash);
/************** FocalLen **************/
#if (LENS_FUNCTION == ENABLE)
FocalLen[0] = Lens_FocusGetFocalLength(OZOOM_IDX_GET());
DBG_MSG("FocalLen = %d/%d \r\n", FocalLen[0], FocalLen[1]);
#endif
/************** Sharpness **************/
switch (UI_GetData(FL_SHARPNESS)) {
case SHARPNESS_SHARP:
uiSharpness = HARD_SHARPNESS;
break;
case SHARPNESS_SOFT:
uiSharpness = SOFT_SHARPNESS;
break;
case SHARPNESS_NORMAL:
default:
uiSharpness = NORMAL_SHARPNESS;
break;
}
// write each exif data
for (i = 0; i < sizeof(ExifIFDTag) / sizeof(EXIF_SETTAG); i++) {
EXIF_SetTag(HandleID, &ExifIFDTag[i]);
}
}
void ExifVendor_Write0thIntIFD(EXIF_HANDLE_ID HandleID)
{
UINT32 i;
CHAR InterOper[] = "R98";
CHAR Exif98Ver[] = {'0', '1', '0', '0'};
EXIF_SETTAG ZerothIntIFDTag[] = {
{EXIF_IFD_INTEROPERABILITY, TAG_ID_INTER_OPERABILITY_INDEX, TAG_TYPE_ASCII, sizeof(InterOper), (UINT32)InterOper, sizeof(InterOper)}, //R98
{EXIF_IFD_INTEROPERABILITY, TAG_ID_EXIF_98_VERSION, TAG_TYPE_UNDEFINED, sizeof(Exif98Ver), (UINT32)Exif98Ver, sizeof(Exif98Ver)} //0100
};
// write each exif data
for (i = 0; i < sizeof(ZerothIntIFDTag) / sizeof(EXIF_SETTAG); i++) {
EXIF_SetTag(HandleID, &ZerothIntIFDTag[i]);
}
}
void ExifVendor_WriteGPSIFD(EXIF_HANDLE_ID HandleID)
{
// Latitude and Longitude values should be replaced by project.
UINT32 i;
CHAR GPSVersionID[] = {'2','2','0','0'};
CHAR GPSLatitudeRef[] = {'N'};
UINT32 GPSLatitude[6] = {0x16,0x01,0x22,0x01,0x51,0x04};
CHAR GPSLongitudeRef[] = {'E'};
UINT32 GPSLongitude[6] = {0x71,0x01,0x37,0x01,0x6c,0x04};
EXIF_SETTAG GPSIFDTag[] =
{
{EXIF_IFD_GPS, TAG_ID_GPS_VERSIONID, TAG_TYPE_BYTE, 4, (UINT32)&GPSVersionID, sizeof(GPSVersionID) },
{EXIF_IFD_GPS, TAG_ID_GPS_LATITUDEREF, TAG_TYPE_ASCII, 2, (UINT32)&GPSLatitudeRef, sizeof(GPSLatitudeRef) },
{EXIF_IFD_GPS, TAG_ID_GPS_LATITUDE, TAG_TYPE_RATIONAL, 3, (UINT32)&GPSLatitude, sizeof(GPSLatitude)},
{EXIF_IFD_GPS, TAG_ID_GPS_LONGITUDEREF, TAG_TYPE_ASCII, 2, (UINT32)&GPSLongitudeRef, sizeof(GPSLongitudeRef)},
{EXIF_IFD_GPS, TAG_ID_GPS_LONGITUDE, TAG_TYPE_RATIONAL, 3, (UINT32)&GPSLongitude, sizeof(GPSLongitude)},
};
// write each exif data
for(i=0; i<sizeof(GPSIFDTag)/sizeof(EXIF_SETTAG); i++)
{
EXIF_SetTag(HandleID, &GPSIFDTag[i]);
}
}
void ExifVendor_SetData(EXIFVENDOR_DATA_SET attribute, UINT32 value)
{
switch (attribute) {
case EXIFVENDOR_QUALITY:
m_uiPhotoQuality = (UINT32)value;
break;
default:
DBG_ERR("no this attribute");
break;
}
}
UINT32 ExifVendor_GetData(EXIFVENDOR_DATA_SET attribute)
{
switch (attribute) {
case EXIFVENDOR_CERTIFICATION:
return m_bCertified;
case EXIFVENDOR_QUALITY:
return m_uiPhotoQuality;
default:
DBG_ERR("no this attribute");
return 0;
}
}
/**
Get byte number of Rat_num/Rat_denum
*/
static int GetRatByteNum(INT32 Rat)
{
INT32 RatByteNum ;
if (Rat > 0) {
RatByteNum = 1;
} else {
return 0;
}
while ((Rat = Rat / 10) != 0) {
RatByteNum++;
}
return RatByteNum;
}
static INT32 Power(INT32 base, INT32 time)
{
INT32 result = 1;
while (time) {
result = result * base;
time --;
}
return result;
}
/*
This function will convert Rat_num/Rat_denum to string ( /-)XX.X (at most 6 Chars)
if Rat_denum=0 or Rat_num=0, string will be 0
*/
void RationalToStr(INT32 Rat_num, INT32 Rat_denum, UINT8 *pstr)
{
int integer, tempchar, tempdigit, remainder;
if ((Rat_denum != 0) && (Rat_num != 0)) {
if (Rat_num < 0) {
*pstr = '-';
pstr++;
Rat_num = -Rat_num;
}
integer = (int)(Rat_num / Rat_denum);
remainder = Rat_num - (Rat_denum * integer);
remainder = remainder * 10; // + (Rat_denum>>1);
tempchar = remainder / Rat_denum;
tempdigit = integer / 10;
if (tempdigit) {
*pstr++ = 0x30 + tempdigit ;
}
*pstr++ = 0x30 + (integer % 10);
*pstr++ = '.';
*pstr++ = 0x30 + tempchar;
*pstr = 0; //null string
} else {
*pstr = 0x30;
*(pstr + 1) = 0;
}
}
void ExposureBiasToStr(INT32 Rat_num, INT32 Rat_denum, UINT8 *pstr)
{
int integer, tempchar, tempdigit, remainder, remainder2;
if ((Rat_denum != 0) && (Rat_num != 0)) {
if (Rat_num < 0) {
*pstr = '-';
Rat_num = -Rat_num;
} else {
*pstr = '+';
}
pstr++;
integer = (int)(Rat_num / Rat_denum);
remainder = Rat_num - (Rat_denum * integer);
remainder = remainder * 10;
tempchar = remainder / Rat_denum;
tempdigit = integer / 10;
if (tempdigit) { // > 10
*pstr++ = 0x30 + tempdigit ;
*pstr++ = 0x30 + (integer % 10);
*pstr++ = '.';
*pstr++ = 0x30 + tempchar;
*pstr = '\0';
} else {
remainder2 = remainder - (Rat_denum * tempchar);
if (remainder2 == 0 || (tempchar != 3 && tempchar != 6)) {
*pstr++ = 0x30 + integer;
*pstr++ = '.';
*pstr++ = 0x30 + tempchar;
*pstr = '\0';
} else { // tempchar == 3 or 6
*pstr++ = 0x30 + integer * 3 + ((tempchar + 3) * 3 / 10);
*pstr++ = '/';
*pstr++ = '3';
*pstr = '\0';
}
}
} else {
*pstr++ = '+';
*pstr++ = '0';
*pstr++ = '.';
*pstr++ = '0';
*pstr = '\0';
}
}
/**
This function will convert Rat_num/Rat_denum to string XX/XX (at most 6 Chars)
if Rat_denum=0 or Rat_num=0, string will be 0
*/
void ExposureTimeToStr(INT32 Rat_num, INT32 Rat_denum, UINT8 *pstr)
{
INT32 integer, tempdigit;
INT32 Rat_num_byteNum, Rat_denum_ByteNum;
INT32 i;
if ((Rat_denum != 0) && (Rat_num != 0)) {
if (Rat_num > Rat_denum) {
Rat_num = Rat_num / Rat_denum;
Rat_num_byteNum = GetRatByteNum(Rat_num);
for (i = 0; i < Rat_num_byteNum; i++) {
integer = Rat_num / Power(10, Rat_num_byteNum - 1 - i);
Rat_num = Rat_num % Power(10, Rat_num_byteNum - 1 - i);
*pstr++ = 0x30 + integer ;
}
*pstr++ = '/';
*pstr++ = '1';
} else {
if (Rat_num != 0x01) {
Rat_denum /= Rat_num;
Rat_num = 0x01;
}
Rat_num_byteNum = GetRatByteNum(Rat_num);
for (i = 0; i < Rat_num_byteNum; i++) {
integer = Rat_num / Power(10, Rat_num_byteNum - 1 - i);
Rat_num = Rat_num % Power(10, Rat_num_byteNum - 1 - i);
*pstr++ = 0x30 + integer ;
}
*pstr++ = '/';
Rat_denum_ByteNum = GetRatByteNum(Rat_denum);
for (i = 0; i < Rat_denum_ByteNum; i++) {
tempdigit = Rat_denum / Power(10, Rat_denum_ByteNum - 1 - i);
Rat_denum = Rat_denum % Power(10, Rat_denum_ByteNum - 1 - i);
*pstr++ = 0x30 + tempdigit ;
}
}
*pstr = 0; //null string
} else {
*pstr = 0x30;
*(pstr + 1) = 0;
}
}