Skip to content

Commit

Permalink
Added gs_binary to control Ghostscript use on all platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Sep 12, 2023
1 parent f225130 commit 1fdef58
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 41 deletions.
14 changes: 14 additions & 0 deletions Tests/test_file_eps.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import io
import sys

import pytest

Expand All @@ -10,6 +11,7 @@
hopper,
mark_if_feature_version,
skip_unless_feature,
is_win32,
)

HAS_GHOSTSCRIPT = EpsImagePlugin.has_ghostscript()
Expand Down Expand Up @@ -98,6 +100,18 @@ def test_load():
assert im.load()[0, 0] == (255, 255, 255)


def test_binary():
if HAS_GHOSTSCRIPT:
assert EpsImagePlugin.gs_binary is not None
else:
assert EpsImagePlugin.gs_binary is None

if HAS_GHOSTSCRIPT and is_win32():
assert EpsImagePlugin.gs_windows_binary is not None
else:
assert EpsImagePlugin.gs_windows_binary is None


def test_invalid_file():
invalid_file = "Tests/images/flower.jpg"
with pytest.raises(SyntaxError):
Expand Down
67 changes: 26 additions & 41 deletions src/PIL/EpsImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,40 +37,39 @@
split = re.compile(r"^%%([^:]*):[ \t]*(.*)[ \t]*$")
field = re.compile(r"^%[%!\w]([^:]*)[ \t]*$")

gs_binary = None
gs_windows_binary = None


def _get_windows_binary():
global gs_windows_binary
if gs_windows_binary is not None:
return gs_windows_binary
if not sys.platform.startswith("win"):
return
import shutil

for binary in ("gswin32c", "gswin64c", "gs"):
if shutil.which(binary) is not None:
gs_windows_binary = binary
break
else:
gs_windows_binary = False
return gs_windows_binary


def has_ghostscript():
gs_windows_binary = _get_windows_binary()
if gs_windows_binary is not None:
return gs_windows_binary is not False
try:
subprocess.check_call(["gs", "--version"], stdout=subprocess.DEVNULL)
return True
except OSError:
# No Ghostscript
return False
global gs_binary, gs_windows_binary
if gs_binary is None:
if sys.platform.startswith("win"):
if gs_windows_binary is None:
import shutil

for binary in ("gswin32c", "gswin64c", "gs"):
if shutil.which(binary) is not None:
gs_windows_binary = binary
break
else:
gs_windows_binary = False
gs_binary = gs_windows_binary
else:
try:
subprocess.check_call(["gs", "--version"], stdout=subprocess.DEVNULL)
gs_binary = "gs"
except OSError:
gs_binary = False
return gs_binary is not False


def Ghostscript(tile, size, fp, scale=1, transparency=False):
"""Render an image using Ghostscript"""
global gs_binary
if not has_ghostscript():
msg = "Unable to locate Ghostscript on paths"
raise OSError(msg)

# Unpack decoder tile
decoder, tile, offset, data = tile[0]
Expand Down Expand Up @@ -120,7 +119,7 @@ def Ghostscript(tile, size, fp, scale=1, transparency=False):

# Build Ghostscript command
command = [
"gs",
gs_binary,
"-q", # quiet mode
"-g%dx%d" % size, # set output geometry (pixels)
"-r%fx%f" % res, # set input DPI (dots per inch)
Expand All @@ -139,20 +138,6 @@ def Ghostscript(tile, size, fp, scale=1, transparency=False):
"showpage",
]

gs_windows_binary = _get_windows_binary()
if gs_windows_binary is False:
try:
os.unlink(outfile)
if infile_temp:
os.unlink(infile_temp)
except OSError:
pass

msg = "Unable to locate Ghostscript on paths"
raise OSError(msg)
elif gs_windows_binary is not None:
command[0] = gs_windows_binary

# push data through Ghostscript
try:
startupinfo = None
Expand Down

0 comments on commit 1fdef58

Please sign in to comment.