PDF文件格式(一):新版格式交叉引用表

PDF交叉引用表是PDF的重要组成部分,本文介绍的是新交叉引用表,这种引用表的格式是PDF的obj格式,内容是被压缩存放在obj下的stream中,因此比常规的引用表格式复杂。下面就开始介绍这种交叉引用表的格式和解析的方法:

1 定位最初始位置:

和旧的交叉引用表方法一样,需要到文件尾部找到"startxref"后面的数字,就是第一个交叉引用表的位置(PDF交叉引用表是倒序的,应该说是最后一个)。

2 解析交叉引用表obj内容:

取出obj内DecodeParms,W, Index,size,Prev ,stream内容

DecodeParms是解压缩参数,针对当前Obj有stream内容的情形,解压缩stream内容使用(解压缩部分后续再说)

W的值是数组,数组里面有三个数字,表示的是交叉引用表三个元素(type,file offset,generation)信息在stream内容需要读取的长度;

Index的值也是数组,数量是偶数个,两两一组,表示交叉引用对应obj的起始obj号和范围;

Prev的值是下一个交叉引用表的位置(准确的说应该叫上一个,因为PDF交叉引用表是倒序的,为了描述方便);

stream的内容是交叉引用表的实际内容,交叉引用相关信息被处理,再被压缩

3 多个交叉引用表

 当文档内有多个交叉引用表时,当前引用表obj的prev内容保存的是下一个交叉引用表的位置,如果当前引用表时最后一个,那么当前obj找不到Prev。

在解析多个交叉引用表时,需要不断查找当前obj下是否存在prev,如果不存在,则停止查找,说明交叉引用表到此是最后一个,在交叉引用表尾都会部有startxrf字段,后面的数字就是当前交叉引用表位置。因此,在最开头去文件尾部查找startxrf,也是在查找第一个交叉引用表尾部的startxrf。

PDF文件格式(一):新版格式交叉引用表_第1张图片

这里第一个引用表的Prev是541882,找到541882(0x844ba)位置如下:

PDF文件格式(一):新版格式交叉引用表_第2张图片

105 0 obj仍然是交叉引用表obj,里面还有Prev,在endobj后面跟着startxrf(当前交叉引用表位置)。

注意:有时候startxrf记录的不是当前obj的位置,准确的方式是使用引用表obj内的Prev判断。

下面结合实例,看一下交叉引用表时如何被解析出来的:

这是一段PDF文档内容:

PDF文件格式(一):新版格式交叉引用表_第3张图片

可以看到,在PDF尾部的startxrf的是572618,对应的位置是8bcca,正好是116 0 obj,这里的Index是[1 1 4 1 12 1 106 11],表示这段交叉引用表保存的是1号obj,4号obj,12号obj,106号至117(106+11)号obj(106,107,108,109....117);W是[1 3 0];接下来是stream内容,下面是一段解压之后的stream内容:

第一个字节是type内容,0表示f,1表示n,2表示o;2到4字节是offset值,二进制存储,得到结果是542265,最后由于W数组最后一个是0,所以不读取stream数据,generation值为0;从stream起始位置对应Index的顺序(两两一组)最后得出交叉引用表的信息:1号obj,type是n,位置在542265,generation是0,;好了现在找到了交叉引用表的1号obj,我们到542265位置看一下:

PDF文件格式(一):新版格式交叉引用表_第4张图片

可以看到,0x84639对应的位置正是1 0 obj,这样一个完整的交叉引用表流程解析完毕。

你可能感兴趣的:(文档结构,pdf)