代碼基本取自dcraw(www.cybercom.net/~dcoffin/dcraw/) 做了一些修改和整理
//首先定義一些必須的全局變量和一些有用的函數,主要是讀取各種數據類型的函數
short order;
FILE *ifp = ifp = fopen ("filename.tiff", "rb");
ushort CLASS sget2 (uchar *s)
{
if (order == 0x4949) /* "II" means little-endian */
return s[0] | s[1] << 8;
else /* "MM" means big-endian */
return s[0] << 8 | s[1];
}
ushort CLASS get2()
{
uchar str[2] = { 0xff,0xff };
fread (str, 1, 2, ifp);
return sget2(str);
}
unsigned CLASS sget4 (uchar *s)
{
if (order == 0x4949)
return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
else
return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
}
#define sget4(s) sget4((uchar *)s)
unsigned CLASS get4()
{
uchar str[4] = { 0xff,0xff,0xff,0xff };
fread (str, 1, 4, ifp);
return sget4(str);
}
unsigned CLASS getint (int type)
{
return type == 3 ? get2() : get4();
}
float CLASS int_to_float (int i)
{
union { int i; float f; } u;
u.i = i;
return u.f;
}
double CLASS getreal (int type)
{
union { char c[8]; double d; } u;
int i, rev;
switch (type) {
case 3: return (unsigned short) get2();
case 4: return (unsigned int) get4();
case 5: u.d = (unsigned int) get4();
return u.d / (unsigned int) get4();
case 8: return (signed short) get2();
case 9: return (signed int) get4();
case 10: u.d = (signed int) get4();
return u.d / (signed int) get4();
case 11: return int_to_float (get4());
case 12:
rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
for (i=0; i < 8; i++)
u.c[i ^ rev] = fgetc(ifp);
return u.d;
default: return fgetc(ifp);
}
}
//先解IFH,得到order和第一個IFD的偏移量
//然後解IFD
//最後是圖像數據
//對於多個IFD,採用同樣的處理方法
int CLASS parse_tiff ()
{
int doff;
fseek (ifp, 0, SEEK_SET);
order = get2();//"II"或者"MM"
get2();//這個值應該是42, 跳過之
doff = get4();//第一個IFD的偏移量
fseek (ifp, doff, SEEK_SET);
parse_tiff_ifd ();
//根據從Tag中得到的值去獲取或者解壓相應的圖像數據
}
int CLASS parse_tiff_ifd ()
{
entries = get2();
if (entries > 512) return 1;
while (entries--) {
//先讀取Tag,Type和Count的值
//根據Type和Count確定存儲的是值還是位置,
}
//獲取下一個IFD的偏移量
}