TIFF图像文件格式分析
一、TIFF图像文件格式概述
1、TIFF的简介
TIFF是Tagged Image File Format的缩写,为标签图像文件格式,是一种灵活的位图格式,主要用来存储包括照片和艺术图在内的图像。最初由Aldus公司与微软公司一起为PostScript打印开发。TIFF与JPEG和PNG一起成为流行的高位彩色图像格式。TIFF格式在业界得到了广泛的支持,如Adobe公司的Photoshop、The GIMP Team的GIMP、Ulead PhotoImpact和Paint Shop Pro等图像处理应用、QuarkXPress和Adobe InDesign这样的桌面印刷和页面排版应用,扫描、传真、文字处理、光学字符识别和其它一些应用等都支持这种格式。从Aldus获得了PageMaker印刷应用程序的Adobe公司控制着TIFF规范。
在现在的标准中,只有TIFF存在, 其他的提法已经舍弃不用了。做为一种标记语言,TIFF与其他文件格式最大的不同在于除了图像数据,它还可以记录很多图像的其他信息。它记录图像数据的方式也比较灵活, 理论上来说, 任何其他的图像格式都能为TIFF所用, 嵌入到TIFF里面。比如JPEG, Lossless JPEG, JPEG2000和任意数据宽度的原始无压缩数据都可以方便的嵌入到TIFF中去。由于它的可扩展性, TIFF在数字影响、遥感、医学等领域中得到了广泛的应用。TIFF文件的后缀是.tif或者.tiff。
2、TIFF的局限及将来发展
TIFF的最大局限在于用4byte来表示偏移量,这样导致文件最大只能有4G。 在20年前指定TIFF标准的时候可能觉得4G足够用了。但是现在这确实成了制约TIFF反展的一个瓶颈。 目前BigTIFF已经提出用8个字节来表示偏移量。这样数据量应该足够大了。也许在不久的将来,这会成为新的tiff的baseline。
二、TIFF文件结构
TIFF文件中的三个关键词是:
1、图像文件头Image File Header(IFH)
3、图像文件目录Image File Directory(IFD)
2、目录项Directory Entry(DE)。
每一幅图像是以8字节的IFH开始的, 这个IFH指向了第一个IFD。IFD包含了图像的各种信息, 同时也包含了一个指向实际图像数据的指针。
1、IFH的构成
Byte 0-1: 字节顺序标志位, 值为II或者MM。II表示小字节在前, 又称为little-endian。MM表示大字节在前,又成为big-endian。
Byte 2-3: TIFF的标志位,一般都是42
Byte 4-7: 第一个IFD的偏移量。可以在任意位置, 但必须是在一个字的边界,也就是说必须是2的整数倍。
可用下图来表示:(图来自http://www.cppblog.com/windcsn/archive/2009/03/12/1158.html)
2、IFD的构成(0代表此IFD的起始位置)
Byte 0-1: 表示此IFD包含了多少个DE,假设数目为n
Byte 2-(n12+1): n个DE
Byte (n12+2)-(n*12+5): 下一个IFD的偏移量,如果没有则置为0
可用下图来表示:(图来自http://www.cppblog.com/windcsn/archive/2009/03/12/1158.html)
3、DE的构成
Byte 0-1: 此TAG的唯一标识
Byte 2-3: 数据类型。
Byte 4-7: 数量。通过类型和数量可以确定存储此TAG的数据需要占据的字节数
Byte 8-11: 如果占用的字节数少于4, 则数据直接存于此。 如果超过4个,则这里存放的是指向实际数据的指针
4、基本TIFF TAGS
在这里列举一些基z本的Tags,更多Tag可以在http://www.awaresystems.be/imaging/tiff/tifftags/baseline.html中查看
十进制码 | 十六进制码 | 名称 | 简短描述 |
---|---|---|---|
254 | 00FE | NewSubfileType | 新的子文件类型标识 LONG 长度为1;用比特来标识图像的类型:Bit0如果是1代表缩略图,Bit1如果是1代表多页图像中的某一页,Bit2如果是1代表它是透明度掩码图像,其余的位数暂时没有定义。与SubfileType的是,此Tag用比特位来区分文件类型而不是用值来区分 |
256 | 0100 | ImageWidth | 图像宽度 SHORT或者LONG 长度为1 |
257 | 0101 | mageLength | 图像高度 SHORT或者LONG 长度为1 |
258 | 0102 | BitsPerSample | 每个分量的Bit数 SHORT 长度为SamplesPerPixel |
259 | 0103 | Compression | 压缩类型 SHORT 长度为1;随着TIFF的不断扩张,目前支持多达几十种的压缩方式。就我个人看来,最需要关注的有以下两个值:Compression=1: 没有压缩;Compression=7:JPEG压缩。 如果是RGB图像并且SamplesPerPixel=3,则是标准的有损JPEG压缩。如果是CFA图像,则是Lossless JPEG |
262 | 0106 | PhotometricInterpretation | 颜色空间 SHORT 长度为1;0 = WhiteIsZero. 应用于灰度或者二值图像, 0对应最亮灰度;1 = BlackIsZero. 应用于灰度或者二值图像. 0对应最暗灰度;2 = RGB. 正常RGB图像,存储顺序为R,G,B;3 = Palette color. 索引图像, ColorMap必须定义,SamplesPerPixel必须1. |
320 | 0140 | ColorMap | 调色板 |
三、实例图片分析
我们以如下图片为例,用FlexHEX作为解析工具进行二进制分析。(CSDN无法上传TIFF文件,所以上传的使TIFF文件的截图为。png格式)
1、IFH
最开始两个字节“ll”(0x4949),II表示小字节在前, 又称为little-endian;后两个字节为0x2A,是TIFF的标志位,一般都是十进制42(0x2A);再后面四个字节0xB4010000,为第一个IFD的偏移量(从数据开始处便宜0x1B4)。可以在任意位置, 但必须是在一个字的边界,也就是说必须是2的整数倍。
2、IFD
IFD开始位置从标黑处开始;
前两个字节0x1200表示此此IFD一共有0x12个DE;
下12个字节表示一个DE,以此类推,一共有18个DE;
在所有DE之后的四个字节0x0000则表示下一个IFD的偏移量,在此图片中只有一个(数值为0所以只有一个)
3、DE
因为本图的DE有18个,并且有压缩。
第一个DE:前2个字节0xFE00表示标签编号(0xFE),通过查表可知道
其为NewSubfileType,后面2个字节0x0400表示数据类型,再后面4个字节0x01000000表示类型数据的数量,这个类型数量为1(0x1),最后4个字节0x00000000表示属性值本身为0。
第二个DE:因为是ll(小字节在前)所以是0x0100,表示图像宽度,0x3表示数据类型,0x1表示有1个这个类型,0x1F表示宽度为31;
第三个DE:因为是ll(小字节在前)所以是0x0101,表示图像高度,0x3表示数据类型,0x1表示有1个这个类型,0x1F表示高度为31;
第四个DE:因为是ll(小字节在前)所以是0x0102,表示每个分量的Bit数,0x3表示数据类型,0x3表示有3个这个类型,0x2A2表示每个分量的Bit数为0x2A2;
第五个DE:因为是ll(小字节在前)所以是0x0103,表示图像压缩类型,0x3表示数据类型,0x1表示有1个这个类型,0x5表示为 LZW压缩;
第六个DE:因为是ll(小字节在前)所以是0x0106,表示图像颜色空间,0x3表示数据类型,0x1表示有1个这个类型,0x2表示为 RGB. 正常RGB图像,存储顺序为R,G,B;
第七个DE:因为是ll(小字节在前)所以是0x010A,表示图像CellLength(抖动或半色调矩阵的长度,用于创建抖动或半色调的双层文件),0x3表示数据类型,0x1表示有1个这个类型,0x1表示长度为1;
第八个DE:因为是ll(小字节在前)所以是0x0111,表示图像每个Strip的偏移量,0x4表示数据类型,0x1表示有1个这个类型,0x8表示为 偏移量为8;
第九个DE:因为是ll(小字节在前)所以是0x0112,表示图像相对于行和列的方向,0x3表示数据类型,0x1表示有1个这个类型,0x1表示为第0行表示图像的可视顶部,第0列表示可视的左侧;
第十个DE:因为是ll(小字节在前)所以是0x0115,表示图像每个象素的通道数,0x3表示数据类型,0x1表示有1个这个类型,0x3表示为通道数为3(SamplesPerPixel is usually 3 for RGB images);
第十一个DE:因为是ll(小字节在前)所以是0x0116,表示图像每个Strip有多少行,0x3表示数据类型,0x1表示有1个这个类型,0x58表示为每个Strip有88行;
第十二个DE:因为是ll(小字节在前)所以是0x0117,表示图像每个Strip的长度,0x4表示数据类型,0x1表示有1个这个类型,0x1AB表示为每个Strip的长度为427;
第十三个DE:因为是ll(小字节在前)所以是0x011A,表示图像每个解析单元在ImageWidth方向的像素数,0x5表示数据类型,0x1表示有1个这个类型,0x292表示为每个解析单元在ImageWidth方向的像素数为658;
第十四个DE:因为是ll(小字节在前)所以是0x011B,表示图像每个解析单元在ImageLength方向上的像素数,0x5表示数据类型,0x1表示有1个这个类型,0x29A表示为每个解析单元在ImageLength方向上的像素数为666;
第十五个DE:因为是ll(小字节在前)所以是0x011C,表示图像如何存储每个像素的组件,0x3表示数据类型,0x1表示有1个这个类型,0x1表示为银河格式。每个像素的组件值被连续存储(例如,对于RGB数据,数据存储为RGBRGBRGB);
第十六个DE:因为是ll(小字节在前)所以是0x0128,表示图像X分辨率和Y分辨率的测量单位,0x3表示数据类型,0x1表示有1个这个类型,0x2表示单位为英寸;
第十七个DE:因为是ll(小字节在前)所以是0x013D,表示图像调色板,0x3表示数据类型,0x1表示有1个这个类型,0x2表示调色板颜色像素将根据第1次红色、绿色、蓝色三重奏显示(在调色板彩色图像中,像素值用于索引到RGB查找表中.例如,值为0的调色板颜色像素将根据第0次红色、绿色、蓝色三重奏显示。在TIFF颜色图中,所有的红色值都是第一位的,然后是绿色值,然后是蓝色值。每种颜色的值数为2**BitsPerSample。因此,8位调色板彩色图像的ColeMap字段将有3*256值.每个值的宽度为16位,这是由Short类型所暗示的。0表示最小强度,65535表示最大强度。黑色由0,0,0表示,白色表示为65535,65535,65535。);
第十八个DE:因为是ll(小字节在前)所以是0x0153,表示图像指定如何解释像素中的每个数据示例,0x3表示数据类型,0x3表示有1个这个类型,0x2A8为其值;
4、图像数据
在IFH和IFD之间的为图像数据,因为其中涉及LZW压缩,所以不太方便进行分析。
5、数据分析准确与否
经过上述数据分析可知,图像大小为31*31
~~
第二个DE:因为是ll(小字节在前)所以是0x0100,表示图像宽度,0x3表示数据类型,0x1表示有1个这个类型,0x1F表示宽度为31;
第三个DE:因为是ll(小字节在前)所以是0x0101,表示图像高度,0x3表示数据类型,0x1表示有1个这个类型,0x1F表示高度为31;
~~
通过查看源文件属性可知属性为31*31
通过数据对比可知,此次文件数据分析正确。
四、总结
TIFF文件分析的重点在于对DE的分析,通过查找TAGS标签号可知其对应的属性。
通过对TIFF文件的粗略解析,加深了我对图像文件格式的了解,也为后续编程处理文件打下基础。