📄 exif.c
字号:
kal_uint16 EntryLength;
for(EntryLength=0;str[EntryLength]!='\0';EntryLength++);
if(++EntryLength>4)
(*IFD_Value_Size)+=EntryLength;
if(EntryLength & 1 !=0)/*Force to half-word aligned*/
(*IFD_Value_Size)++;
return EntryLength;
}
kal_uint32 eixf_burst_mode_fill_header(kal_uint8* Buffer)
{
kal_uint8* NewBuffer;
if(Buffer[0]==0xff && Buffer[1]==0xd8)
return 0;
NewBuffer=Buffer-exif_BufferSize-2;
IFD_TiffHeader_Offset=2+exif_header_size;
exif_ExIFD_Entry_Switch=0xffffffff;
cam_para_get=KAL_TRUE; //Re-Eanble
exif_Fillin_Header(NewBuffer,2);
NewBuffer[0]=0xff;
NewBuffer[1]=0xd8;
cam_para_get=KAL_FALSE; //Disable
return exif_BufferSize+2;
}
kal_bool exif_Fillin_Header(kal_uint8* Buffer,kal_uint32 BufferOffset)
{
kal_uint8 i;
kal_uint32 mask;
kal_uint16 j;
kal_uint16 IFD_entry_offset;
kal_uint16 IFD_value_offset;
exif_Buffer=Buffer;
exif_next_ExIFD_entry=0;
if(!cam_para_get && !cus_para_get)
return KAL_TRUE;
if(exif_IFD0_count==0 && exif_ExifIFD_count==0)
return KAL_TRUE;
//-- copy JPEG,EXIF header --
IFD_entry_offset=BufferOffset;
for(j=0;j<exif_header_size;j++)
Buffer[IFD_entry_offset++]=exif_Header[j];
//-- copy TiffHeader --
for(j=0;j<tiff_header_size;j++)
Buffer[IFD_entry_offset++]=exif_tiffHeader[j];
/************* Fillin IFD0 entries *************/
IFD_value_offset=IFD_entry_offset+IFD0_Entry_Size;
mask=1;
exif_Fillin_16(Buffer, &IFD_entry_offset, exif_IFD0_count);//Fill in number of IFD0 entries
for(i=0;i<EXIF_EXIF_IFD;i++)
{
if((exif_IFD0_Entry_Switch & mask)==0)// This entry is switched off
{
mask<<=1;
continue;
}
if(IFD0[i].type==EXIF_ASCII && *((kal_char**)IFD0[i].value)==0)
{
mask<<=1;
continue;
}
//-- check Extended tags --
while((j=exif_get_next_extended_tag(EXIF_IFD0,IFD0[i].tag))!=255)
{
exif_Fillin_tag(&ExIFD[j].entry,&IFD_entry_offset,&IFD_value_offset);
}
exif_Fillin_tag(&IFD0[i],&IFD_entry_offset,&IFD_value_offset);
mask<<=1;
}
//--Fillin ExifIFD entry of IFD0--
if(exif_ExifIFD_count>0 && exif_is_switched_on(EXIF_IFD0,EXIF_EXIF_IFD))
{
//-- check IFD0 Extended tags (before IFD0.ExifIFD tag)--
while((j=exif_get_next_extended_tag(EXIF_IFD0,IFD0[EXIF_EXIF_IFD].tag))!=255)
{
exif_Fillin_tag(&ExIFD[j].entry,&IFD_entry_offset,&IFD_value_offset);
}
exif_Fillin_tag(&IFD0[EXIF_EXIF_IFD],&IFD_entry_offset,&IFD_value_offset);
}
//-- check Rest IFD0 Extended tags --
while((j=exif_get_next_extended_tag(EXIF_IFD0,exif_tag_MAXIMUM))!=255)
{
exif_Fillin_tag(&ExIFD[j].entry,&IFD_entry_offset,&IFD_value_offset);
}
exif_Fillin_32(Buffer, &IFD_entry_offset,0);//no next IFD(IFD1)
/************* Fill in exif_IFD entries *************/
if((exif_IFD0_Entry_Switch & (1<<EXIF_EXIF_IFD))!=0)
{
IFD_entry_offset=IFD_value_offset;
IFD_value_offset=IFD_entry_offset+ExifIFD_Entry_Size;
mask=1;
exif_Fillin_16(Buffer, &IFD_entry_offset,exif_ExifIFD_count);//Fill in number of IFD0 entries
for(i=0;i<ExifIFD_Number_of_Entry;i++)
{
if((exif_ExifIFD_Entry_Switch & mask)==0)// This entry is switched off
{
mask<<=1;
continue;
}
if(ExifIFD[i].type==EXIF_ASCII && *((kal_char**)ExifIFD[i].value)==0)
{
mask<<=1;
continue;
}
while((j=exif_get_next_extended_tag(EXIF_EXIFIFD,ExifIFD[i].tag))!=255)
{
exif_Fillin_tag(&ExIFD[j].entry,&IFD_entry_offset,&IFD_value_offset);
}
exif_Fillin_tag(&ExifIFD[i],&IFD_entry_offset,&IFD_value_offset);
mask<<=1;
}
//-- check Rest ExifIFD Extended tags --
while((j=exif_get_next_extended_tag(EXIF_EXIFIFD,exif_tag_MAXIMUM))!=255)
{
exif_Fillin_tag(&ExIFD[j].entry,&IFD_entry_offset,&IFD_value_offset);
}
exif_Fillin_32(Buffer, &IFD_entry_offset,0);//no next IFD(IFD1)
}
cam_para_get=KAL_FALSE;
//cus_para_get=KAL_FALSE;
//exif_switch_cam_entry(EXIF_SWITCH_OFF);
//exif_switch_IFD_entry(EXIF_EXIFIFD,EXIF_MAKER_NOTE,EXIF_SWITCH_OFF);
return KAL_TRUE;
}
void exif_Fillin_tag(exif_entry_struct* Exif_entry,kal_uint16* IFD_entry_offset,kal_uint16* IFD_value_offset)
{
kal_uint32 ValueOffset;
kal_uint16 j;
ASSERT(Exif_entry->count>0);
exif_Fillin_16(exif_Buffer, IFD_entry_offset, Exif_entry->tag);
exif_Fillin_16(exif_Buffer, IFD_entry_offset, Exif_entry->type);
exif_Fillin_32(exif_Buffer, IFD_entry_offset, Exif_entry->count);
switch(Exif_entry->type)
{
case EXIF_UNDEFINED:
//printf("FillinTag EXIF_UNDEFINED\n");
if(Exif_entry->count>4)
{
ValueOffset=*IFD_value_offset-IFD_TiffHeader_Offset;
exif_Fillin_32(exif_Buffer, IFD_entry_offset, ValueOffset);
exif_Fillin_ASCII(exif_Buffer,IFD_value_offset,(exif_UNDEFINED*)Exif_entry->value,Exif_entry->count);
}
else
{
for(j=0;j<Exif_entry->count;j++)
{
exif_Buffer[(*IFD_entry_offset)++]=((exif_UNDEFINED*)Exif_entry->value)[j];
}
for(j=Exif_entry->count;j<4;j++)
exif_Buffer[(*IFD_entry_offset)++]=0x00;
}
break;
case EXIF_ASCII:
//printf("FillinTag EXIF_ASCII\n");
if(Exif_entry->count>4)
{
ValueOffset=*IFD_value_offset-IFD_TiffHeader_Offset;
exif_Fillin_32(exif_Buffer, IFD_entry_offset, ValueOffset);
exif_Fillin_ASCII(exif_Buffer,IFD_value_offset,*((kal_char**)Exif_entry->value),Exif_entry->count);
}
else
{
for(j=0;j<Exif_entry->count;j++)
{
exif_Buffer[(*IFD_entry_offset)++]=(*((kal_char**)Exif_entry->value))[j];
}
for(j=Exif_entry->count;j<4;j++)
exif_Buffer[(*IFD_entry_offset)++]=0x00;
}
break;
case EXIF_LONG:
//printf("FillinTag EXIF_LONG\n");
if(Exif_entry->count==1)
exif_Fillin_32(exif_Buffer, IFD_entry_offset,((exif_LONG*)Exif_entry->value)[0]);
else
{
ValueOffset=*IFD_value_offset-IFD_TiffHeader_Offset;
exif_Fillin_32(exif_Buffer, IFD_entry_offset, ValueOffset);
for(j=0;j<Exif_entry->count;j++)
exif_Fillin_32(exif_Buffer, IFD_value_offset,((exif_LONG*)Exif_entry->value)[j]);
}
break;
case EXIF_SRATIONAL:
case EXIF_RATIONAL:
//printf("FillinTag EXIF_RATIONAL\n");
ValueOffset=*IFD_value_offset-IFD_TiffHeader_Offset;
exif_Fillin_32(exif_Buffer, IFD_entry_offset, ValueOffset);
for(j=0;j<Exif_entry->count;j++)
{
exif_Fillin_32(exif_Buffer, IFD_value_offset, ((exif_RATIONAL*)Exif_entry->value)[j][0]);
exif_Fillin_32(exif_Buffer, IFD_value_offset, ((exif_RATIONAL*)Exif_entry->value)[j][1]);
}
break;
case EXIF_SHORT:
//printf("FillinTag EXIF_SHORT, count:%d\n",Exif_entry->count);
if(Exif_entry->count==1)
{
exif_Fillin_16(exif_Buffer, IFD_entry_offset,((exif_SHORT*)Exif_entry->value)[0]);
exif_Fillin_16(exif_Buffer, IFD_entry_offset,0);
}
else if(Exif_entry->count==2)
{
exif_Fillin_16(exif_Buffer, IFD_entry_offset,((exif_SHORT*)Exif_entry->value)[0]);
exif_Fillin_16(exif_Buffer, IFD_entry_offset,((exif_SHORT*)Exif_entry->value)[1]);
}
else if(Exif_entry->count>2)
{
ValueOffset=*IFD_value_offset-IFD_TiffHeader_Offset;
exif_Fillin_32(exif_Buffer, IFD_entry_offset, ValueOffset);
for(j=0;j<Exif_entry->count;j++)
exif_Fillin_16(exif_Buffer, IFD_value_offset,((exif_SHORT*)Exif_entry->value)[j]);
}
break;
default :
ASSERT(0);
}
}
void exif_check_ExIFD_data(void)
{
kal_uint8 i,j;
kal_bool IFD_switched=KAL_FALSE;
if(ExIFD_Number_of_Entry==0) return;
if(ExIFD_Number_of_Entry>EXIF_MAXIMUM_NUMBER_OF_EXIFD_ENTRIES)
ASSERT(0);
for(i=0;i<ExIFD_Number_of_Entry;i++)
{
ASSERT(/*ExIFD[i].exif_IFD_type>=EXIF_IFD0 && */ExIFD[i].exif_IFD_type<=EXIF_EXIFIFD);
//--Checking double definition--
for(j=0;j<IFD0_Number_of_Entry;j++)
{
ASSERT(ExIFD[i].entry.tag!=IFD0[j].tag);
if(IFD0[j].tag>ExIFD[i].entry.tag) break;
}
for(j=0;j<ExifIFD_Number_of_Entry;j++)
{
ASSERT(ExIFD[i].entry.tag!=ExifIFD[j].tag);
if(ExifIFD[j].tag>ExIFD[i].entry.tag) break;
}
}
//--Checking ordering--
exif_AscOrder=KAL_TRUE;
for(i=1;i<ExIFD_Number_of_Entry;i++)
{
if(!IFD_switched && ExIFD[i].exif_IFD_type != ExIFD[i-1].exif_IFD_type)
{
IFD_switched=KAL_TRUE;
continue;
}
if(IFD_switched && ExIFD[i].exif_IFD_type != EXIF_EXIFIFD)
{
exif_AscOrder=KAL_FALSE;
break;
}
if(ExIFD[i].entry.tag<ExIFD[i-1].entry.tag)
{
exif_AscOrder=KAL_FALSE;
break;
}
}
exif_ExIFD_Entry_Switch=0xffffffff;
}
kal_uint8 exif_get_next_extended_tag(kal_uint8 IFD,kal_uint16 MinTag)
{
kal_uint8 j,index=255;
if(!exif_AscOrder)
{
for(j=0;j<ExIFD_Number_of_Entry;j++)
{
if( exif_is_switched_on(EXIF_EXIFD,j) &&
ExIFD[j].exif_IFD_type==IFD &&
ExIFD[j].entry.tag<MinTag)
{
index=j;
MinTag=ExIFD[j].entry.tag;
}
}
}
else
{
if(exif_next_ExIFD_entry<ExIFD_Number_of_Entry &&
exif_is_switched_on(EXIF_EXIFD,exif_next_ExIFD_entry) &&
ExIFD[exif_next_ExIFD_entry].exif_IFD_type==IFD &&
ExIFD[exif_next_ExIFD_entry].entry.tag<MinTag)
{
//printf("ExIFD:%x MinTag:%x\n",ExIFD[exif_next_ExIFD_entry].entry.tag,MinTag);
index=exif_next_ExIFD_entry++;
}
}
/* switch off the selected tag */
if(index<EXIF_MAXIMUM_NUMBER_OF_EXIFD_ENTRIES)
{
exif_switch_IFD_entry(EXIF_EXIFD,index,EXIF_SWITCH_OFF);
}
else if(index>=EXIF_MAXIMUM_NUMBER_OF_EXIFD_ENTRIES && index !=255)
ASSERT(0);
//printf("count:%d index:%d\n",count,index);
return index;
}
void exif_Fillin_16(kal_uint8* Buffer, kal_uint16* Offset, kal_uint16 Value)
{
Buffer[(*Offset)++]=Value & 0xff;
Buffer[(*Offset)++]=Value>>8 & 0xff;
}
void exif_Fillin_32(kal_uint8* Buffer, kal_uint16* Offset, kal_uint32 Value)
{
Buffer[(*Offset)++]=Value & 0xff;
Buffer[(*Offset)++]=Value>>8 & 0xff;
Buffer[(*Offset)++]=Value>>16 & 0xff;
Buffer[(*Offset)++]=Value>>24 & 0xff;
}
void exif_Fillin_ASCII(kal_uint8* Buffer, kal_uint16* Offset, kal_char* Value,kal_uint32 count)
{
kal_uint32 j;
ASSERT(count>0);
for(j=0;j<count;j++)
Buffer[(*Offset)++]=Value[j];
if(count & 1 !=0)/*Force to half-word aligned*/
Buffer[(*Offset)++]=0x00;
}
void exif_switch_cam_entry(kal_uint8 action)
{
kal_uint8 i;
for(i=EXIF_ORIENTATION;i<=EXIF_YCBCR_POSITIONING;i++)
exif_switch_IFD_entry(EXIF_IFD0,i,action);
for(i=EXIF_EXPOSURE_TIME;i<EXIF_MAKER_NOTE;i++)
exif_switch_IFD_entry(EXIF_EXIFIFD,i,action);
for(i=EXIF_FLASHPIX_VERSION;i<=EXIF_SCENE_CAPTURE_TYPE;i++)
exif_switch_IFD_entry(EXIF_EXIFIFD,i,action);
}
/* Switch On/Off IFD entries*/
void exif_switch_IFD_entry(kal_uint8 IFD,kal_uint8 Entry,kal_uint8 action)
{
kal_uint32* IFD_switch;
kal_uint32 mask;
mask=1 << Entry;
switch(IFD)
{
case EXIF_IFD0:
IFD_switch=&exif_IFD0_Entry_Switch;
break;
case EXIF_EXIFIFD:
IFD_switch=&exif_ExifIFD_Entry_Switch;
break;
case EXIF_EXIFD:
IFD_switch=&exif_ExIFD_Entry_Switch;
break;
default:
ASSERT(0);
return;
}
switch(action)
{
case EXIF_SWITCH_ON:
*IFD_switch |=mask;
break;
case EXIF_SWITCH_OFF:
*IFD_switch &=~mask;
break;
default:
ASSERT(0);
return;
}
}
kal_bool exif_is_switched_on(kal_uint8 IFD,kal_uint8 Entry)
{
kal_uint32 mask=1<<Entry;
switch(IFD)
{
case EXIF_IFD0:
return (exif_IFD0_Entry_Switch & mask)>>Entry;
case EXIF_EXIFIFD:
return (exif_ExifIFD_Entry_Switch & mask)>>Entry;
case EXIF_EXIFD:
return (exif_ExIFD_Entry_Switch & mask)>>Entry;
default:
ASSERT(0);
}
return KAL_FALSE;
}
/********************* Below this line, It's Exif Parser *********************/
STFSAL exif_FSAL;
kal_uint8 exif_parser_buffer[EXIF_PARSER_BUFFER_SIZE];
kal_uint8 exif_decoder_state=EXIF_DECODER_IDLE_STATE;
//--Exif para--
kal_uint16 exif_ByteOrder;
kal_uint32 exif_app1_boundary;
kal_uint32 exif_TiffOffset;
kal_uint32 exif_ReqBufferSize;
kal_uint32 exif_UsedBufferSize;
kal_uint32 exif_FileSize;
kal_char** exif_valueArr;
kal_uint16* exif_tagArr;
//--IFD0 para--
kal_uint32 IFD0_entry_pos;
kal_uint16 IFD0_entry_num;
//--ExifIFD para--
kal_uint32 ExifIFD_entry_pos;
kal_uint16 ExifIFD_entry_num;
kal_uint32 exif_MakerNote_pos;
kal_uint32 exif_MakerNote_size;
kal_bool exif_getNextMarker(kal_uint16* marker);
void exif_decoder_acc_tag(kal_uint16 tag,kal_uint16 type);
FSAL_Status exif_read_uint8(kal_uint8* byte);
FSAL_Status exif_read_uint16(kal_uint16 *pwValue);
FSAL_Status exif_read_uint32(kal_uint32 *puValue);
FSAL_Status exif_direct_read_uint16(kal_uint16 *pwValue);
FSAL_Status exif_direct_read_uint32(kal_uint32 *puValue);
FSAL_Status exif_seek_buffer(kal_uint32 offset, kal_uint8 ref);
kal_uint32 exif_set_entry(kal_char** str,kal_char* buffer,exif_dec_entry_struct* Exif_entry);
kal_uint32 Long_stringSize(kal_uint32 x);
kal_uint32 SLong_stringSize(kal_int32 x);
kal_uint32 Float_stringSize(float fp);
kal_uint8* Byte2Hex(kal_uint8 x);
/*************************************************************************
* FUNCTION
* exif_open_jpeg_file()
*
* DESCRIPTION
* This function is to open a jpeg file for parsing the exif header
*
* PARAMETERS
* void* file_name_p
*
* RETURNS
* The size of buffer required to store the parsing result. If 0 is
* returned, it means finding no exif header or somthing error
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_uint32 exif_open_jpeg_file(void* file_name_p)
{
FSAL_Status eFSALRet;
kal_uint16 marker,JumpDest,halfword,tag,type;
kal_uint8 byte0,i,byte[2];
kal_bool Exif_Found=KAL_FALSE;
if(exif_decoder_state!=EXIF_DECODER_IDLE_STATE)
exif_close_jpeg_file();
eFSALRet = FSAL_Open(&exif_FSAL,file_name_p, FSAL_READ);
if(eFSALRet !=FSAL_OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -