Reputation: 168
I'm trying to get information from a tiff image file. The output of Endian is correct but the rest of them are all wrong. The first 8 bytes of the tiff file is:
4d 4d 00 2a 00 02 03 60
The magicno I'm getting is 10752, which is 2A00 is HEX. But I should be reading the third and for bytes, which should be 002a. Need help please!!
Here's my code.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char buffer[3];
short magicno;
int ifdaddress;
short ifdcount;
ifstream imfile;
imfile.open("pooh.tif",ios::binary);
imfile.seekg(0,ios::beg);
imfile.read(buffer,2);
imfile.read((char*)&magicno, 2);
imfile.read((char*)&ifdaddress, 4);
imfile.seekg(ifdaddress, ios::beg);
imfile.read((char*)&ifdcount, 2);
imfile.close();
buffer[2]='\0';
cout<<"Endian: "<<buffer<<endl;
cout<<"Magic: "<<magicno<<endl;
cout<<"IFD Address: "<<ifdaddress<<endl;
cout<<"IFD CountL "<<ifdcount<<endl;
return 0;
}
My output is:
Endian: MM
Magic: 10752
IFD Address: 1610809856
IFD CountL 0
Upvotes: 4
Views: 10521
Reputation: 22478
You read the endianness marker correctly but you do not act upon it. From Adobe's "TIFF 6":
Bytes 0-1:
The byte order used within the file. Legal values are:
“II” (4949.H)
“MM” (4D4D.H)
In the “II” format, byte order is always from the least significant byte to the most significant byte, for both 16-bit and 32-bit integers. This is called little-endian byte order. In the “MM” format, byte order is always from most significant to least significant, for both 16-bit and 32-bit integers. This is called big-endian byte order.
(https://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf)
You need two sets of routines to read a short integer from a TIFF file (and also to read the longer integral types): one that reads Motorola ("MM") big-endian numbers, and one that reads Intel ("II") little-endians.
As it is, you must be one a little-endian system while attemtping to natively read big-endian numbers.
The code to correctly read a word can be as simple as
unsigned char d1,d2;
imfile.read (&d1,1);
imfile.read (&d2,1);
if (magicno == 0x4949)
word = d1 + (d2<<8);
else
word = (d1<<8)+d2;
Untested, but the general idea should be clear. Best make it a functionl because you need a similar setup for the "LONG" data type, which in turn is needed for the "RATIONAL" datatype.
Ultimately, for TIFF files, you may want a generalized read_data
function which first checks what data type is stored in the file and then calls the correct routine.
Upvotes: 1