Декодирование и распаковка AI9_DataStream в файлах.eps
Контекст: я пытаюсь автоматизировать проверку файлов eps, чтобы определить список атрибутов, например, содержит ли файл заблокированные слои, встроенные растровые изображения и т. Д.
До сих пор мы обнаружили, что некоторые из этих вещей могут быть обнаружены с помощью проверки необработанных данных файла eps и сопровождающих их метаданных (аналогично информации, возвращаемой imagemagick.) Однако кажется, что в файлах, созданных иллюстратором 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 ответа
Очевидно, мы что-то не так поняли в кодировке ascii85. E сть ~>
разделитель в конце закодированного блока, который необходимо исключить из строки перед декодированием и последующим разархивированием.
Так что вместо:
/(%AI9_DataStream)([\s\S]*?)(AI9_PrivateDataEnd)/
Использование:
/(%AI9_DataStream)([\s\S]*?)(~>)/
И вы можете получить правильные закодированные / сжатые данные. До сих пор это давало читаемые / регулярные выражения для человека во всех наших текущих тестовых случаях, поэтому, если мы не бросим другую кривую, которая, кажется, является ответом.
Единственный надежный способ получения содержимого из PostScript - это запуск его через интерпретатор PostScript, поскольку PostScript является языком программирования.
Если вы придерживаетесь определенного рабочего процесса с хорошо понятным вводом, то вы можете добиться некоторого успеха в простом разборе, но это единственный вероятный сценарий, который будет работать.
Обратите внимание, что файлы EPS не имеют "слоев" и, конечно, не имеют "заблокированных" слоев.
Вы на самом деле не указали на рабочий пример, но я подозреваю, что содержимое AI9_DataStream не относится к EPS. Вероятно, это средство для Illustrator включить собственный формат файла в файл EPS, не затрагивая интерпретатор PostScript. Вот как это работает с созданными AI файлами PDF.
Это означает, что при повторном открытии файла EPS с помощью Adobe Illustrator он игнорирует EPS и использует встроенный собственный файл, который волшебным образом дает вам возможность редактировать файл, включая функции, такие как слои, которые не могут быть представлены в EPS.