/** 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 //#include #include #include #include "exif/ExifDef.h" #include "ImageApp/ImageApp_MovieMulti.h" #include "vendor_isp.h" #define MAKERNOTEID 0x36353000 #define EXIF_MAKER "MAKER NAME " #define EXIF_SOFTWARE "Verx.xx" #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 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; //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; 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] = 18; MaxAperture[0] = 18; #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 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; } }