EXIF format analysis and through XML processing (4)

zhaozj2021-02-08  213

EXIF format analysis and through XML processing

Raptor [Mental Studio] (Personal Column) (Blog)

Http://eental.mentsu.com

The following code snippet (Borland C Builder implements the conversion from EXIF ​​data to XML:

/ / -------------------------------------------------------------------------------------------- ---------------------------

#include

Typedef struct {

Word entrytag;

Word EntryType;

DWORD ENTRYSIZE;

DWORD ENTRYVALUE;

} Tifdiff;

#include

/ / -------------------------------------------------------------------------------------------- ---------------------------

BYTE * __FASTCALL TEXIFXML :: Getifd (_di_ixmlnode anode, byte * atifheader, int aposition, ANSISTRING Aname)

{

_DI_ixmlnode pifd = anode-> addchild ("ifd");

IF (aname! = "")

PIFD-> Attributes ["name"] = aname

BYTE * P = Atiffheader aposition;

Word nword;

Memcpy (& nWord, P, Sizeof (nword));

P = SizeOf (nWORD);

_DI_ixmlnode pchild = pifd-> addchild ("count");

PCHILD-> text = format ("0x% x", arrayofconst ((int) nword));

TifdenTry Ent;

_DI_IXMLNode Pentry;

BYTE * PTEMP;

For (int i = nword; i> 0; --I)

{

Memcpy (& Ent, P, SizeOf (ENT));

P = SizeOf (ent);

PENTRY = PIFD-> AddChild ("entry");

PCHILD = PENTRY-> AddChild ("tag");

PCHILD-> text = format ("0x% x", arrayofconst ((int) ent.entrytag)))))

PCHILD = PENTRY-> AddChild ("Type");

PCHILD-> text = INTOSTR (ent.EnTryType);

PCHILD = PENTRY-> AddChild ("size");

PCHILD-> text = format ("0x% x", arrayofconst ((int) ent.EntrySize)))

PCHILD = PENTRY-> AddChild ("Value");

Switch (ent.enTryType) {

Case 1: // Byte

IF (ent.EnTrySize == 1)

PCHILD-> text = format ("0x% .02x", arrayofconst ((int) ent.EntryValue)))))); ELSE

Throw Exception ("unsupported!");

Break;

Case 2: // ASCII

ENT.EnTrySize <= 4)

PCHILD-> text = reinterpret_cast (& ent.EntryValue);

Else

PCHILD-> text = reinterpret_cast (atiffheader ent.EnTryValue);

Break;

Case 3: // short

IF (ent.EnTrySize == 1)

PCHILD-> text = format ("0x% .04x", arrayofconst ((int) ent.EntryValue))));

Else

Throw Exception ("unsupported!");

Break;

Case 5: // ruleal

PCHILD-> text = floattostr (* reinterpret_cast (atiffheader ent.EnTryValue)

/ (* Reinterpret_cast (atiffheader ent.EntryValue sizeof (dword))))

Break;

Case 7: // undefined

ENT.EnTrySize <= 4)

PTEMP = Reinterpret_cast (& ent.EntryValue);

Else

PTEMP = AtiffHeader Ent.EntryValue;

PCHILD-> text = ""

For (int J = 0; j <(int) ent.EnTrySize; J)

{

PCHILD-> text = pchild-> text = PCHILD-> Text

Format ("0x% .02x", arrayofconst ((int)))))))));

PTEMP ;

IF (j% 16 == 15)

PCHILD-> text = pchild-> text "/ r / n";

}

Break;

Case 9: // slong

IF (ent.EnTrySize == 1)

PCHILD-> Text = INTOSTR (ENT.EnTryValue);

Else

Throw Exception ("unsupported!");

Break;

Case 10: // srtational

PCHild-> text = floattostr (* reinterpret_cast (atiffheader ent.EnTryValue)

/ (* Reinterpret_cast (atifheader ent.EntryValue sizeof (int)))))))));

Default: // long & other unknown type

PCHILD-> text = format ("0x% .08X", arrayofconst ((int) ent.EntryValue)))))

Break;

}

Switch (ent.entrytag) {

Case 0x8769: // EXIF ​​IFD

Getifd (Anode, Atiffheader, Ent.EnTryValue, "EXIF");

Break;

Case 0x8805: // GPS IFD

GetIfd (Anode, Atiffheader, Ent.EntryValue, "GPS");

Break;

Case 0xa005: // Interoperability IFD

Getifd (Anode, Atifheader, Ent.EnTryValue, "Interop");

Break;

}

}

Return P;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

Void __fastcall texifxml :: gettiffheader (_di_ixmlnode anode, byte * atifheader)

{

BYTE * P = atiffheader;

Char sbyteorder [3];

Memcpy (sbyteorder, p, 2);

P = 2;

Sbyteorder [2] = 0;

_DI_ixmlnode pchild = anode-> addchild ("byteorder");

PCHILD-> text = sbyteorder;

Word nflag;

Memcpy (& NFLAG, P, SIZEOF (NFLAG));

P = SizeOf (NFLAG);

PCHILD = anode-> addchild ("flag");

PCHILD-> text = format ("0x% .04x", arrayofconst ((int) nflag));

DWORD NPOINTER;

Memcpy (& NPointer, P, Sizeof (npoint));

INT i = 0;

While (npointer> 0)

{

P = Getifd (Anode, Atiffheader, Npoint, Ansistring ("IFD") INTOSTR (i ));

IF (! p)

Break;

Memcpy (& NPointer, P, Sizeof (npoint));

}

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

INT __FASTCALL TEXIFXML :: LoadFromstream (TSTREAM * ASTREAM)

{

IF (! fxmldoc)

Throw Exception ("XMLDoc Property Is Null!");

TMAUTO_PTR MS (New TMemoryStream ());

MS-> CopyFrom (Astream, ASTREAM-> SIZE);

MS-> Seek (0, SOFROMBEGINNING);

FXMLDOC-> filename = "";

FXMLDOC-> Active = True;

FXMLDOC-> Version = "1.0";

FXMLDOC-> Encoding = "GB2312";

_di_ixmlnode pnode = fxmldoc-> addchild ("eXifApp1");

_di_ixmlnode pchild = pnode-> addchild ("eXiFID");

Char sexifid [6];

MS-> Read (SexiFID, 6);

PCHILD-> Text = sexifid;

PCHILD = PNODE-> AddChild ("Tiffheader");

BYTE * PHEADER = static_cast (ms-> memory) (int) ms-> position;

GetTiffheader (PCHILD, PHEADER);

Return ms-> size;

}

Where fxmldoc is a TXMLDocument control for generating XML. The content read in the LoadFromstream method is the content of the JPEG App1 this Marker Segment (note, not a JPEG file). The GetTiffHeader method is used to read the contents of TiffHeader, including Image File Header and IFD Links. Getifd is used to interpret the specific content of the IFD, including recursive interpretation of the three expansion IFDs of Exif, and contains part of the various data types into a string, particularly for unmissible undefined types. (The result is shown in the XML after the conversion).

(to be continued)

转载请注明原文地址:https://www.9cbs.com/read-2680.html

New Post(0)