⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exif.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*****************************************************************************
*  Copyright Statement:
*  --------------------
*  This software is protected by Copyright and the information contained
*  herein is confidential. The software may not be copied and the information
*  contained herein may not be used or disclosed except with the written
*  permission of MediaTek Inc. (C) 2005
*
*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
*
*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/

/*****************************************************************************
 *
 * Filename:
 * ---------
 *   exif.c
 *
 * Project:
 * --------
 *   MT6226,MT6227,MT6228,MT6229
 *
 * Description:
 * ------------
 *   This file is intends for Exif encoder.
 *
 * Author:
 * -------
 * -------
 *
 *============================================================================
 *             HISTORY
 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
 *------------------------------------------------------------------------------
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *------------------------------------------------------------------------------
 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
 *============================================================================
 ****************************************************************************/
#include <stdio.h>
#include <string.h>

#if (defined(EXIF_SUPPORT))
#include "exif.h"
#include "exif_table.h"	

#include "Drm_gprot.h"
#include "kal_release.h"
#include "FSAL.h"
#include "rtc_sw.h"

extern void RTC_GetTime(t_rtc *rtctime);
extern kal_char* release_verno(void);
extern void exif_update_MTK_para_struct(exif_MTK_para_struct *exif_MTK_para);

/* Global variables  */
kal_uint32	exif_IFD0_Entry_Switch= 0x0080;		/* Switch off all cam &cus entries as default */
kal_uint32	exif_ExifIFD_Entry_Switch= 0x0000; /* Switch off all cam & cus entries as default */
kal_uint32	exif_ExIFD_Entry_Switch=0x0000; 

kal_bool cam_para_get=KAL_FALSE;
kal_bool cus_para_get=KAL_FALSE;

kal_bool exif_AscOrder;

kal_uint8 exif_next_ExIFD_entry;

exif_cam_para_struct exif_cam_para;
exif_MTK_para_struct exif_MTK_para;

exif_LONG exif_ExifIFD_Offset;

kal_uint16	IFD0_Entry_Size;
kal_uint16	IFD0_Value_Size;
kal_uint16	ExifIFD_Entry_Size;
kal_uint16	ExifIFD_Value_Size;
kal_uint16	IFD_TiffHeader_Offset;

/* Number of entries of each IFD */
kal_uint16 exif_IFD0_count;
kal_uint16 exif_ExifIFD_count;

/* Buffer pointer*/
kal_uint8*  exif_Buffer;

/* Required Buffer Size for EXIF encoding*/
kal_uint16	exif_BufferSize;

exif_extend_entry_struct* ExIFD;
kal_uint8 ExIFD_Number_of_Entry=0;

/* tables */
exif_entry_struct IFD0[IFD0_Number_of_Entry]=
{
	//{exif_tag_Make,			EXIF_ASCII,		0,	&exif_cus_para.Make},
	//{exif_tag_Model,			EXIF_ASCII,		0,	&exif_cus_para.Model},
	{exif_tag_Orientation,		EXIF_SHORT,		1,	&exif_cam_para.Orientation},
	{exif_tag_XResolution,		EXIF_RATIONAL,	1,	&exif_cam_para.XResolution},
	{exif_tag_YResolution,		EXIF_RATIONAL,	1,	&exif_cam_para.YResolution},
	{exif_tag_ResolutionUnit,	EXIF_SHORT,		1,	&exif_cam_para.ResolutionUnit},

	{exif_tag_Software,			EXIF_ASCII,		0,	&exif_cam_para.Software},
	{exif_tag_DateTime,			EXIF_ASCII,		0,	&exif_cam_para.DateTime},
	{exif_tag_YCbCrPositioning,	EXIF_SHORT,		1,	&exif_cam_para.YCbCrPositioning},
	{exif_tag_ExifIFD,			EXIF_LONG,		1,	&exif_ExifIFD_Offset}
};

exif_entry_struct ExifIFD[ExifIFD_Number_of_Entry]=
{
	{exif_tag_ExposureTime,		EXIF_RATIONAL,	1,	&exif_cam_para.ExposureTime},
	{exif_tag_FNumber,			EXIF_RATIONAL,	1,	&exif_cam_para.FNumber},
	{exif_tag_ExposureProgram,	EXIF_SHORT,		1,	&exif_cam_para.ExposureProgram},
	{exif_tag_ISOSpeedRatings,	EXIF_SHORT,		1,	&exif_cam_para.ISOSpeedRatings},
	{exif_tag_ExifVersion,		EXIF_UNDEFINED,	4,	&exif_cam_para.ExifVersion},

	{exif_tag_DateTimeOriginal,	EXIF_ASCII,		0,	&exif_cam_para.DateTimeOriginal},
	{exif_tag_DateTimeDigitized,EXIF_ASCII,		0,	&exif_cam_para.DateTimeDigitized},
	{exif_tag_ComponentsConfig,	EXIF_UNDEFINED,	4,	&exif_cam_para.ComponentsConfig},
	{exif_tag_ExposureBiasValue,EXIF_SRATIONAL,	1,	&exif_cam_para.ExposureBiasValue},
	{exif_tag_MeteringMode,		EXIF_SHORT,		1,	&exif_cam_para.MeteringMode},

	{exif_tag_LightSource,		EXIF_SHORT,		1,	&exif_cam_para.LightSource},
	{exif_tag_Flash,			EXIF_SHORT,		1,	&exif_cam_para.Flash},
	{exif_tag_MakerNote,		EXIF_UNDEFINED,	sizeof(exif_MTK_para_struct),&exif_MTK_para},
	//{exif_tag_UserComment,	EXIF_UNDEFINED,	exif_Count_UserComment,&exif_cus_para.UserComment},
	{exif_tag_FlashpixVersion,	EXIF_UNDEFINED,	4,	&exif_cam_para.FlashpixVersion},

	{exif_tag_ColorSpace,		EXIF_SHORT,		1,	&exif_cam_para.ColorSpace},
	{exif_tag_PixelXDimension,	EXIF_LONG,		1,	&exif_cam_para.PixelXDimension},
	{exif_tag_PixelYDimension,	EXIF_LONG,		1,	&exif_cam_para.PixelYDimension},
	{exif_tag_ExposureMode,		EXIF_SHORT,		1,	&exif_cam_para.ExposureMode},
	{exif_tag_DigitalZoomRatio,	EXIF_RATIONAL,	1,	&exif_cam_para.DigitalZoomRatio},

	{exif_tag_SceneCaptureType,	EXIF_SHORT,		1,	&exif_cam_para.SceneCaptureType}
};


/* Exif Headers */
kal_uint8	exif_Header[exif_header_size]={0xff,0xe1,0x00,0x00,'E','x','i','f','\0',0};
const kal_uint8	exif_tiffHeader[tiff_header_size]={0x49,0x49,0x2a,0x00,0x08,0x00,0x00,0x00};

kal_uint16 exif_Accumulate_ASCII(char* str,kal_uint16* IFD_Value_Size);

kal_bool exif_Acc_IFD_Size(exif_entry_struct* Exif_entry,kal_uint16* IFD_count,kal_uint16* IFD_Entry_Size,kal_uint16* IFD_Value_Size);
void exif_Fillin_tag(exif_entry_struct* Exif_entry,kal_uint16* IFD_entry_offset,kal_uint16* IFD_value_offset);
void exif_Fillin_32(kal_uint8* Buffer, kal_uint16* Offset, kal_uint32 Value);
void exif_Fillin_16(kal_uint8* Buffer, kal_uint16* Offset, kal_uint16 Value);
void exif_Fillin_ASCII(kal_uint8* Buffer, kal_uint16* Offset, kal_char* Value,kal_uint32 count);

void exif_switch_cam_entry(kal_uint8 action);
void exif_switch_cus_entry(kal_uint8 action);
kal_bool exif_is_switched_on(kal_uint8 IFD,kal_uint8 Entry);
void exif_check_ExIFD_data(void);

kal_uint16 exif_Calculate_Buffer_Size(kal_uint32 BufferOffset);

kal_uint8 exif_get_next_extended_tag(kal_uint8 IFD,kal_uint16 MinTag);

exif_ASCII exif_sys_time[20]={'y','y','y','y',':','m','m',':','d','d',' ','h','h',':','m','m',':','s','s','\0'};

//exif_ASCII* exif_sys_time="yyyy:mm:dd hh:mm:ss";

void exif_uint8_to_char(kal_uint8 val,kal_char* h, kal_char* l)
{
 if(val>=100)
 {
  *h='9';	
  *l='9';	
  return;
 }
 *h=val/10;
 *l=val%10;
 return;	
}

void exif_get_sys_time()
{
 t_rtc exif_time;
 RTC_GetTime(&exif_time);	
 
 exif_sys_time[0]='2';
 if(exif_time.rtc_year>=100)
 {
  exif_sys_time[1]='1';
  exif_time.rtc_year-=100;
 }
 else
  exif_sys_time[1]='0';
  
 exif_sys_time[2]=(exif_time.rtc_year/10)+48;
 exif_sys_time[3]=(exif_time.rtc_year%10)+48;
 
 exif_sys_time[5]=(exif_time.rtc_mon/10)+48;
 exif_sys_time[6]=(exif_time.rtc_mon%10)+48;
 
 exif_sys_time[8]=(exif_time.rtc_day/10)+48;
 exif_sys_time[9]=(exif_time.rtc_day%10)+48;
 
 exif_sys_time[11]=(exif_time.rtc_hour/10)+48;
 exif_sys_time[12]=(exif_time.rtc_hour%10)+48;
 
 exif_sys_time[14]=(exif_time.rtc_min/10)+48;
 exif_sys_time[15]=(exif_time.rtc_min%10)+48;
 
 exif_sys_time[17]=(exif_time.rtc_sec/10)+48;
 exif_sys_time[18]=(exif_time.rtc_sec%10)+48;
}			

/* Set preDefined values to some of the IFD entries */
exif_cam_para_struct* exif_get_cam_para_struct(void)
{
	exif_get_sys_time();
	
	exif_cam_para.Orientation=1;
	exif_cam_para.XResolution[0]=72;
	exif_cam_para.XResolution[1]=1;
	exif_cam_para.YResolution[0]=72;
	exif_cam_para.YResolution[1]=1;
	exif_cam_para.ResolutionUnit=2;	/* inches */

	exif_cam_para.Software=(kal_char*)release_verno();
	exif_cam_para.DateTime=exif_sys_time; //"yyyy:mm:dd hh:mm:ss";
	
	exif_cam_para.YCbCrPositioning=2;/* co-siteded */

	/* Exif IFD default values */

	exif_cam_para.ExposureTime[0]=0;
	exif_cam_para.ExposureTime[1]=0;

	exif_cam_para.FNumber[0]=0;
	exif_cam_para.FNumber[1]=0;

	exif_cam_para.ExposureProgram=0;	/* Unknown*/

	exif_cam_para.ISOSpeedRatings=0;

	exif_cam_para.ExifVersion[3]='0';/* Supported Exif Version: 2.2*/
	exif_cam_para.ExifVersion[2]='2';
	exif_cam_para.ExifVersion[1]='2';
	exif_cam_para.ExifVersion[0]='0';

	exif_cam_para.DateTimeOriginal=0;
	exif_cam_para.DateTimeDigitized=0;
	
	exif_cam_para.ComponentsConfig[0]=1;	/* YCbCr */
	exif_cam_para.ComponentsConfig[1]=2;
	exif_cam_para.ComponentsConfig[2]=3;
	exif_cam_para.ComponentsConfig[3]=0;
	
	exif_cam_para.ExposureBiasValue[0]=0;
	exif_cam_para.ExposureBiasValue[1]=1;

	exif_cam_para.MeteringMode=0;
	exif_cam_para.LightSource=0;
	exif_cam_para.Flash=0;

	exif_cam_para.FlashpixVersion[3]='0';
	exif_cam_para.FlashpixVersion[2]='0';
	exif_cam_para.FlashpixVersion[1]='1';
	exif_cam_para.FlashpixVersion[0]='0';

	exif_cam_para.ColorSpace=1;	/* sRGB */

	exif_cam_para.PixelXDimension=0;
	exif_cam_para.PixelYDimension=0;

	exif_cam_para.ExposureMode=0; /* auto exposure */

	exif_cam_para.DigitalZoomRatio[0]=1;
	exif_cam_para.DigitalZoomRatio[1]=1;

	exif_cam_para.SceneCaptureType=0; /* standard */

	cam_para_get=KAL_TRUE;
	exif_switch_cam_entry(EXIF_SWITCH_ON);

	/* Temporly switch FNumber off*/
	exif_switch_IFD_entry(EXIF_EXIFIFD,EXIF_FNUMBER,EXIF_SWITCH_OFF);

	return &exif_cam_para;
}

exif_MTK_para_struct* exif_get_MTK_para_struct(void)
{
	strcpy(exif_MTK_para.title,"MediaTek");
	exif_MTK_para.version[0]=exif_MTK_specific_ver_main;
	exif_MTK_para.version[1]=exif_MTK_specific_ver_fraction;

	exif_update_MTK_para_struct(&exif_MTK_para);   

	cam_para_get=KAL_TRUE;
	exif_switch_IFD_entry(EXIF_EXIFIFD,EXIF_MAKER_NOTE,EXIF_SWITCH_ON);

	return &exif_MTK_para;
}

kal_uint16 exif_Fillin_Buffer(kal_uint8* Buffer,kal_uint32 BufferOffset)
{
	kal_uint16 BufferSize;

	ExIFD=exif_get_custom_specific_IFD(&ExIFD_Number_of_Entry);

	exif_check_ExIFD_data();

	BufferSize=exif_Calculate_Buffer_Size(BufferOffset);
	
	if(BufferSize==0) 
	 return BufferSize;
	else if(BufferSize>EXIF_MAXIMUM_SIZE)
	 ASSERT(0);

	exif_Fillin_Header(Buffer,BufferOffset);

	return BufferSize;

}

/* Used for MT6227*/
kal_uint16 exif_get_custom_IFD_and_buffer_size(kal_uint32 BufferOffset)
{
 kal_uint16 BufferSize;
 ExIFD=exif_get_custom_specific_IFD(&ExIFD_Number_of_Entry);
 exif_check_ExIFD_data();
 BufferSize=exif_Calculate_Buffer_Size(BufferOffset);

 if(BufferSize>EXIF_MAXIMUM_SIZE)
	 ASSERT(0);
 return BufferSize;
}

/* Accumulate the Exif Buffer Size */
kal_uint16 exif_Calculate_Buffer_Size(kal_uint32 BufferOffset)
{
 kal_uint8	i;
 kal_uint32	mask=1;

 if(!cam_para_get && !cus_para_get)
  return 0;
	//return exif_Overlap_Offset;
	

 IFD0_Entry_Size=0;
 IFD0_Value_Size=0;
 ExifIFD_Entry_Size=0;
 ExifIFD_Value_Size=0;

 exif_IFD0_count=0;
 exif_ExifIFD_count=0;
 //--Acc ExifIFD--
 if(exif_is_switched_on(EXIF_IFD0,EXIF_EXIF_IFD))
 {
    mask=1;
	for(i=0;i<ExifIFD_Number_of_Entry;i++)
	{
	 if((exif_ExifIFD_Entry_Switch & mask)==0)// This entry is switched off
	 {
		mask<<=1;
		continue;
	 }

	exif_Acc_IFD_Size(&ExifIFD[i],&exif_ExifIFD_count,&ExifIFD_Entry_Size,&ExifIFD_Value_Size);
	mask<<=1;

	}
 }
 //--Acc ExIFD--
 for(i=0;i<ExIFD_Number_of_Entry;i++)
 {
	if(ExIFD[i].exif_IFD_type==EXIF_IFD0)
	 exif_Acc_IFD_Size(&ExIFD[i].entry,&exif_IFD0_count,&IFD0_Entry_Size,&IFD0_Value_Size);
	else if(ExIFD[i].exif_IFD_type==EXIF_EXIFIFD && exif_is_switched_on(EXIF_IFD0,EXIF_EXIF_IFD))
	 exif_Acc_IFD_Size(&ExIFD[i].entry,&exif_ExifIFD_count,&ExifIFD_Entry_Size,&ExifIFD_Value_Size);
 }

 //--Acc IFD0--
 mask=1;
 for(i=0;i<EXIF_EXIF_IFD;i++)
 {
  	if((exif_IFD0_Entry_Switch & mask)==0)// This entry is switched off
	 {
		mask<<=1;
		continue;
	 }
	exif_Acc_IFD_Size(&IFD0[i],&exif_IFD0_count,&IFD0_Entry_Size,&IFD0_Value_Size);
	mask<<=1;
 }
 //--Acc ExifIFD entry of IFD0--
 if(exif_ExifIFD_count>0 && exif_is_switched_on(EXIF_IFD0,EXIF_EXIF_IFD))	
  exif_Acc_IFD_Size(&IFD0[EXIF_EXIF_IFD],&exif_IFD0_count,&IFD0_Entry_Size,&IFD0_Value_Size);

if(exif_IFD0_count==0 && exif_ExifIFD_count==0)
  return 0;
  //return exif_Overlap_Offset;

if(exif_IFD0_count>0)
 IFD0_Entry_Size+=(2+4);

if(exif_ExifIFD_count>0) 
 ExifIFD_Entry_Size+=(2+4);

/*-- Get TiffHeaderOffset --*/
 IFD_TiffHeader_Offset=BufferOffset+exif_header_size;

 exif_BufferSize=exif_header_size+tiff_header_size+IFD0_Entry_Size+IFD0_Value_Size+ExifIFD_Entry_Size+ExifIFD_Value_Size;

 /*//-- 4 bytes align--
 if(exif_BufferSize & 0x03 !=0)
	 exif_BufferSize=((exif_BufferSize+4)>>2)<<2;
*/

 /*--Fill in the length field of app0 marker--*/
 exif_Header[2]=(exif_BufferSize-2)>>8 & 0xff;
 exif_Header[3]=(exif_BufferSize-2) & 0xff;

 /*--Fill IFD0 ExifIFD entry. 12: jpeg SOI marker and exif header, 8: Tiff Header --*/
 exif_ExifIFD_Offset=BufferOffset+exif_header_size+tiff_header_size+IFD0_Entry_Size+IFD0_Value_Size-IFD_TiffHeader_Offset;
 
 return exif_BufferSize;

}

kal_bool exif_Acc_IFD_Size(exif_entry_struct* Exif_entry,kal_uint16* IFD_entry_count,kal_uint16* IFD_Entry_Size,kal_uint16* IFD_Value_Size)
{
	if(Exif_entry->type!=EXIF_ASCII && Exif_entry->count==0)
		ASSERT(0);

	 switch(Exif_entry->type)
	 {
		case EXIF_ASCII:
			 if(*((char**)Exif_entry->value)!=0)
				{
					(*IFD_Entry_Size)+=12;
					Exif_entry->count=exif_Accumulate_ASCII(*((char**)Exif_entry->value),IFD_Value_Size);
					(*IFD_entry_count)++;
				} 
			break;
		case EXIF_SRATIONAL:
		case EXIF_RATIONAL:
			(*IFD_Entry_Size)+=12;
			//(*IFD_Value_Size)+=8;
			(*IFD_Value_Size)+=(8*Exif_entry->count);
			(*IFD_entry_count)++;
			break;
		case EXIF_SHORT:
			(*IFD_Entry_Size)+=12;
			if(Exif_entry->count>2)
			 (*IFD_Value_Size)+=(2*Exif_entry->count);
			(*IFD_entry_count)++;
			break;
		case EXIF_LONG:
			(*IFD_Entry_Size)+=12;
			if(Exif_entry->count>1)
			 (*IFD_Value_Size)+=(4*Exif_entry->count);
			(*IFD_entry_count)++;
			break;
		case EXIF_UNDEFINED:
			(*IFD_Entry_Size)+=12;
			if(Exif_entry->count>4)
			{
				(*IFD_Value_Size)+=Exif_entry->count;
				if(Exif_entry->count & 1 !=0)/*Force to half-word aligned*/
					(*IFD_Value_Size)++;
			}
			(*IFD_entry_count)++;
			break;		
		default:
			ASSERT(0);
			//return KAL_FALSE;
	 }
	return KAL_TRUE;
}

kal_uint16 exif_Accumulate_ASCII(char* str,kal_uint16* IFD_Value_Size)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -