From 4f7d784a7137c4a0f7c75891a63c5f0cd9170dd0 Mon Sep 17 00:00:00 2001 From: Brian Crowell Date: Tue, 23 Oct 2012 22:21:19 -0500 Subject: [PATCH] py3k: Actually fix the EPS encoder The EPS encoder wasn't part of Gohlke's test suite, so the previous "fixes" there were only expected syntactic ones. This gives a cleaner fix to the encoder. The decoder doesn't work in round-trip due to a missing eps_decoder method on the core module, but it's clear it worked at some point. --- PIL/EpsImagePlugin.py | 66 +++++++++++++++++++++++++---------------- Tests/test_imagefile.py | 1 + 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/PIL/EpsImagePlugin.py b/PIL/EpsImagePlugin.py index b1df67fd6..9d30bc40f 100644 --- a/PIL/EpsImagePlugin.py +++ b/PIL/EpsImagePlugin.py @@ -21,6 +21,7 @@ __version__ = "0.5" import re +import io from . import Image, ImageFile, _binary # @@ -90,6 +91,8 @@ class PSFile: def seek(self, offset, whence=0): self.char = None self.fp.seek(offset, whence) + def read(self, count): + return self.fp.read(count).decode('latin-1') def tell(self): pos = self.fp.tell() if self.char: @@ -109,7 +112,7 @@ class PSFile: self.char = self.fp.read(1) if self.char == b"\n": self.char = None - return s + b"\n" + return s.decode('latin-1') + "\n" def _accept(prefix): @@ -193,13 +196,14 @@ class EpsImageFile(ImageFile.ImageFile): if m: k = m.group(1) + if k == "EndComments": break if k[:8] == "PS-Adobe": self.info[k[:8]] = k[9:] else: self.info[k] = "" - elif s[0] == '%': + elif s[0:1] == '%': # handle non-DSC Postscript comments that some # tools mistakenly put in the Comments section pass @@ -228,7 +232,7 @@ class EpsImageFile(ImageFile.ImageFile): if s[:11] == "%ImageData:": [x, y, bi, mo, z3, z4, en, id] =\ - s[11:].split(maxsplit=7) + s[11:].split(None, 7) x = int(x); y = int(y) @@ -299,42 +303,54 @@ def _save(im, fp, filename, eps=1): # # determine postscript image mode if im.mode == "L": - operator = (8, 1, b"image") + operator = (8, 1, "image") elif im.mode == "RGB": - operator = (8, 3, b"false 3 colorimage") + operator = (8, 3, "false 3 colorimage") elif im.mode == "CMYK": - operator = (8, 4, b"false 4 colorimage") + operator = (8, 4, "false 4 colorimage") else: raise ValueError("image mode is not supported") + class NoCloseStream: + def __init__(self, fp): + self.fp = fp + def __getattr__(self, name): + return getattr(self.fp, name) + def close(self): + pass + + base_fp = fp + fp = io.TextIOWrapper(NoCloseStream(fp), encoding='latin-1') + if eps: # # write EPS header - fp.write(b"%!PS-Adobe-3.0 EPSF-3.0\n") - fp.write(b"%%Creator: PIL 0.1 EpsEncode\n") + fp.write("%!PS-Adobe-3.0 EPSF-3.0\n") + fp.write("%%Creator: PIL 0.1 EpsEncode\n") #fp.write("%%CreationDate: %s"...) - fp.write(("%%%%BoundingBox: 0 0 %d %d\n" % im.size).encode('ascii')) - fp.write(b"%%Pages: 1\n") - fp.write(b"%%EndComments\n") - fp.write(b"%%Page: 1 1\n") - fp.write(("%%ImageData: %d %d " % im.size).encode('ascii')) - fp.write(("%d %d 0 1 1 \"%s\"\n" % operator).encode('ascii')) + fp.write("%%%%BoundingBox: 0 0 %d %d\n" % im.size) + fp.write("%%Pages: 1\n") + fp.write("%%EndComments\n") + fp.write("%%Page: 1 1\n") + fp.write("%%ImageData: %d %d " % im.size) + fp.write("%d %d 0 1 1 \"%s\"\n" % operator) # # image header - fp.write(b"gsave\n") - fp.write(b"10 dict begin\n") - fp.write(("/buf %d string def\n" % (im.size[0] * operator[1])).encode('ascii')) - fp.write(("%d %d scale\n" % im.size).encode('ascii')) - fp.write(("%d %d 8\n" % im.size).encode('ascii')) # <= bits - fp.write(("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1])).encode('ascii')) - fp.write(b"{ currentfile buf readhexstring pop } bind\n") - fp.write(operator[2] + b"\n") + fp.write("gsave\n") + fp.write("10 dict begin\n") + fp.write("/buf %d string def\n" % (im.size[0] * operator[1])) + fp.write("%d %d scale\n" % im.size) + fp.write("%d %d 8\n" % im.size) # <= bits + fp.write("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1])) + fp.write("{ currentfile buf readhexstring pop } bind\n") + fp.write(operator[2] + "\n") + fp.flush() - ImageFile._save(im, fp, [("eps", (0,0)+im.size, 0, None)]) + ImageFile._save(im, base_fp, [("eps", (0,0)+im.size, 0, None)]) - fp.write(b"\n%%%%EndBinary\n") - fp.write(b"grestore end\n") + fp.write("\n%%%%EndBinary\n") + fp.write("grestore end\n") fp.flush() # diff --git a/Tests/test_imagefile.py b/Tests/test_imagefile.py index 4b8c84299..485208c36 100644 --- a/Tests/test_imagefile.py +++ b/Tests/test_imagefile.py @@ -40,6 +40,7 @@ def test_parser(): assert_image_equal(*roundtrip("PPM")) assert_image_equal(*roundtrip("TIFF")) assert_image_equal(*roundtrip("XBM")) + #assert_image_equal(*roundtrip("EPS")) #no eps_decoder assert_image_equal(*roundtrip("TGA")) im1, im2 = roundtrip("JPEG") # lossy compression