Ovdje je jednostavni kod sa kojim sam čitao IFD0 tag-ove, te slika koju sam čitao (koja je konvertovana iz NEF u DNG pomoću Adobe DNG Converter software-a)
Slika
Code:
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
// Ovo koristim zbog little endian-a
double long BytesToInteger(unsigned char *data, int length) {
double long result(0);
for (int i=0; i<length; i++) result += data[i] * (double long)(pow(256., i));
return result;
}
int main() {
unsigned char header[8], countDirectoryEntries[2], tagIdentifier[2], fieldType[2], countData[4], offsetData[4], offsetIFD[4];
int adressNewIFD;
ifstream input("C:\\DSC_5857.dng", ios::in | ios::binary);
input.read((char*)header, sizeof header);
input.read((char*)countDirectoryEntries, sizeof countDirectoryEntries);
cout << "Directory entries of IFD0: " << BytesToInteger(countDirectoryEntries, 2) << endl << endl;
for (int i=0; i<BytesToInteger(countDirectoryEntries, 2); i++) {
input.read((char*)tagIdentifier, sizeof tagIdentifier);
input.read((char*)fieldType, sizeof fieldType);
input.read((char*)countData, sizeof countData);
input.read((char*)offsetData, sizeof offsetData);
// 254 == NewSubFileType tag, 330 == SubIFDs tag
if ((BytesToInteger(tagIdentifier, 2) == 330) || (BytesToInteger(tagIdentifier, 2) == 254)) {
// za NewSubFileType tag, offset je 1 (u ovom slucaju to je i podatak, jer staje u 4 bajta), pa vidimo da je IFD0 thumbnail
// za SubIFDs tag, offset je 714, odem na tu adresu (recimo u binary readeru ili kroz ovaj program) i dobijem besmislene vrijednosti
cout << "Tag identifier: " << BytesToInteger(tagIdentifier, 2) << endl;
cout << "Field type: " << BytesToInteger(fieldType, 2) << endl;
cout << "Count data: " << BytesToInteger(countData, 4) << endl;
cout << "Offset data: " << BytesToInteger(offsetData, 4) << endl << endl;
adressNewIFD = BytesToInteger(offsetData, 4);
}
}
input.seekg(adressNewIFD); // adresa novog IFD-a
input.read((char*)countDirectoryEntries, sizeof countDirectoryEntries);
cout << "Directory entries of new IFD: " << BytesToInteger(countDirectoryEntries, 2) << endl << endl;
// prvi tag, dobiju se besmislene vrijednosti
input.read((char*)tagIdentifier, sizeof tagIdentifier);
input.read((char*)fieldType, sizeof fieldType);
input.read((char*)countData, sizeof countData);
input.read((char*)offsetData, sizeof offsetData);
cout << "Tag identifier: " << BytesToInteger(tagIdentifier, 2) << endl;
cout << "Field type: " << BytesToInteger(fieldType, 2) << endl;
cout << "Count data: " << BytesToInteger(countData, 4) << endl;
cout << "Offset data: " << BytesToInteger(offsetData, 4) << endl << endl;
return 0;
}
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
// Ovo koristim zbog little endian-a
double long BytesToInteger(unsigned char *data, int length) {
double long result(0);
for (int i=0; i<length; i++) result += data[i] * (double long)(pow(256., i));
return result;
}
int main() {
unsigned char header[8], countDirectoryEntries[2], tagIdentifier[2], fieldType[2], countData[4], offsetData[4], offsetIFD[4];
int adressNewIFD;
ifstream input("C:\\DSC_5857.dng", ios::in | ios::binary);
input.read((char*)header, sizeof header);
input.read((char*)countDirectoryEntries, sizeof countDirectoryEntries);
cout << "Directory entries of IFD0: " << BytesToInteger(countDirectoryEntries, 2) << endl << endl;
for (int i=0; i<BytesToInteger(countDirectoryEntries, 2); i++) {
input.read((char*)tagIdentifier, sizeof tagIdentifier);
input.read((char*)fieldType, sizeof fieldType);
input.read((char*)countData, sizeof countData);
input.read((char*)offsetData, sizeof offsetData);
// 254 == NewSubFileType tag, 330 == SubIFDs tag
if ((BytesToInteger(tagIdentifier, 2) == 330) || (BytesToInteger(tagIdentifier, 2) == 254)) {
// za NewSubFileType tag, offset je 1 (u ovom slucaju to je i podatak, jer staje u 4 bajta), pa vidimo da je IFD0 thumbnail
// za SubIFDs tag, offset je 714, odem na tu adresu (recimo u binary readeru ili kroz ovaj program) i dobijem besmislene vrijednosti
cout << "Tag identifier: " << BytesToInteger(tagIdentifier, 2) << endl;
cout << "Field type: " << BytesToInteger(fieldType, 2) << endl;
cout << "Count data: " << BytesToInteger(countData, 4) << endl;
cout << "Offset data: " << BytesToInteger(offsetData, 4) << endl << endl;
adressNewIFD = BytesToInteger(offsetData, 4);
}
}
input.seekg(adressNewIFD); // adresa novog IFD-a
input.read((char*)countDirectoryEntries, sizeof countDirectoryEntries);
cout << "Directory entries of new IFD: " << BytesToInteger(countDirectoryEntries, 2) << endl << endl;
// prvi tag, dobiju se besmislene vrijednosti
input.read((char*)tagIdentifier, sizeof tagIdentifier);
input.read((char*)fieldType, sizeof fieldType);
input.read((char*)countData, sizeof countData);
input.read((char*)offsetData, sizeof offsetData);
cout << "Tag identifier: " << BytesToInteger(tagIdentifier, 2) << endl;
cout << "Field type: " << BytesToInteger(fieldType, 2) << endl;
cout << "Count data: " << BytesToInteger(countData, 4) << endl;
cout << "Offset data: " << BytesToInteger(offsetData, 4) << endl << endl;
return 0;
}