Вы можете встроить любые данные в блок данных EXIF в формате JPG. Я не знаю ограничения по размеру, вы просто разбиваете его на несколько блоков данных EXIF, если это необходимо.
Тебе даже не нужен libexif. Вы можете сделать все это вручную в коде C, программно выполнив следующее (обратите внимание, что это работает только с файлами JPG, в которых уже есть другие данные EXIF):
Обычно ваш файл JPG (если в нем уже есть заголовок EXIF) будет начинаться с чего-то вроде:
0xFF 0xD8
Тогда самый первый заголовок Exif будет начинаться с этого:
0xFF 0xE0
Далее следует длина блока данных Exif, которая здесь составляет два байта:
0x00 0x10 //In this case it is 16 bytes (0x0010) long and it INCLUDES these two bytes of the header
Далее следуют фактические данные блока данных Exif (ваши могут отличаться). Обратите внимание, что его длина составляет 14 байт (или 14 + 2 = 16 байт, или 0x0010, как показано выше):
0x4A 0x46 0x49 0x46 0x00 0x01 0x01 0x01 0x00 0x60 0x00 0x60 0x00 0x00
Теперь вы можете вставить свой блок данных XML Exif после этого заголовка, начиная с идентификатора данных exif (всегда одинакового):
0xFF 0xE1
Тогда размер вашего XML-файла в байтах + 2 (учтите, что если размер вашего файла больше 0xFFFE, вы должны разделить его на несколько блоков данных EXIF):
0x07 0x7D //In this case it is 1917bytes long or 0x077D
Затем вставьте xml прямо в JPG и оставьте остальной файл как есть.
См. Рисунок ниже для визуального объяснения (просто щелкните правой кнопкой мыши и просмотрите изображение, если вы не можете его прочитать):
Вот мой JPG с моим фиктивным XML-файлом. Щелкните правой кнопкой мыши, сохраните, откройте его в шестнадцатеричном редакторе и посмотрите сами:
Пример JPG с XML в блоке данных EXIF
В конце просто проверьте, что вы все еще можете открыть JPG, и если вы можете, то вам это удалось.
Вот краткий пример на C ++ (заметьте, я не отлаживал код, просто записал его из памяти, так что будьте осторожны!):
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;
Я использовал HxD, но вы можете использовать любой шестнадцатеричный редактор.