English 中文(简体)
libexif example to add a small Xml document in the exif data
原标题:

Any libexif user/developer that could point me in the right direction on what are the appropriate call for adding a small custom XML document in the exif meta data of a JPG image ?

I have been googling around for a while and can t figure it out.

I am open to any other opensource library that will let me do that as long as it is C based.

问题回答

You can embed any data into an EXIF data block in a JPG. There is no size limit that I am aware of, you just split it into mutliple EXIF data blocks if required.

You don t even need libexif. You can do it all manually in C code by programmatically doing the following (note that this only works with JPG files that already have other EXIF data in it):

Basically your JPG file (if it already has an EXIF header in it) will start with something like:

0xFF 0xD8 

Then the very first Exif header will start with this:

0xFF 0xE0 

The next comes the length of the Exif data block which is two bytes here:

0x00 0x10 //In this case it is 16 bytes (0x0010) long and it INCLUDES these two bytes of the header

Next comes the Exif data block s actual data (yours may be different). Note that it is 14 bytes long (or 14+2 = 16bytes, or 0x0010 as shown above):

0x4A 0x46 0x49 0x46 0x00 0x01 0x01 0x01 0x00 0x60 0x00 0x60 0x00 0x00 

Now you can insert your XML Exif data block after this header starting with an exif data identifier (always the same):

0xFF 0xE1

Then the size of your XML file in bytes + 2 (note that if your file is larger than 0xFFFE in size then you must split it up into multiple EXIF data blocks):

0x07 0x7D //In this case it is 1917bytes long or 0x077D

Then insert your xml directly into the JPG at this point and leave the rest of the file as is.

See the picture below for a visual explanation (just right click and view image if you can t read it):

Example of XML file inserted into EXIF data of JPG

Here is my JPG with my dummy XML file in it. Right click, save, open it in a Hex editor and look for yourself:

Sample JPG with XML in EXIF data block

At the end just check you can still open the JPG and if you can you ve succeeded.

Here is a quick example in C++ (note I haven t debugged the code, just wrote it from memory so be warned!):

char yourdata[]="<xml> contents to </add>";
long yourdatalen = 0x18;

//open file
char * file;
long filelen=0;
std::ifstream infile;
infile.open("yourjpg.jpg",std::ios::binary| std::ios::in);

//find size of file
infile.seekg (0, ios::end);
filelen = infile.tellg();
infile.seekg (0, ios::beg);

//read contents of file
file = new char [filelen];
infile.read(file,filelen);
infile.close();

//lets parse through the file and find any exif headers
long x=0;
if ((file[0]==0xFF) && (file[1]==0xD8)){

    //all good lets go!!
    while ((file[x]!=0xFF) && (file[x+1]!=0xE1)) {
       x++;
    }

    //were at the first EXIF data block! insert XML here
    char * temp=file;
    file = new char [filelen+yourdatalen+4];
    memcpy(file,temp,x);
    file[x+0]=0xFF;
    file[x+1]=0xE1;
    file[x+2]=int((yourdatalen+2)/0xFF); //note assumes that your xml file is less than 0xFFFE bytes long
    file[x+3]=yourdatalen-int((yourdatalen+2)/0xFF);
    memcpy(&file[x+4],yourdata,yourdatalen);
    memcpy(&file[x+4+yourdatalen],temp[x],filelen-x);
    delete [] temp;

    //Save to file
    std::ofstream ofile;
    ofile.open("savejpg.jpg",std::ios::binary| std::ios::out);
    ofile.write(file,yourdatalen+4+filelen);
    ofile.close();
}
else {
    //JPG file does not have exif data in it, you ll need to add it first or find another way of adding your data
}

//Clean up
delete [] file;

I used HxD but you can use any hex editor.

I believe that the maximum EXIF field size is 32KB, so this should be more than enough for doing an XML file.

Generate an ASCII C-string representation of your XML tree, using libxml2 perhaps. Then set the EXIF "User Comment" tag to that string.

The following example sets this tag: http://libexif.cvs.sourceforge.net/viewvc/libexif/libexif/contrib/examples/write-exif.c?view=markup

I think that you need to use that ASCII_COMMENT prefix, and FILE_COMMENT would be your XML string.





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签