signed

QiShunwang

“诚信为本、客户至上”

PDF文件结构

2020/12/28 19:29:34   来源:

研究一下PDF文件结构,简单对比.txt,.docx等之间的异同。

-> 传送门 <-

  • 1 PDF file structure
    • ① general
    • ② header
    • ③ body
    • ④ cross-reference table
    • ⑤ trailer
  • 2 PDF document structure
    • ① Document catalog dictionary
    • ② Page tree
  • 3 Example "Hello world"
  • 4 Comparison
  • 5 References

1 PDF file structure

① general

  PDF使用户能够轻松可靠地交换和查看电子文档,而与创建或查看他们的环境无关。核心是源自PostScript页面描述语言的高级成像模型,可以以与设备分辨率无关的方式描述文本和图形。一个基本的PDF文件结构应包含四个部分1

在这里插入图片描述
  然而,为了使提高文件的效率、增量访问策略等,文件结构会附加一些额外的规则,这种文件组织方式称为线性化PDF(Linearized PDF)。除了这种组织方式外,所有文件在阅读时应通过交叉引用表和文件尾,这就是说文件的物理组织形式不影响阅读顺序,类似于链表,逻辑结构与存储结构相独立。

② header

  文件头以五个字符“%PDF-”打头后跟版本号

%PDF-1.0
%PDF-1.7
%PDF-2.0

等都是合法的。文件头行后应加上至少四个二进制字符的注释,确保传输应用通过文件开头识别这是文本文件或是二进制文件(?)。

③ body

  文件体包含一系列间接对象(objects),对象代表文档的内容,包括字体、文档页、图像等。文件体也可以包含对象流。

④ cross-reference table

  看文档理解就是索引表,包含允许随机访问间接对象的信息,因此无需读取整个文件即可找到任何一个特定的对象。每个间接对象包含一个单行条目,指明该对象在文件正文中的字节偏移量。
  每个交叉引用表以关键字xref的行开头,后跟交叉引用小节(增量更新会导致交叉引用小节不止一个),小节前有两个数字,以空格隔开,第一个数字表示小节中第一个对象的对象编号,第二个数字表示该小节中的条目数(类比于段始址+段长),条目见对象编号应连续。一个对象只能出现在一个小节中。
  一个交叉引用条目共有20位,有两种类型,对于正在使用中的对象以关键字(n)、空闲/被删除条目以关键字(f)作区分。

10-digit1-digit5-digit1-digit1-digit2-digit
10位字节偏移量空格5位世代号空格条目类型行结束符

  对象0的世代号为65535,其他物体号初始化时世代号应为00000,当物体被删除时,物体号空闲,标记为f,世代号自增1,增加到最大值65535时,该物体号无法再被使用。(这机制有啥用?)

						%例
xref           			%xref申明交叉引用表
0 6						%第一个数字是小节中第一个对象号,第二个数字是小节中条目数
0000000003 65535 f		%偏移量为3字节,世代号为65535,条目被删除以f表示
0000000017 00000 n
0000000081 00000 n
0000000000 00007 f
0000000331 00000 n
0000000409 00000 n
						%当物体号3再次被使用时,世代号被赋予7

⑤ trailer

  定位交叉引用表和任一物体,PDF文件应该从最后的文件尾开始阅读,文件最后一行仅包含文件结束标记**%%EOF**,标记结束前两行为关键字startxref和解码后的字节偏移量,键值对写到<<>>中。

trailer
<<key1 value1
key2 value2
…
keyn valuen
>>
startxref
Byte_offset_of_last_cross-reference_section
%%EOF

  文件尾条目关键字包含sizeprevrootencrypt等,例举下文例子中用到的两个。

  • size(integer类型)交叉引用表中条目总数,该值比文件中最大的对象号大1,所有比该值大的对象会被忽略。
  • root(dictionary类型)包含PDF文档的目录字典。

2 PDF document structure

① Document catalog dictionary

  PDF文档被视为PDF文件结构体body中物体objects的层次结构,层次结构的根root是文档的目录catalog dictionary,文档目录由文件尾trailer进行定位。
  目录包含文档的内容、大纲、主题、命名目的和其他一些属性。此外,还包含一些如何显示文档的控制信息等。

在这里插入图片描述

目录条目

  • Type(name) PDF物体的类型,与目录对应的值应该是Catalog
  • Pages(dictionary) page tree节点是page节点的父节点(如上图)
  • Outlines(dictionary) 引用文档大纲层次的根节点

② Page tree

  通过文档的page tree访问文档的页面,page tree定义了页面的顺序,包含两种类型的节点:中间节点page tree nodes和叶节点page objects,page实体只在叶节点处(b+tree?)。简单的page tree可以只包含叶节点page objects,但是为了存取效率,应当改善树结构例如平衡树以提高效率。

page tree node 条目

  • Type(name) PDF对象的类型,与page tree node对应的值应该是Pages
  • Parent(dictionary) page tree node的直接父节点,根节点不允许有父节点
  • Kids(array) page tree node的孩子节点,包括其他中间节点page tree node和叶节点page object
  • Count(integer) 叶节点page object的数目
2 0 obj
<</Type /Pages				%根节点
/Kids [4 0 R				%孩子节点4 10 24
10 0 R
24 0 R
]
/Count 3					%叶节点计数3
>>
endobj
4 0 obj
<</Type /Page				%叶节点4
…Additional entries describing the attributes of this page…
>>
endobj
10 0 obj
<</Type /Page				%叶节点10
…Additional entries describing the attributes of this page…
>>
endobj
24 0 obj
<</Type /Page				%叶节点24
…Additional entries describing the attributes of this page…
>>
endobj

page object 条目

  • Type(name) PDF对象的类型,与**page object **对应的值应该是PageTemplate
  • Parent(dictionary) page object的直接父节点,根节点不允许有父节点,Template 无此项
  • Resources(dictionary) page object的页面资源,若无资源对应empty,若无此条目表明资源从祖先节点继承(不推荐使用)
  • MediaBox(rectangle) 页面显示的边界
  • Contents(stream or array) 页面的内容,如果该条目不存在,则表示页面为空

3 Example “Hello world”

%PDF−1.4				%符合PDF1.4规范
%%档档					%确保传输应用通过文件开头识别这是文本文件或是二进制文件

1 0 obj					%第一个数字为对象号,第二个数字为世代号(说明创建后第几次被修改,0表示未被修改),obj表明这是一个对象
<< /Type /Catalog		%这是一个目录对象
/Outlines 2 0 R			%文档大纲根节点的对象号为2
/Pages 3 0 R			%文档页面根节点的对象号为3
>>
endobj					%一个对象结束标识

2 0 obj
<< /Type /Outlines		%这是一个大纲根节点对象
/Count 0				%大纲计数为0,表明该根节点无任何子节点
>>
endobj

3 0 obj
<< /Type /Pages			%这是一个页面根节点对象
/Kids [4 0 R]			%页面根节点下有一个页面,对象号为4
/Count 1				%对象3下有叶节点(page object)数目1
>>
endobj

4 0 obj					
<< /Type /Page			%这是一个页面对象
/Parent 3 0 R			%该页面的父节点为对象3
/MediaBox [0 0 612 792]	%页面显示边界
/Contents 5 0 R			%该页面的内容为对象5
/Resources << /ProcSet 6 0 R	%页面资源 内容类型为对象6
/Font << /F1 7 0 R >>			%	     字体类型为对象7,字体名为F1
>>
>>
endobj

5 0 obj
<< /Length 73 >>		%流对象字节数
stream					%流对象开始标记
BT						%文字对象开始标记
/F1 24 Tf				%F1字体 字号24
100 650 Td				%位置
(Hello World) Tj		%文本内容(。。)
ET						%文字对象结束标记
endstream				%流对象结束标记
endobj

6 0 obj
[/PDF /Text]			%文档内容类型为文本
endobj


7 0 obj
<< /Type /Font			%这是一个字体对象
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /MacRomanEncoding
>>
endobj

xref					%xref申明交叉引用表
0 8						%第一个数字是小节中第一个对象号,第二个数字是小节中条目数
0000000000 65535 f		%偏移量为0字节,世代号为65535,条目被删除以f表示
0000000009 00000 n
0000000074 00000 n
0000000120 00000 n
0000000179 00000 n
0000000364 00000 n
0000000466 00000 n
0000000496 00000 n

trailer					%文件尾
<< /Size 8				%交叉引用表中条目总数,该值比文件中最大的对象号大1
/Root 1 0 R				%文档目录对象号为1
>>
startxref				%交叉引用表的偏移地址
625
%%EOF					%文件结束标记

  保存为pdf文件查看
在这里插入图片描述

4 Comparison

  PDF基于结构化的二进制文件格式,与html、xml文件结构类似,由一些特定的格式、关键字、数据等组成。PDF文件数据是以二进制文件保存,用文本文件打开一般是不可读的,而html文件是以文本形式保存,打开文件可以阅读在浏览器中解析后的数据,html与pdf都包含文件显示信息,而xml文件只包含数据信息2
  doc是微软开发的封闭的格式,文件结构不公开,基于二进制保存。docx基于xml文件进行存储,与外部资源一起打包成zip格式进行存储,xml不包含如何显示等控制信息,只包含数据。
  txt是微软在操作系统上附带的文本文件格式,只支持纯文字,无法保存图像等多媒体信息,但只要知道编码方式,就能进行解码阅读,无需包含显示等控制信息。

5 References

  • [1] adobe

  • [2] pdf文档解析