TIFF图像文件格式详解(1)

http://blog.csdn.net/dcraw/article/details/6443537

1 什么是TIFF? 
TIFF是Tagged Image File Format的缩写。在现在的标准中,只有TIFF存在, 其他的提法已经舍弃不用了。做为一种标记语言,TIFF与其他文件格式最大的不同在于除了图像数据,它还可以记录很多图像的其他信息。它记录图像数据的方式也比较灵活, 理论上来说, 任何其他的图像格式都能为TIFF所用, 嵌入到TIFF里面。比如JPEG, Lossless JPEG, JPEG2000和任意数据宽度的原始无压缩数据都可以方便的嵌入到TIFF中去。由于它的可扩展性, TIFF在数字影响、遥感、医学等领域中得到了广泛的应用。TIFF文件的后缀是.tif或者.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的标志位,一般都是42
Byte 4-7: 第一个IFD的偏移量。可以在任意位置, 但必须是在一个字的边界,也就是说必须是2的整数倍。

IFD的构成(0代表此IFD的起始位置): 
Byte 0-1: 表示此IFD包含了多少个DE,假设数目为n
Byte 2-(n*12+1): n个DE
Byte (n*12+2)-(n*12+5): 下一个IFD的偏移量,如果没有则置为0

DE的构成: 
Byte 0-1: 此TAG的唯一标识
Byte 2-3: 数据类型。
Byte 4-7: 数量。通过类型和数量可以确定存储此TAG的数据需要占据的字节数
Byte 8-11: 如果占用的字节数少于4, 则数据直接存于此。 如果超过4个,则这里存放的是指向实际数据的指针

可以用以下的图来表示(图来自http://www.cppblog.com/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 byte
must 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-complement) integer.
7 = UNDEFINED An 8-bit byte that may contain anything, depending on
the definition of the field.
8 = SSHORT A 16-bit (2-byte) signed (twos-complement) integer.
9 = SLONG A 32-bit (4-byte) signed (twos-complement) integer.
10 = SRATIONAL Two SLONG’s: the first represents the numerator of a
fraction, 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 本文后续可能会涉及到的内容

(1) 重要的基本TAG

(2) 重要的扩展TAG

(3) 重要的私有TAG

(4) TIFF/EP以及DNG

(5) TIFF相关的软件

(6) TIFF目前的局限及未来的发展

TIFF图像文件格式详解(2)

http://blog.csdn.net/dcraw/article/details/6443679

1 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标准, 标准号为ISO 12234-2

DNG(Digital Negative)是Adobe开发的一种开放的raw image file format。 里面使用的tag基本上都定义在TIFF或者TIFF/EP中, 在DNG Sepcification中只是定义或者建议了数据的组织方式,颜色空间的转换等等。

就我个人的理解,这三者之间的关系应该是这样的:

(1) TIFF和DNG同为Specification,分别定义了后缀名为.tif/.tiff和.dng的文件格式

(2) 同时在TIFF Specification也定义个baseline及部分扩展的tag。TIFF/EP则定义并规范了在电子影像中所使用的TAG。

(3) DNG同时与TIFF和TIFF/EP兼容,并包含了EXIF和XMP信息。DNG实际上就是扩张的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格式仍然是大势所趋。


2 TIFF的应用

(1) tiff很灵活,可以记录各种类型不同精度的图像, 是一种很重要的图像基本格式。 这本省就是一个很重要的应用

(2) 如前所述, DNG也是一个很重要的应用

(3) 医学

(4) 地理遥感

(5) 印刷业

3 TIFF的局限及将来的发展

TIFF的最大局限在于用4byte来表示偏移量,这样导致文件最大只能有4G。 在20年前指定TIFF标准的时候可能觉得4G足够用了。但是现在这确实成了制约TIFF反展的一个瓶颈。 目前BigTIFF已经提出用8个字节来表示偏移量。这样数据量应该足够大了。也许在不久的将来,这会成为新的tiff的baseline

TIFF图像文件格式详解(3)
http://blog.csdn.net/dcraw/article/details/6445851

基本TIFF TAGS

本页主要摘自 http://www.awaresystems.be/imaging/tiff/tifftags/baseline.html。每一个TAG均有原始链接,可以点击查看详细的描述。

这些基本Tag是所有TIFF编解码器必须支持的Tag

名称 简短描述
十进制码 十六进制
254 00FE NewSubfileType

新的子文件类型标识 LONG 长度为1

用比特来标识图像的类型

Bit0如果是1代表缩略图

Bit1如果是1代表多页图像中的某一页

Bit2如果是1代表它是透明度掩码图像

其余的位数暂时没有定义。与SubfileType的是,此Tag用比特位来区分文件类型而不是用值来区分

255 00FF SubfileType

子文件类型标识 SHORT 长度为1

1 全分辨率图像

2 缩小分辨率的图像

3 多页图像的某一页

过时的Tag,已不再使用。

256 0100 ImageWidth

图像宽度 SHORT或者LONG 长度为1

257 0101 ImageLength 图像高度 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.

32803 = CFA (Color Filter Array)

263 0107 Threshholding 定义了转换成二值图像的阈值,忽略之
264 0108 CellWidth The width of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file.
265 0109 CellLength The length of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file.
266 010A FillOrder 在同一字节中的逻辑顺序。一般不做定义,要定义的话建议用1
270 010E ImageDescription 字符串, 对图像的描述
271 010F Make 字符串, 生产厂商的描述
272 0110 Model 字符串
273 0111 StripOffsets

每个Strip的偏移量 SHORT或者LONG

N = StripsPerImage for PlanarConfiguration equal to 1; N = SamplesPerPixel * StripsPerImage for PlanarConfiguration equal to 2

274 0112 Orientation The orientation of the image with respect to the rows and columns.
277 0115 SamplesPerPixel 每个象素的通道数 SHORT 长度为1
278 0116 RowsPerStrip

每个Strip有多少行 SHORT或者LONG 长度为1。Default是无限大

StripsPerImage = floor ((ImageLength + RowsPerStrip - 1) / RowsPerStrip).

279 0117 StripByteCounts

每个Strip的长度 SHORT或者LONG

N = StripsPerImage for PlanarConfiguration equal to 1; N = SamplesPerPixel * StripsPerImage for PlanarConfiguration equal to 2

280 0118 MinSampleValue The minimum component value used.
281 0119 MaxSampleValue The maximum component value used.
282 011A XResolution The number of pixels per ResolutionUnit in the ImageWidth direction.
283 011B YResolution The number of pixels per ResolutionUnit in the ImageLength direction.
284 011C PlanarConfiguration How the components of each pixel are stored.
288 0120 FreeOffsets For each string of contiguous unused bytes in a TIFF file, the byte offset of the string.
289 0121 FreeByteCounts For each string of contiguous unused bytes in a TIFF file, the number of bytes in the string.
290 0122 GrayResponseUnit The precision of the information contained in the GrayResponseCurve.
291 0123 GrayResponseCurve For grayscale data, the optical density of each possible pixel value.
296 0128 ResolutionUnit The unit of measurement for XResolution and YResolution.
305 0131 Software Name and version number of the software package(s) used to create the image.
306 0132 DateTime Date and time of image creation.
315 013B Artist Person who created the image.
316 013C HostComputer The computer and/or operating system in use at the time of image creation.
320 0140 ColorMap 调色板
338 0152 ExtraSamples Description of extra components.
33432 8298 Copyright Copyright notice.

TIFF图像文件格式详解(4)

http://blog.csdn.net/dcraw/article/details/6446444

代码基本取自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;elsereturn 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的偏移量
}

TIFF图像文件格式详解(5)

http://blog.csdn.net/dcraw/article/details/6455972

众所周知, JPEG是基于DCT变换的有损压缩图像格式。自从1992年ITU T.81标准创立以来,JPEG已经取得了巨大的成功。JPEG已经成为了现在最流行的图像格式。任何与图像有关的工具系统必须支持JPEG解码甚至编码。虽然它有这样或者那样的缺点, 由于其高压缩率,简单,灵活,以及应用广泛, 到现在为止一直是最流行的图像格式。虽然JPEG2000有很多优点,但丝毫没有撼动JPEG的老大地位。

虽然JPEG应用广泛, 但也仅仅限于日常生活中。在有些场合需要无损压缩,这时JPEG就无能为力了,比如医疗图像,Digital Photography中的Raw图像的保存。还好JPEG标准在指定的时候就考虑到了这种情况, 专门预留了无损压缩的格式。后来的ITU T.87完善了无损压缩编码,这就是JPEG-LS或者称为Lossless JPEG。

JPEG-LS采用的是预测熵编码。是一种行扫描的编码方式。从这个方面来说,它与JPEG没有任何共同点。不过它所使用的标记(Marker)都定义在JPEG中,所以也不能与JPEG独立开来。要想理解T87,必须得理解T81。

1 预测模型

C  B

A  X

X是需要编码的象素,A,B,C是其三个邻域值

选择值        预测值
0 No prediction
1 A
2 B
3 C
4 A + B – C
5 A + (B – C)/2
6 B + (A – C)/2
7 (A + B)/2

在预测过程中,所有不存在的值均初始化为0。

2 JPEG-LS的编码过程

首先,根据预测方式计算出差分值以及存储该值所需的比特数

然后,根据huffman码表查出该比特数的huffman码字并输出,然后输出对应位数的差分值

3 JPEG-LS 码流

以下码流是从一幅JPEG-LS的图像中截取的码流,对照ITU T81可以轻松理解每一个比特所代表的含义

FF D8 %SOI(Start Of Image)

FF C3 %SOF3

00 0B %长度=11,减去当前的两个字节,紧随之后的是9个字节

10 %比特数

0A 92 %高度=2706

38 60 %宽度= 14432

01 00 11 00

FF C4 %DHT

00 24 %长度

00 00 02 01 04 02 03 01 01 01 01 01 00 00 00 00 00 06 07 05 04 08 09 0A 03 0B 01 02 0C 00 0D 0E 0F 10

FF DA %SOS

00 08 %长度=8

01 00 00 06 00 00

%实际图像数据

FF 00 87 BC 7F 6F 03 F8 7E 7F DC F3 FE 1A A7 F7 4A 7F 86 3F FD B7 5F E2 20 7F 72 17 F8 69 5F DB EB FE 1F 47 F7 2B BF 86 D1 FD D3 2F E1 5E 7F 70 8F F8 93 FF 00 DC 1B FE 1D F7 F7 59 FF 00 84 A1 FD CB 4F E1 7A 7F 70 FB F8 82 5F DC CC FE 18 57 F7 25 BF 86 87 FD D0 4F E1 BD FF 00 6E FF 00 F8 86 BF DC 55 FE 1D 97 F7 15 BF 86 B5 FD C4 2F E1 A1 7F 6C 53 F8 7A 9F D2 4B FE 61 1F F4 37 BF 9C 25 FD 0A 6F 87 EF FB AC FF 00 C4 A3 FE DB EF F1 29 3F AF F5 FC 5F 6F B0 D3 F9 D8 7D AC 7D 00 3F 47 07 42 77 F4 0D BE 3B FF 00 EE D8 FF 00 16 CF FB B7 7F C3 02 FE E3 77 F0 E7 3F B9 C1 FC 2F DF EE 33 7F 0E 7B FB 9C 9F C3 16 FE E1 B7 F1 04 BF B9 85 FC 36 CF EE 3E 7F 0D D3 FB A0 BF C2 82 FE  。。。。。。

FF D9 %EOI

4 一些细节

4.1 如何选择预测模型?

开始我也为这个问题困惑了很久。如果全局图像都用同一个模型,这几个选择直接有差异吗?后来当我看到对Bayer Pattern的Raw图像进行编码的过程后,终于明白了这几个预测模型的差异和用途。

Bayer Pattern的图像如下所示:

BGBGBGBG

GRGRGRGR

BGBGBGBG

GRGRGRGR

BGBGBGBG

GRGRGRGR

BGBGBGBG

GRGRGRGR

只有同一个通道内的预测才有意义,但如果用原始的排列方式来直接编码,就会发现哪种方式都不合适。在处理Raw图像时,通常采用的是把两行合成一行的方法,如下:

BGBGBGBGGRGRGRGR

BGBGBGBGGRGRGRGR

BGBGBGBGGRGRGRGR

BGBGBGBGGRGRGRGR

这样预测模型2,4,6都可以使用。在DNG中一般都使用6。如果是普通的图像,由于每个象素都是同一个通道,所以哪种预测方式都差不多。从这个角度来看,感觉JPEG-LS天生就是为存储Raw图像而设计的。

4.2 在数据码流中如何处理FF?

由于X'FF'是marker的预留码字。为了方便的检测marker,在JPEG和JPEG-LS中对X'FF'都做了特殊的处理。在JPEG中, 如果编码出现了FF,而它并不是marker,那么在其之后插一个X'00'。在解码的时候遇到FF00就直接丢掉00。

ITU T87宣称JPEG-LS采用和JPEG不同的处理方式。由于JPEG-LS的marker都>=FF80,也就是说紧随FF的marker的最高位一定是1。如果在编数据码流的时候出现了X'FF',只插一个比特0用来区分X'FF'是数据码流还是marker。如果是0,就丢掉这一比特。

但是,在DNG中的Lossless JPEG仍然采用了JPEG的方式,从DCRAW和DNG SDK的代码中都可以得到验证,很奇怪。

TIFF图像文件详解相关推荐

  1. 【TIFF】一.TIFF 格式详解

    目录 ​​​​​​​ 一 TIFF图像格式概念 二 PNG, JPEG, GIF,  TIFF的区别是什么? 1.PNG 2.JPEG 3.GIF 4.TIFF 三 从哪里获取TIFF ​​​​​​​ ...

  2. FileReader详解与实例---读取并显示图像文件 | JS Mix

    2019独角兽企业重金招聘Python工程师标准>>> FileReader详解与实例---读取并显示图像文件 | JS Mix. 转载于:https://my.oschina.ne ...

  3. 【OpenCV 4开发详解】图像与视频的保存

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  4. 《OpenCV 4开发详解》图像的读取与显示

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  5. 三维重建:PNG格式详解-与LibPNG使用

    PNG图像包含了骨骼信息,左边的图像比右边的大几十K,包含了骨骼信息:        PNG格式详解:https://blog.mythsman.com/post/5d2d62b4a2005d7404 ...

  6. ArcGIS中栅格数据的金字塔详解

    1 栅格金字塔定义 金字塔可用于改善性能.它们是原始栅格数据集的缩减采样版本,可包含多个缩减采样图层.金字塔的各个连续图层均以 2:1 的比例进行缩减采样.以下是为栅格数据集创建的两级金字塔示例: 图 ...

  7. Gentoo 2005.1 完整的USE参数清单中文详解(转)

    Gentoo 2005.1 完整的USE参数清单中文详解(转)[@more@] apache2 - 当一个程序包同时支持Apache1和Apache2时,选择支持Apache2 *apm - 添加AP ...

  8. Gentoo 2005.1 完整的USE参数清单中文详解

    Gentoo 2005.1 完整的USE参数清单中文详解 apache2 - 当一个程序包同时支持Apache1和Apache2时,选择支持Apache2 *apm - 添加APM电源管理支持[参考文 ...

  9. iOS中ImageIO框架详解与应用分析

    2019独角兽企业重金招聘Python工程师标准>>> iOS中ImageIO框架详解与应用分析 一.引言 ImageIO框架提供了读取与写入图片数据的基本方法,使用它可以直接获取到 ...

最新文章

  1. 数据结构-冒泡排序过程
  2. vimproc_mac.so” is not found
  3. 民生银行 IT运维故障管理 可视化案例
  4. android activity view 区别,片段中onCreateView和onViewCreated之间的区别
  5. asp.net 安装element ui_Vue+Element环境搭建
  6. linux 虚拟一个40段ip,linux – 接口上的Multiples ip地址.我想指定其中一个输出
  7. 用asp.net实现微博系统_微信几亿人在线的点赞、取消点赞系统,用Redis如何实现?...
  8. numpy tricks(一)—— 多维数组的阈值化处理
  9. Flutter高级第6篇:事件广播 、事件监听
  10. 7.RabbitMQ实战 --- warren和Shovel:故障转移和复制
  11. 关于Encode in UTF-8 without BOM
  12. 两张表合并加标识根据ID
  13. 三菱PLC源型漏型输入输出
  14. Scrapy爬取美女图片第四集 突破反爬虫(上)
  15. android透明度100%,Android设置字体透明度
  16. 应用Dubbo框架打造仿猫眼项目 理解微服务核心思想
  17. MyEclipse配置jdk
  18. 徐家骏:我在华为工作十年的感悟 (转)
  19. vue绑定类名 禁用样式
  20. 关于python爬取网页

热门文章

  1. PS CC2019 安装过程中遇到 Command line option syntax error. Type Command /? for Help.
  2. phpExcel导出excel打不开问题
  3. GX Works2 SFC编程基础
  4. android n模拟器,Android N预览模拟器崩溃
  5. pageoffice 骑缝章_PageOffice V4.0
  6. [杂记]培训杂记(一)
  7. 艾默生质量流量计的正确安装
  8. Dell电脑安装系统时看不到固态硬盘的解决方案
  9. keil中不显示system_Viewer,无法查看寄存器的问题
  10. 任意人数的循环赛日程表 分治 非分治 c++