Molim za pomoć ako neko poznaje tiff standard. Moram za seminarski napraviti plugin za čitanje dng datoteka, čija je struktura podataka rađena poTIFF-EP standardu. Problem je u slijedećem, u dokumentaciji piše da NewSubFileType tag određuje da li IFD0 predstavlja thumbnail image ili ne. Vrijednost 1 u tom tag-u kaže da IFD0 predstavlja thumbnail i da IFD0 pokazuje na neki drugi IFD koji u sebi sadrži (preciznije, pokazuje na pravu sliku). Ako je to tako, SubIFDs tag u sebi sadrži adresu (u bajtima, računajući od početka datoteke) na taj novi IFD. Ta adresa je u mom slučaju 714. Ja odem na tu adresu, pročitam prva dva bajta, koja mi kažu koliko tagova ima u tom IFD-u i dobijem broj 60780 (što je besmisleno). Ja sam se stvarno trudio detaljno čitati dokumentaciju, ali mi nije jasno u čemu je problem.
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;
}