PDF文件格式(一):交叉引用流

在PDF-1.5版本之前,对象的交叉引用信息是存储在交叉引用表(cross-reference table)中的。在PDF-1.5版本之后,引进了交叉引用流(cross-reference stream)对象,可以用它来存储对象的交叉引用信息,就像交叉引用表的功能一样。

采用交叉引用流对象有以下几点好处:

1) 存储的信息更紧凑,并且可以引入压缩算法进行压缩

2) 提供了访问存储于对象流(ObjectStreams)中的被压缩的对象的功能

3) 提供了将来的可扩展的交叉引用流的表项类型,以便存储更多不同信息

PDF交叉引用表是PDF的重要组成部分,本文介绍的是交叉引用流(cross-reference stream)对象,这种引用表的格式是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。

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

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

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

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

这是一段PDF文档内容:

可以看到,在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位置看一下:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/457129.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Go语言成长之路】创建Go模块

文章目录 创建Go模块一、包、模块、函数的关系二、创建模块2.1 创建目录2.2 跟踪包2.3 编写模块代码 三、其它模块调用函数3.1 修改hello.go代码3.2 修改go.mod文件3.3 运行程序 四、错误处理4.1 函数添加错误处理4.2 调用者获取函数返回值4.4 执行错误处理代码 五、单元测试5.…

《【python】staticmethod与classmethod深度机制解析——要知其所以然》学习笔记

《【python】staticmethod与classmethod深度机制解析——要知其所以然》 1 Python中classmethod的实现机制 1.1 type_getattro(PyObject *type, PyObject *name)解析

2024三掌柜赠书活动第九期:Node.js从基础到项目实践(视频教学版)

目录 前言Node.js从基础到项目实践关于《Node.js从基础到项目实践(视频教学版)》编辑推荐内容简介作者简介图书目录书中前言/序言《Node.js从基础到项目实践(视频教学版)》全书速览结束语 前言 随着Web应用的快速发展,Node.js作为一种强大的JavaScript运行时环境&…

李沐《动手学深度学习》注意力机制

系列文章 李沐《动手学深度学习》预备知识 张量操作及数据处理 李沐《动手学深度学习》预备知识 线性代数及微积分 李沐《动手学深度学习》线性神经网络 线性回归 李沐《动手学深度学习》线性神经网络 softmax回归 李沐《动手学深度学习》多层感知机 模型概念和代码实现 李沐《…

MongoDB从入门到实战之MongoDB工作常用操作命令

前言: 上一章节我们快速的在Docker容器中安装了MongoDB,并且通过Navicat MongoDB可视化管理工具快速的连接、创建数据库、集合以及添加了文档数据源。这一章节我们主要是了解一下在日常工作中MongoDB一些常用的操作命令。 MongoDB从入门到实战的相关教程…

2024/2/6学习记录

ts 因为已经学习过了 js ,下面的都是挑了一些 ts 与 js 不同的地方来记录。 安装 npm install -g typescript 安装好之后,可以看看自己的版本 ts基础语法 模块 函数 变量 语法和表达式 注释 编译 ts 文件需要用 tsc xxx.ts ,js 文件…

怎么把照片变成漫画?分享4个工具!

在数字时代,我们每天都会接触到无数的图片,其中很多都是静态的、真实的。超全工具推荐!然而,有没有想过将你的照片变成漫画,让它们焕发出全新的生命力? 在数字时代,我们的创意和想象力不再局限…

BUUCTF-Real-[ThinkPHP]2-Rce1

任意代码执行漏洞 ThinkPHP 2.x版本中,使用preg_replace的/e模式匹配路由: $res preg_replace((\w).$depr.([^.$depr.\/])e, $var[\\\1\]"\\2";, implode($depr,$paths)); 导致用户的输入参数被插入双引号中执行,造成任意代码执行…

基于YOLOv7算法的高精度实时垃圾满溢检测系统(PyTorch+Pyside6+YOLOv7)

摘要:基于YOLOv7算法的高精度实时垃圾满溢检测系统可用于日常生活中检测与定位垃圾(garbage)、垃圾桶(garbage_bin)和垃圾满溢(overflow),此系统可完成对输入图片、视频、文件夹以及…

【Web】小白也能看懂的HGAME week1个人wp(全)

目录 ezHTTP Bypass it Select Courses 2048*16 jhat ezHTTP exp 如下: GET / HTTP/1.1 Host: 47.100.137.175:31717 Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Vidar; VidarOS x86_64) AppleW…

1896_Linux中free命令小结

1896_Linux中free命令小结 全部学习汇总: little_bits_of_linux: 一星半点的Linux经验 (gitee.com) 查看Linux中存储的使用情况,我经常使用htop,毕竟这个命令提供的信息是十分直观的。我现在常用的一个小主机其实是我的树莓派3B,虽…

第5节、S曲线加减速转动【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】,查看本系列全部文章 摘要:本节介绍步进电机S曲线相关内容,总共分四个小节讨论步进电机S曲线相关内容 5-1、S曲线加减速简介   根据上节内容,步进电机每一段的速度可以任意设置,但是每一段的…