727 lines
25 KiB
C
Executable File
727 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;
|
|
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;
|
|
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=status.status_info.iso_gain[0];
|
|
expo=status.status_info.expotime[0];
|
|
DBG_MSG("RecID=%d, uiISOSpeed=%d, expo=%d\r\n",RecID,uiISOSpeed,expo);
|
|
|
|
|
|
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;
|
|
}
|
|
}
|
|
|