pdf文档结构
champkeh opened this issue · comments
基本元素
PDF 文档的基本元素是 PDF 对象(PDF Object),PDF 对象包括直接对象
(Direct Object)和间接对象
(Indirect Object)。
直接对象
直接对象有8种类型,如下:
-
Boolean
布尔类型,值只能是true
和false
-
Integer and Real number
数值类型,包括整数和实数 -
String
字符串类型,包括包含在圆括号( )
内的文字字符串(literal string)
和包含在尖括号< >
内的十六进制字符串<hexadecimal string>
例如:
1. (Hello World)
2. <9ADCF1>
- Name
用字符组成的字符串,用/
作为前导符号,在PDF文件中具有唯一性。相同的名字表示相同的对象,常出现在Dictionary
里面作为Key
,用来表示对象名称
例如:
/Page
/Kid
- Array
数组类型,存在于方括号[ ]
内,元素可以是除Stream
之外的所有类型。只支持一维数组
例如:
[/Page false 17 (hello)]
上面这个数组包含了4种元素类型
- Dictionary
字典类型,包含在双尖括号<< >>
内,每两个元素为一对,第一个为key
,第二个为value
,key
的类型只能为Name
,value
可以是任意类型。Dictionary
可以嵌套
例如:
<</Page 1 0 obj /Filter /FlateDecode /Name (Hello)>>
上面这个字典包含了3对:
/Page -> 1 0 obj
/Filter -> /FlateDecode
/Name -> (Hello)
- Stream
流对象,使用字节表示的序列,长度理论上无限制。包含在stream
和endstream
之间,以CRLF
或LF
结尾,不能单独以CR
结尾。stream
前面的dictionary
用来描述该stream
的相关信息。
例如:
dictionary
stream
...
endstream
- Null
空对象类型,用关键字null
表示
间接对象
间接对象,又叫labelled object
,嵌套在关键词 n 0 obj
和 endobj
之间,使用一种标识来表示一个PDF对象,通过标识来让别的PDF对象进行引用,这个标识叫做间接对象的ID。
结构如下:
12 0 obj
...
endobj
第一行的12
规定为positive integer
,表示对象ID;0
表示生成号(generation number
),通常为0;obj
和endobj
中间的是对象内容。
其他地方引用该对象时,使用如下格式:
12 0 R
文件结构
+----------------------+
| Header | <-----文件头,表示版本.格式为: %PDF-1.M
+----------------------+
| Body | <-----文件体,由一系列PDF对象组成
+----------------------+
| Cross-reference |
| table | <-----交叉引用表,包含指向所有间接对象的文件位置索引的列表
| (xref) |
+----------------------+
| Trailer | <-----包含文件的根节点信息和文件解析的起点信息
+----------------------+
交叉引用表
结构:
xref
0 22
0000000002 65535 f
0000000016 00000 n
0000000004 00001 f
0000000066 00000 n
0000000006 00001 f
0000000169 00000 n
0000000008 00001 f
0000000229 00000 n
0000000010 00001 f
0000000353 00000 n
0000000011 00001 f
0000000012 00001 f
0000000013 00001 f
0000000015 00001 f
0000000373 00000 n
0000000016 00001 f
0000000017 00001 f
0000000018 00001 f
0000000019 00001 f
0000000020 00001 f
0000000000 00001 f
0000000394 00000 n
第一行 xref 表示交叉引用表开始;第二行 0 22 表示下面部分引用的对象从 0 开始,共有 22 个对象;第三行开始相同的结构,每行20字节,包括换行符。 nnnnnnnnnn 10位,字节偏移地址,表示从 文件开始(beginning of the file) 到 该对象开始(beginning of the object) 的偏移; ggggg 5位,生成号; N 可以为 n 或者 f,其中 n 表示该对象在使用,f 表示该对象为free状态,未被使用。
示例
%PDF-1.6 # 文件头,表示该文档符合 PDF 1.6 规范 , % 表示注释
%鲣 # (binary data)二进制, 主要用来表示文件内容是 text 还是 binary
12 0 obj # object 对象, 12是顺序号,0是生成号, obj 为关键词
<</Filter /FlateDecode # 过滤器类别,处理stream 和 endstream 之间的数据时候需要用到的, FlateDecode表示使用zip算法
/Length 1732>> # 表示 stream 和 endstream 之间数据的长度
stream # stream的内容部分
......
endstream
endobj # 标识该对象结束
1 0 obj
<</Contents 12 0 R
/Parent 2 0 R
/MediaBox [0 0 595 842]
/Resources 7 0 R
/Rotate 0
/Type /Page>>
endobj
2 0 obj
<</Kids [1 0 R] /Type/Pages /Count 1>>
endobj
......
9 0 obj
<</Fields [11 0 R] /XFA [5 0 R] /DA (/Helv 0 Tf 0 g )>>
endobj
11 0 obj
<</T (gapejess[0]) /Kids [4 0 R]>>
endobj
13 0 obj
<</AcroForm 9 0 R /Lang (en-us) /Pages 2 0 R /Type/Catalog>>
endobj
5 0 obj
<</Length 3602 /Filter/FlateDecode>>
stream
......
endstream
endobj
xref # 标识交叉引用表开始
0 14 # 说明下面对象编号是从0开始,总共有14个对象, 从 0 到 13
0000000000 65535 f # 第0个对象,规定生成号为65535,f 表示 free entry,对象不存在或者删除
0000003079 00000 n # 第1个对象,偏移地址为3079,生成号为0表示未被修改过, n 表示 in use
0000003191 00000 n
0000003245 00000 n
0000003695 00000 n
0000003955 00000 n
0000003515 00000 n
0000003347 00000 n
0000003446 00000 n
0000003756 00000 n
0000001823 00000 n
0000003827 00000 n
0000000017 00000 n
0000003878 00000 n
trailer # 标识文件尾trailer对象开始
<</Root 13 0 R # 表明根对象的对象号为13,即交叉表中的最后一个对象
/ID [<4E76CDCEDB1E2EC4AC47475DB4EE376E> <C8B1AEBC2C6615E39860F1C150A2847C>]
/Size 14 # 表明PDF文件的对象数目
/Info 8 0 R>>
startxref
7630 # 交叉引用表的偏移地址,相对于文件开始
%%EOF # 标识文件结束