4
votes

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
1

1 Answers

1
votes

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.