📄 exif.c
字号:
/* Tag 3 */
ExifMakeTag(exif, EXIF_COLOR_SPACE_TAG, EXIF_SHORT, 1, prmExif->ColorSpace << 16);
/* Tag 4 */
ExifMakeTag(exif, EXIF_PIX_X_DIM_TAG, EXIF_SHORT, 1, prmExif->PixXDim << 16);
/* Tag 5 */
ExifMakeTag(exif, EXIF_PIX_Y_DIM_TAG, EXIF_SHORT, 1, prmExif->PixYDim << 16);
/* put next IFD offset */
put_word32(exif, 0);
/* calculate offset into exif header */
exif->ix = data.ix + TIFF_HEADER_OFFSET;
return E_PASS;
}
/*-----------------------------------------------------------------------------\
@RoutineName :: EXIFMakeTag
@Description ::
Creates the EXIF tag
@Parameters ::
WordStream *exif :: The EXIF Header data stream
Uint16 tag :: The tag to create
EXIF_TYPE type :: The data format type
Uint32 count :: The component count
Uint32 offset :: The offset to tag data
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS ExifMakeTag(WordStream *exif, Uint16 tag, EXIF_TYPE type, Uint32 count, Uint32 offset) {
put_word16(exif, tag);
put_word16(exif, type);
put_word32(exif, count);
put_word32(exif, offset);
return E_PASS;
}
/*-----------------------------------------------------------------------------\
@RoutineName :: EXIFMakeIFD1
@Description ::
Creates the EXIF IFD1 based on the EXIF configuration structure
This is for THUMBNAIL
@Parameters ::
EXIFParams *prmExif :: The EXIF Configuration structure
WordStream *exif :: The EXIF Header data stream
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS EXIFMakeIFD1(EXIFParams *prmExif, WordStream *exif ) {
Uint16 tag_count;
WordStream data;
tag_count = 9;
put_word16(exif, tag_count );
/* point 'data' to IFD1 Value Area */
data.addr = exif->addr + TIFF_HEADER_OFFSET; /* Points to TIFF header */
data.ix =
exif->ix /* offset into data stream */
+ tag_count*12 /* tag array size */
- TIFF_HEADER_OFFSET /* offset of TIFF header from APP1 marker */
+ 4 /* skip over next IFD offset field */
;
/* Tag 1 */
ExifMakeTag(exif, EXIF_COMPRESSION_TAG, EXIF_SHORT, 1,prmExif->compression<<16);
/* Tag 2 */
ExifMakeTag(exif, EXIF_MAKE_TAG, EXIF_ASCII, strlen((char*)prmExif->make)+1, data.ix);
put_str(&data, prmExif->make);
/* Tag 3 */
ExifMakeTag(exif, EXIF_MODEL_TAG, EXIF_ASCII, strlen((char*)prmExif->model)+1, data.ix);
put_str(&data, prmExif->model);
/* Tag 4 */
ExifMakeTag(exif, EXIF_XRES_TAG, EXIF_RATIONAL, 1, data.ix);
put_word32(&data, prmExif->XRes);
put_word32(&data, 1);
/* Tag 5 */
ExifMakeTag(exif, EXIF_YRES_TAG, EXIF_RATIONAL, 1, data.ix);
put_word32(&data, prmExif->YRes);
put_word32(&data, 1);
/* Tag 6 */
ExifMakeTag(exif, EXIF_RES_UNIT_TAG, EXIF_SHORT, 1, prmExif->ResUnit << 16);
/* Tag 7 */ //added by Manoj
/* This last field in this tag will be updated later */
prmExif->thumbDataOffsetField=exif->ix+8;
ExifMakeTag(exif, EXIF_JPEGINTER_FORMAT_TAG, EXIF_LONG, 1,0 );
/* Tag 8 */
ExifMakeTag(exif, EXIF_JPEGINTER_FORMAT_LENGTH_TAG, EXIF_LONG, 1, prmExif->thumbSize);
/* Tag 9 */
ExifMakeTag(exif, EXIF_YCBCR_POSITION_TAG, EXIF_SHORT, 1, prmExif->YCbCrPosition << 16);
/* put next IFD offset */
put_word32(exif, 0);
/* calculate offset into exif header */
exif->ix = data.ix + TIFF_HEADER_OFFSET;
return E_PASS;
}
/*-----------------------------------------------------------------------------\
@RoutineName :: EXIFParseHeader
@Description ::
Parse the EXIF Header and extract the tag value into the EXIF configuration structure
@Parameters ::
EXIFParams *prmExif :: The EXIF Configuration structure
Uint8 *exifHeader :: The Address where the Header is stored
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS EXIFParseHeader( EXIFParams *prmExif, Uint8 *exifHeader) {
Uint8 *cur = exifHeader;
Uint32 ifd0_Offset;
memset(prmExif, 0, sizeof(*prmExif)); /* clear params struct */
if( get_word16(cur) != EXIF_APP1_TAG ) /* check for APP1 marker */
return E_DEVICE;
cur += 4; /* skip over APP1 marker and marker length */
if( get_word32(cur) != MAKE_TAG('E','x','i','f') ) /* check if EXIF marker */
return E_DEVICE;
cur += 6; /* skip over 'Exif' and 0x0000 */
if( get_word16(cur) == ( ('M' << 8) + 'M' ) ) /* check Endianess */
prmExif->bswap = TRUE; /* big endian */
else
prmExif->bswap = FALSE; /* little endian */
cur += 2; /* skip Endianess */
if(prmExif->bswap) {
if( get_word16(cur) != 0x002A ) /* check TIFF Tag */
return E_DEVICE;
}
else {
if( byte_swap16(get_word16(cur)) != 0x002A ) /* check TIFF Tag */
return E_DEVICE;
}
cur += 2; /* skip TIFF Tag */
if(prmExif->bswap)
ifd0_Offset = get_word32( cur );
else
ifd0_Offset = byte_swap32( get_word32( cur ) );
if( EXIFParseIFD(prmExif, exifHeader + TIFF_HEADER_OFFSET, exifHeader + TIFF_HEADER_OFFSET + ifd0_Offset , IFD_0 ) != E_PASS )
return E_DEVICE;
return E_PASS;
}
/*-----------------------------------------------------------------------------\
@RoutineName :: EXIFParseIFD
@Description ::
Parse a EXIF IFD
@Parameters ::
EXIFParams *prmExif :: The EXIF Configuration structure
Uint8 *tiff :: The pointer to tiff header
Uint8 *ifd :: The pointer to the IFD
IFD_TYPE ifdType :: The IFD type
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS EXIFParseIFD( EXIFParams *prmExif, Uint8 *tiff, Uint8 *ifd, IFD_TYPE ifdType) {
Uint16 count, i;
EXIF_TAG tag;
Uint32 nextIfd;
if( prmExif->bswap)
count = get_word16(ifd);
else
count = byte_swap16(get_word16(ifd));
ifd += 2;
for( i=0; i<count; i++) {
if( prmExif->bswap) {
tag.tag = get_word16( ifd );
tag.type = get_word16( ifd + 2);
tag.count = get_word32( ifd + 4);
tag.offset = get_word32( ifd + 8);
} else {
tag.tag = byte_swap16(get_word16( ifd ) );
tag.type = byte_swap16(get_word16( ifd + 2));
tag.count = byte_swap32(get_word32( ifd + 4));
tag.offset = byte_swap32(get_word32( ifd + 8));
}
switch( ifdType ) {
case IFD_0 :
EXIFParseIFD0Tag(prmExif, tiff, &tag);
break;
case IFD_1 :
EXIFParseIFD1Tag(prmExif, tiff, &tag);
break;
case IFD_EXIF :
EXIFParseIFDExifTag(prmExif, tiff, &tag);
break;
default :
break;
}
ifd+=12;
}
if( prmExif->bswap)
nextIfd = get_word32(ifd);
else
nextIfd = byte_swap32(get_word32(ifd));
if( nextIfd != 0 ) {
if( ifdType == IFD_0)
prmExif->thumbPresent=TRUE;
EXIFParseIFD( prmExif, tiff, tiff + nextIfd , IFD_1 );
}
return E_PASS;
}
/*-----------------------------------------------------------------------------\
@RoutineName :: EXIFParseIFD0Tag
@Description ::
Parse EXIF IFD0 Tag's
@Parameters ::
EXIFParams *prmExif :: The EXIF Configuration structure
Uint8 *tiff :: Pointer to tiff header
EXIF_TAG :: Pointer to EXIF tag
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS EXIFParseIFD0Tag(EXIFParams *prmExif, Uint8 *tiff, EXIF_TAG *tag) {
Uint32 nBytes;
Uint32 Nr, Dr;
nBytes = tag->count * EXIFTypeSize[tag->type];
/*
printf("\n bytes : %3ld", nBytes);
printf(" :: tag : %x", tag->tag);
*/
switch(tag->tag) {
case EXIF_MAKE_TAG :
prmExif->make = (Uint8*)malloc( nBytes );
if( nBytes > 4 )
strcpy((char*)prmExif->make, (char*)tiff + tag->offset );
else
strcpy((char*)prmExif->make, (char *)&tag->offset);
break;
case EXIF_MODEL_TAG :
prmExif->model = (Uint8*)malloc( nBytes );
if( nBytes > 4 )
strcpy((char*)prmExif->model, (char*)tiff + tag->offset );
else
strcpy((char*)prmExif->model, (char *)&tag->offset);
break;
case EXIF_SOFTWARE_TAG :
prmExif->software = (Uint8*)malloc( nBytes );
if( nBytes > 4 )
strcpy((char*)prmExif->software , (char*)tiff + tag->offset );
else
strcpy((char*)prmExif->software , (char *)&tag->offset);
break;
case EXIF_COPYRIGHT_TAG :
prmExif->copyright = (Uint8*)malloc( nBytes );
if( nBytes > 4 )
strcpy((char*)prmExif->copyright, (char*)tiff + tag->offset );
else
strcpy((char*)prmExif->copyright, (char *)&tag->offset);
break;
case EXIF_XRES_TAG :
if( prmExif->bswap)
Nr = get_word32((tiff + tag->offset) );
else
Nr = byte_swap32( get_word32(tiff + tag->offset) );
if( prmExif->bswap)
Dr = get_word32((tiff + tag->offset + 4 ) );
else
Dr = byte_swap32( get_word32(tiff + tag->offset + 4 ) );
if( Dr != 0 )
prmExif->XRes = Nr / Dr;
break;
case EXIF_YRES_TAG :
if( prmExif->bswap)
Nr = get_word32((tiff + tag->offset) );
else
Nr = byte_swap32( get_word32(tiff + tag->offset) );
if( prmExif->bswap)
Dr = get_word32((tiff + tag->offset + 4 ) );
else
Dr = byte_swap32( get_word32( tiff + tag->offset + 4 ) );
if( Dr != 0 )
prmExif->YRes = Nr / Dr;
break;
case EXIF_RES_UNIT_TAG :
if( prmExif->bswap )
prmExif->ResUnit = tag->offset >> 16;
else
prmExif->ResUnit = tag->offset ;
break;
case EXIF_YCBCR_POSITION_TAG :
if( prmExif->bswap )
prmExif->YCbCrPosition = tag->offset >> 16;
else
prmExif->YCbCrPosition = tag->offset ;
break;
case EXIF_EXIF_IFD_PTR_TAG :
EXIFParseIFD(prmExif, tiff, tiff + tag->offset , IFD_EXIF );
break;
}
return E_PASS;
}
/*-----------------------------------------------------------------------------\
@RoutineName :: EXIFParseIFD1Tag
@Description ::
Parse EXIF IFD1 Tag's
@Parameters ::
EXIFParams *prmExif :: The EXIF Configuration structure
Uint8 *tiff :: Pointer to tiff header
EXIF_TAG :: Pointer to EXIF tag
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS EXIFParseIFD1Tag(EXIFParams *prmExif, Uint8 *tiff, EXIF_TAG *tag) {
switch(tag->tag) {
case EXIF_JPEGINTER_FORMAT_TAG :
prmExif->thumbDataOffset = tag->offset ;
break;
case EXIF_JPEGINTER_FORMAT_LENGTH_TAG :
prmExif->thumbSize = tag->offset ;
break;
default :
break;
}
return 1;
}
/*-----------------------------------------------------------------------------\
@RoutineName :: EXIFParseIFDExifTag
@Description ::
Parse EXIF sub-IFD0 ( EXIF specific IFD ) Tag's
@Parameters ::
EXIFParams *prmExif :: The EXIF Configuration structure
Uint8 *tiff :: Pointer to tiff header
EXIF_TAG :: Pointer to EXIF tag
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS EXIFParseIFDExifTag(EXIFParams *prmExif, Uint8 *tiff, EXIF_TAG *tag) {
/*
{
Uint32 nBytes;
nBytes = tag->count * EXIFTypeSize[tag->type];
printf("\n bytes : %3ld", nBytes);
printf(" :: tag : %x", tag->tag);
}
*/
switch(tag->tag) {
case EXIF_EXIF_VERSION_TAG :
if( prmExif->bswap )
prmExif->EXIFVersion = tag->offset;
else
prmExif->EXIFVersion = byte_swap32( tag->offset ); /* because this value is in a big endian format */
break;
case EXIF_COMP_CONF_TAG :
if( prmExif->bswap )
prmExif->CompConf = tag->offset;
else
prmExif->CompConf = byte_swap32( tag->offset ); /* because this value is in a big endian format */
break;
case EXIF_COLOR_SPACE_TAG :
if( prmExif->bswap )
prmExif->ColorSpace = tag->offset >> 16 ;
else
prmExif->ColorSpace = tag->offset ;
break;
case EXIF_PIX_X_DIM_TAG :
if( prmExif->bswap )
prmExif->PixXDim = tag->offset >> 16 ;
else
prmExif->PixXDim = tag->offset ;
break;
case EXIF_PIX_Y_DIM_TAG :
if( prmExif->bswap )
prmExif->PixYDim = tag->offset >> 16 ;
else
prmExif->PixYDim = tag->offset ;
break;
}
return E_PASS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -