mirror of
https://github.com/ocrmypdf/OCRmyPDF.git
synced 2025-12-29 08:01:04 +00:00
Embed ICC profile in .ps (fixing Ghostscript 9.28 compatibility)
Previously we included the filename, which required Postscript to run with file access enabled. For security, Ghostscript 9.28 enables ``-dSAFER`` and as such, no longer permits access to any file by default. This fix is necessary for compatibility with Ghostscript 9.28. We use ASCII85 for a slightly more compact representation.
This commit is contained in:
parent
a2a197ce4c
commit
17ac9d7a9a
@ -13,6 +13,16 @@ Note that it is licensed under GPLv3, so scripts that
|
||||
``import ocrmypdf`` and are released publicly should probably also be
|
||||
licensed under GPLv3.
|
||||
|
||||
v9.0.3
|
||||
======
|
||||
|
||||
- Embed an encoded version of the sRGB ICC profile in the intermediate
|
||||
Postscript file (used for PDF/A conversion). Previously we included the
|
||||
filename, which required Postscript to run with file access enabled. For
|
||||
security, Ghostscript 9.28 enables ``-dSAFER`` and as such, no longer
|
||||
permits access to any file by default. This fix is necessary for
|
||||
compatibility with Ghostscript 9.28.
|
||||
|
||||
v9.0.2
|
||||
======
|
||||
|
||||
|
||||
@ -259,6 +259,7 @@ def generate_pdfa(
|
||||
"-dQUIET",
|
||||
"-dBATCH",
|
||||
"-dNOPAUSE",
|
||||
"-dSAFER",
|
||||
"-dCompatibilityLevel=" + str(pdf_version),
|
||||
"-sDEVICE=pdfwrite",
|
||||
"-dAutoRotatePages=/None",
|
||||
|
||||
@ -31,6 +31,7 @@ Ghostscript's handling of pdfmark.
|
||||
|
||||
"""
|
||||
|
||||
import base64
|
||||
import os
|
||||
from binascii import hexlify
|
||||
from pathlib import Path
|
||||
@ -48,12 +49,10 @@ SRGB_ICC_PROFILE = pkg_resources.resource_filename('ocrmypdf', ICC_PROFILE_RELPA
|
||||
# files, from the Ghostscript documentation. Lines beginning with % are
|
||||
# comments. Python substitution variables have a '$' prefix.
|
||||
pdfa_def_template = u"""%!
|
||||
% Define entries in the document Info dictionary :
|
||||
% Define an ICC profile :
|
||||
/ICCProfile $icc_profile
|
||||
def
|
||||
|
||||
% Define an ICC profile :
|
||||
|
||||
[/_objdef {icc_PDFA} /type /stream /OBJ pdfmark
|
||||
[{icc_PDFA}
|
||||
<<
|
||||
@ -67,7 +66,7 @@ def
|
||||
(ERROR, unable to determine ProcessColorModel) == flush
|
||||
} ifelse
|
||||
>> /PUT pdfmark
|
||||
[{icc_PDFA} ICCProfile (r) file /PUT pdfmark
|
||||
[{icc_PDFA} ICCProfile /PUT pdfmark
|
||||
|
||||
% Define the output intent dictionary :
|
||||
|
||||
@ -104,16 +103,10 @@ def generate_pdfa_ps(target_filename, icc='sRGB'):
|
||||
else:
|
||||
raise NotImplementedError("Only supporting sRGB")
|
||||
|
||||
# pdfmark must contain the full path to the ICC profile, and pdfmark must be
|
||||
# also encoded in ASCII. ocrmypdf can be installed anywhere, including to
|
||||
# paths that have a non-ASCII character in the filename. Ghostscript
|
||||
# accepts hex-encoded strings and converts them to byte strings, so
|
||||
# we encode the path with fsencode() and use the hex representation.
|
||||
# UTF-16 not accepted here. (Even though ASCII encodable is the usual case,
|
||||
# do this always to avoid making it a rare conditional.)
|
||||
bytes_icc_profile = os.fsencode(icc_profile)
|
||||
hex_icc_profile = hexlify(bytes_icc_profile)
|
||||
icc_profile = '<' + hex_icc_profile.decode('ascii') + '>'
|
||||
# Read the ICC profile, encode as ASCII85 and convert to a string which we
|
||||
# will insert in the .ps file
|
||||
bytes_icc_profile = Path(icc_profile).read_bytes()
|
||||
icc_profile = base64.a85encode(bytes_icc_profile, adobe=True).decode('ascii')
|
||||
|
||||
t = Template(pdfa_def_template)
|
||||
ps = t.substitute(icc_profile=icc_profile, icc_identifier=icc)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user