在.eps文件中解码和解压缩AI9_DataStream

时间:2018-09-04 20:31:57

标签: zlib eps ascii85

上下文:我正在尝试自动检查eps文件以检测属性列表,例如文件是否包含锁定的图层,嵌入式位图图像等。

到目前为止,我们发现可以通过检查原始eps文件数据及其随附的元数据(类似于imagemagick返回的信息)来检测其中的某些内容。但是,似乎在illustrator创建的文件中在图9及更高版本中,此信息的绝大多数都编码在文件的“ AI9_DataStream”部分中。该数据通过ascii85进行编码和压缩。我们发现通过使用https://github.com/huandu/node-ascii85进行解码并使用节点zlib库进行解压缩/解压缩可以成功获取此数据。 (我们的项目是用node / javascript编写的)。但是,似乎在大约一半的测试用例/文件中,解压缩部分失败,抛出了Z_DATA_ERROR /“错误的数据检查”。

我们负责尝试解码的方法:

export const decode = eps =>
   new Promise((resolve, reject) => {
     const lineDelimiters = /\r\n%|\r%|\n%/g;
     const internal = eps.match(
       /(%AI9_DataStream)([\s\S]*?)(AI9_PrivateDataEnd)/
     );
     const hasDataStream = internal && internal.length >= 2;

     if (!hasDataStream) resolve('');

     const encoded = internal[2].replace(lineDelimiters, '');
     const decoded = ascii85.decode(encoded);

     try {
       zlib.unzip(decoded, (err, buffer) => {
         // files can crash this process, for now we need to allow it
         if (err) resolve('');
         else resolve(buffer.toString('utf8'));
       });
     } catch (err) {
       reject(err);
     }
   });

我想知道是否有人在此问题上有过任何经验,并且对可能导致此问题的方法有一定的了解,以及是否存在探索可靠解码此数据的替代方法。有关此主题的信息似乎很少,因此,非常感谢能够使我们朝正确方向前进的任何事情。

注意:ascii85解码产生的缓冲区都具有相同的78 9c头,应该指示标准zlib压缩(实际上,它解压缩成可解析的数据大约有一半的时间,而没有错误)

2 个答案:

答案 0 :(得分:0)

从PostScript获取内容的唯一可靠方法是通过PostScript解释器运行它,因为PostScript是一种编程语言。

如果您坚持使用具有很好理解的输入的特定工作流程,那么您可能会在简单解析中取得一些成功,但这是唯一可行的方案。

请注意,EPS文件没有“图层”,当然也没有“锁定”的图层。

您实际上并未指出一个可行的示例,但是我怀疑AI9_DataStream的内容与EPS无关。它可能是Illustrator将自己的本机文件格式包括在EPS文件中的一种方法,而不会影响PostScript解释器。这就是AI生成的PDF文件的工作方式。

这意味着当您使用Adobe Illustrator重新打开EPS文件时,它将忽略EPS并使用嵌入的本机文件,这神奇地使您能够编辑文件,包括诸如EPS中无法表示的图层之类的功能。

答案 1 :(得分:0)

显然,我们在误读有关ascii85编码的内容。在编码的块的末尾有一个~>分隔符,在解码和随后的解压缩之前需要从字符串中省略该分隔符。

所以代替:

/(%AI9_DataStream)([\s\S]*?)(AI9_PrivateDataEnd)/

使用:

/(%AI9_DataStream)([\s\S]*?)(~>)/

您可以获取正确的编码/压缩数据。到目前为止,这已经在我们所有的当前测试用例中产生了人类可读/可重新编码的数据,因此除非我们抛出另一条似乎可以解决问题的曲线。