TIFF文件资料格式详细说明书

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1 什么是TIFF?
2 TIFF文件结构TIFF文件中的三个关键词是:图像文件头Image File Header(IFH),图像文件目录Image File Directory(IFD)和目录项Directory Entry(DE)。

每一幅图像是以8字节的IFH开始的,这个IFH指向了第一个IFD。

IFD包含了图像的各种信息,同时也包含了一个指向实际图像数据的指针。

IFH的构成:Byte 0-1: 字节顺序标志位,值为II或者MM。

II表示小字节在前,又称为
little-endian。

MM表示大字节在前,又成为big-endian。

Byte 2-3: TIFF的标志位,一般都是42Byte 4-7: 第一个IFD的偏移量。

可以在任意位置,但必须是在一个字的边界,也就是说必须是2的整数倍。

IFD的构成(0代表此IFD的起始位置):Byte 0-1: 表示此IFD包含了多少个DE,假设数目为nByte 2-(n*12+1): n个DEByte (n*12+2)-(n*12+5): 下一个IFD的偏移量,如果没有如此置为0DE的构成:Byte 0-1: 此TAG的唯一标识Byte 2-3: 数据类型。

Byte 4-7: 数量。

通过类型和数量可以确定存储此TAG的数据需要占据的字节数Byte 8-11: 如果占用的字节数少于4,如此数据直接存于此。

如果超过4个,如此这里存放的是指向实际数据的指针
可以用以下的图来表示(.cppblog./windcsn/archive/2009/03/12/1158.html)
在TIFF6.0中,定义了12种数据类型,分别是:
1 = BYTE 8-bit unsigned integer.
2 = ASCII 8-bit byte that contains a 7-bit ASCII code; the last bytemust be NUL (binary zero).
3 = SHORT 16-bit (2-byte) unsigned integer.
4 = LONG 32-bit (4-byte) unsigned integer.
5 = RATIONAL Two LONGs: the first represents the numerator
6 = SBYTE An 8-bit signed (twos-plement) integer.
7 = UNDEFINED An 8-bit byte that may contain anything, depending onthe definition of the field.
8 = SSHORT A 16-bit (2-byte) signed (twos-plement) integer.
9 = SLONG A 32-bit (4-byte) signed (twos-plement) integer.10 = SRATIONAL Two SLONG’s
: the first represents the numerator of afraction, the second the denominator.11 = FLOAT Single precision (4-byte) IEEE format.12 = DOUBLE Double precision (8-byte) IEEE format.
-个TIFF文件可能包含多个IFD,每一个IFD都是一个子文件。

Baseline解码器只要求解第一个IFD所对应的图像数据。

扩展的TIFF图像经常包含多个IFD,每一个IFD都包含了不同的信息。

3 TIFF,TIFF/EP以与DNG的关系
TIFF/EP的全称是"Tag Image File Format / Electronic Photography"。

它是一个名为“Electronic still-picture imaging – Removable memory – Part 2: TIFF/EP image data format〞ISO标准,标准号为ISO12234-2
DNG(Digital Negative)是Adobe开发的一种开放的raw image file format。

里面使用的tag根本上都定义在TIFF或者TIFF/EP中,在DNG Sepcification中只是定义或者建议了数据的组织方式,颜色空间的转换等等。

就我个人的理解,这三者之间的关系应该是这样的:
(2) 同时在TIFF Specification也定义个baseline与局部扩展的tag。

TIFF/EP如此定义并规X了在电子影像中所使用的TAG。

(3) DNG同时与TIFF和TIFF/EP兼容,并包含了EXIF和XMP信息。

DNG实际上就是扩X的TIFF,把DNG的扩展名改成TIF就可以直接预览图片
(4) 虽然都归Adobe所有,但都可以无偿使用
在DNG出现以前,各个数码相机制造商都有自己的格式,比如Canon(cr2/crw), Nikon(nef), Olympus(orf), Pentex(pef)等等。

之所以出现这么多格式,一方面的原因是在这之前没有统一的raw格式,但更重要的是,各个厂商希望用这个只对自己公开的数据格式来保护自己的私密信息。

Adobe推出DNG希望能一统raw的天下。

但很遗憾,只有极少的数码制造商响应,比如sony,hasselblad,目前的结果也仅仅是多了一种raw的格式。

虽然如何, DNG仍然是成功的。

由于有很成熟的DNG编解码与转换公司,很多小厂商乐于使用DNG作为自己的文件格式。

随着时间的推进,迫于消费者的意愿,大的数码厂商被迫支持DNG。

最后DNG统一这个数码raw格式仍然是大势所趋。

4 TIFF的特点
(1)应用广泛。

①TIFF可以描述多种类型的图像;②TIFF拥有一系列的压缩方案可供选择;③TIFF不依赖于具体的硬件;④TIFF是一种可移植的文件格式。

(2)TIFF具有可扩展性。

在TIFF 6.0中定义了许多扩展,它们允许TIFF提供以下通用功能:
①几种主要的压缩方法;②多种色彩表示方法;③图像质量增强;④特殊图像效果;⑤文档的存储和检索帮助。

(3)格式复杂。

TIFF文件的复杂性给它的应用带来了一些问题。

一方面,要写一种能够识别所有不同标记的软件非常困难。

另一方面,一个TIFF文件可以包含多个图像,每个图像都有自己的IFD和一系列标记,并且采用了多种压缩算法。

这样也增加了程序设计的复杂度。

5 TIFF的局限与将来的开展
TIFF的最大局限在于用4byte来表示偏移量,这样导致文件最大只能有4G。

在20年前指定TIFF标准的时候可能觉得4G足够用了。

但是现在这确实成了制约TIFF反展的一个瓶颈。

目前BigTIFF已经提出用8个字节来表示偏移量。

这样数据量应该足够大了。

也许在不久的将来,这会成为新的tiff的baseline
6根本TIFF TAGS
本页主要摘自 .awaresystems.be/imaging/tiff/tifftags/baseline.html。

每一个TAG均有原始,可以点击查看详细的描述。

这些根本Tag是所有TIFF编解码器必须支持的Tag
解码:
//首先定义一些必须的全局变量和一些有用的函数,主要是读取各种数据类型的函数
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的偏移量
}。

相关文档
最新文档