From 1fdef58e221ec5e4490e6828e2d2152cebd0edf5 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 12 Sep 2023 19:29:02 +1000 Subject: [PATCH] Added gs_binary to control Ghostscript use on all platforms --- Tests/test_file_eps.py | 14 ++++++++ src/PIL/EpsImagePlugin.py | 67 +++++++++++++++------------------------ 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/Tests/test_file_eps.py b/Tests/test_file_eps.py index 26adfff8786..606f3e0e769 100644 --- a/Tests/test_file_eps.py +++ b/Tests/test_file_eps.py @@ -1,4 +1,5 @@ import io +import sys import pytest @@ -10,6 +11,7 @@ hopper, mark_if_feature_version, skip_unless_feature, + is_win32, ) HAS_GHOSTSCRIPT = EpsImagePlugin.has_ghostscript() @@ -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): diff --git a/src/PIL/EpsImagePlugin.py b/src/PIL/EpsImagePlugin.py index 84177aaaa88..ec4e822d109 100644 --- a/src/PIL/EpsImagePlugin.py +++ b/src/PIL/EpsImagePlugin.py @@ -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] @@ -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) @@ -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