(self, orig, dest)
| 109 | |
| 110 | class _GSConverter(_Converter): |
| 111 | def __call__(self, orig, dest): |
| 112 | if not self._proc: |
| 113 | self._proc = subprocess.Popen( |
| 114 | [mpl._get_executable_info("gs").executable, |
| 115 | "-dNOSAFER", "-dNOPAUSE", "-dEPSCrop", "-sDEVICE=png16m"], |
| 116 | # As far as I can see, ghostscript never outputs to stderr. |
| 117 | stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
| 118 | try: |
| 119 | self._read_until(b"\nGS") |
| 120 | except _ConverterError as e: |
| 121 | raise OSError(f"Failed to start Ghostscript:\n\n{e.args[0]}") from None |
| 122 | |
| 123 | def encode_and_escape(name): |
| 124 | return (os.fsencode(name) |
| 125 | .replace(b"\\", b"\\\\") |
| 126 | .replace(b"(", br"\(") |
| 127 | .replace(b")", br"\)")) |
| 128 | |
| 129 | self._proc.stdin.write( |
| 130 | b"<< /OutputFile (" |
| 131 | + encode_and_escape(dest) |
| 132 | + b") >> setpagedevice (" |
| 133 | + encode_and_escape(orig) |
| 134 | + b") run flush\n") |
| 135 | self._proc.stdin.flush() |
| 136 | # GS> if nothing left on the stack; GS<n> if n items left on the stack. |
| 137 | err = self._read_until((b"GS<", b"GS>")) |
| 138 | stack = self._read_until(b">") if err.endswith(b"GS<") else b"" |
| 139 | if stack or not os.path.exists(dest): |
| 140 | stack_size = int(stack[:-1]) if stack else 0 |
| 141 | self._proc.stdin.write(b"pop\n" * stack_size) |
| 142 | # Using the systemencoding should at least get the filenames right. |
| 143 | raise ImageComparisonFailure( |
| 144 | (err + stack).decode(sys.getfilesystemencoding(), "replace")) |
| 145 | |
| 146 | |
| 147 | class _SVGConverter(_Converter): |
no test coverage detected