From 22a370afc219af47907b2fe69e791854dd2d9c79 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sat, 10 May 2014 11:46:53 +0300 Subject: [PATCH 01/12] Fix 12-year-old FIXME --- PIL/Image.py | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/PIL/Image.py b/PIL/Image.py index 333397701..7736a3718 100644 --- a/PIL/Image.py +++ b/PIL/Image.py @@ -101,7 +101,7 @@ import collections import numbers # works everywhere, win for pypy, not cpython -USE_CFFI_ACCESS = hasattr(sys, 'pypy_version_info') +USE_CFFI_ACCESS = hasattr(sys, 'pypy_version_info') try: import cffi HAS_CFFI=True @@ -233,7 +233,7 @@ _MODE_CONV = { "CMYK": ('|u1', 4), "YCbCr": ('|u1', 3), "LAB": ('|u1', 3), # UNDONE - unsigned |u1i1i1 - # I;16 == I;16L, and I;32 == I;32L + # I;16 == I;16L, and I;32 == I;32L "I;16": ('u2', None), "I;16L": (' 8bit images. + # a gamma function point transform on > 8bit images. scale, offset = _getscaleoffset(lut) return self._new(self.im.point_transform(scale, offset)) # for other modes, convert the function to a table @@ -1420,8 +1420,8 @@ class Image: self._copy() self.pyaccess = None self.load() - - if self.pyaccess: + + if self.pyaccess: return self.pyaccess.putpixel(xy,value) return self.im.putpixel(xy, value) @@ -1667,7 +1667,7 @@ class Image: """ return 0 - def thumbnail(self, size, resample=NEAREST): + def thumbnail(self, size, resample=ANTIALIAS): """ Make this image into a thumbnail. This method modifies the image to contain a thumbnail version of itself, no larger than @@ -1690,14 +1690,10 @@ class Image: of :py:attr:`PIL.Image.NEAREST`, :py:attr:`PIL.Image.BILINEAR`, :py:attr:`PIL.Image.BICUBIC`, or :py:attr:`PIL.Image.ANTIALIAS` (best quality). If omitted, it defaults to - :py:attr:`PIL.Image.NEAREST` (this will be changed to ANTIALIAS in a - future version). + :py:attr:`PIL.Image.ANTIALIAS`. :returns: None """ - # FIXME: the default resampling filter will be changed - # to ANTIALIAS in future versions - # preserve aspect ratio x, y = self.size if x > size[0]: y = int(max(y * size[0] / x, 1)); x = int(size[0]) From 74514fa1f54d82194d9cb2388f6383b6d8ca8df1 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sat, 10 May 2014 12:34:36 +0300 Subject: [PATCH 02/12] Some pep8 and pyflakes cleanup --- PIL/Image.py | 152 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 94 insertions(+), 58 deletions(-) diff --git a/PIL/Image.py b/PIL/Image.py index 7736a3718..80b7258c6 100644 --- a/PIL/Image.py +++ b/PIL/Image.py @@ -30,6 +30,7 @@ from PIL import VERSION, PILLOW_VERSION, _plugins import warnings + class _imaging_not_installed: # module placeholder def __getattr__(self, id): @@ -52,7 +53,7 @@ try: # directly; import Image and use the Image.core variable instead. from PIL import _imaging as core if PILLOW_VERSION != getattr(core, 'PILLOW_VERSION', None): - raise ImportError("The _imaging extension was built for another " + raise ImportError("The _imaging extension was built for another " " version of Pillow or PIL") except ImportError as v: @@ -91,10 +92,13 @@ except ImportError: builtins = __builtin__ from PIL import ImageMode -from PIL._binary import i8, o8 -from PIL._util import isPath, isStringType, deferred_error +from PIL._binary import i8 +from PIL._util import isPath +from PIL._util import isStringType +from PIL._util import deferred_error -import os, sys +import os +import sys # type stuff import collections @@ -104,9 +108,10 @@ import numbers USE_CFFI_ACCESS = hasattr(sys, 'pypy_version_info') try: import cffi - HAS_CFFI=True + HAS_CFFI = True except: - HAS_CFFI=False + HAS_CFFI = False + def isImageType(t): """ @@ -148,16 +153,16 @@ MESH = 4 # resampling filters NONE = 0 NEAREST = 0 -ANTIALIAS = 1 # 3-lobed lanczos +ANTIALIAS = 1 # 3-lobed lanczos LINEAR = BILINEAR = 2 CUBIC = BICUBIC = 3 # dithers NONE = 0 NEAREST = 0 -ORDERED = 1 # Not yet implemented -RASTERIZE = 2 # Not yet implemented -FLOYDSTEINBERG = 3 # default +ORDERED = 1 # Not yet implemented +RASTERIZE = 2 # Not yet implemented +FLOYDSTEINBERG = 3 # default # palettes/quantizers WEB = 0 @@ -222,7 +227,7 @@ else: _MODE_CONV = { # official modes - "1": ('|b1', None), # broken + "1": ('|b1', None), # broken "L": ('|u1', None), "I": (_ENDIAN + 'i4', None), "F": (_ENDIAN + 'f4', None), @@ -232,8 +237,8 @@ _MODE_CONV = { "RGBA": ('|u1', 4), "CMYK": ('|u1', 4), "YCbCr": ('|u1', 3), - "LAB": ('|u1', 3), # UNDONE - unsigned |u1i1i1 - # I;16 == I;16L, and I;32 == I;32L + "LAB": ('|u1', 3), # UNDONE - unsigned |u1i1i1 + # I;16 == I;16L, and I;32 == I;32L "I;16": ('u2', None), "I;16L": (' size[0]: y = int(max(y * size[0] / x, 1)); x = int(size[0]) - if y > size[1]: x = int(max(x * size[1] / y, 1)); y = int(size[1]) + if x > size[0]: + y = int(max(y * size[0] / x, 1)) + x = int(size[0]) + if y > size[1]: + x = int(max(x * size[1] / y, 1)) + y = int(size[1]) size = x, y if size == self.size: @@ -1712,7 +1733,7 @@ class Image: except ValueError: if resample != ANTIALIAS: raise - im = self.resize(size, NEAREST) # fallback + im = self.resize(size, NEAREST) # fallback self.im = im.im self.mode = im.mode @@ -1748,7 +1769,9 @@ class Image: """ if self.mode == 'RGBA': - return self.convert('RGBa').transform(size, method, data, resample, fill).convert('RGBA') + return self.convert('RGBa') \ + .transform(size, method, data, resample, fill) \ + .convert('RGBA') if isinstance(method, ImageTransformHandler): return method.transform(size, self, resample=resample, fill=fill) @@ -1795,8 +1818,13 @@ class Image: elif method == QUAD: # quadrilateral warp. data specifies the four corners # given as NW, SW, SE, and NE. - nw = data[0:2]; sw = data[2:4]; se = data[4:6]; ne = data[6:8] - x0, y0 = nw; As = 1.0 / w; At = 1.0 / h + nw = data[0:2] + sw = data[2:4] + se = data[4:6] + ne = data[6:8] + x0, y0 = nw + As = 1.0 / w + At = 1.0 / h data = (x0, (ne[0]-x0)*As, (sw[0]-x0)*At, (se[0]-sw[0]-ne[0]+x0)*As*At, y0, (ne[1]-y0)*As, (sw[1]-y0)*At, @@ -1830,6 +1858,7 @@ class Image: im = self.im.transpose(method) return self._new(im) + # -------------------------------------------------------------------- # Lazy operations @@ -1865,6 +1894,7 @@ class _ImageCrop(Image): # FIXME: future versions should optimize crop/paste # sequences! + # -------------------------------------------------------------------- # Abstract handlers. @@ -1872,10 +1902,12 @@ class ImagePointHandler: # used as a mixin by point transforms (for use with im.point) pass + class ImageTransformHandler: # used as a mixin by geometry transforms (for use with im.transform) pass + # -------------------------------------------------------------------- # Factories @@ -1951,6 +1983,7 @@ def frombytes(mode, size, data, decoder_name="raw", *args): im.frombytes(data, decoder_name, args) return im + def fromstring(*args, **kw): """Deprecated alias to frombytes. @@ -2013,9 +2046,9 @@ def frombuffer(mode, size, data, decoder_name="raw", *args): " frombuffer(mode, size, data, 'raw', mode, 0, 1)", RuntimeWarning, stacklevel=2 ) - args = mode, 0, -1 # may change to (mode, 0, 1) post-1.1.6 + args = mode, 0, -1 # may change to (mode, 0, 1) post-1.1.6 if args[0] in _MAPMODES: - im = new(mode, (1,1)) + im = new(mode, (1, 1)) im = im._new( core.map_buffer(data, size, decoder_name, None, 0, args) ) @@ -2135,8 +2168,8 @@ def open(fp, mode="r"): fp.seek(0) return factory(fp, filename) except (SyntaxError, IndexError, TypeError): - #import traceback - #traceback.print_exc() + # import traceback + # traceback.print_exc() pass if init(): @@ -2148,13 +2181,14 @@ def open(fp, mode="r"): fp.seek(0) return factory(fp, filename) except (SyntaxError, IndexError, TypeError): - #import traceback - #traceback.print_exc() + # import traceback + # traceback.print_exc() pass raise IOError("cannot identify image file %r" % (filename if filename else fp)) + # # Image processing. @@ -2253,6 +2287,7 @@ def merge(mode, bands): im.putband(bands[i].im, i) return bands[0]._new(im) + # -------------------------------------------------------------------- # Plugin registry @@ -2311,6 +2346,7 @@ def _show(image, **options): # override me, as necessary _showxv(image, **options) + def _showxv(image, title=None, **options): from PIL import ImageShow ImageShow.show(image, title, **options) From f165d2034fc97f172034cadf8c4b3aa3670ae1f3 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sun, 11 May 2014 09:01:09 +0300 Subject: [PATCH 03/12] Simple test for saving to PDF --- Tests/test_file_pdf.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Tests/test_file_pdf.py diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py new file mode 100644 index 000000000..7519d270f --- /dev/null +++ b/Tests/test_file_pdf.py @@ -0,0 +1,17 @@ +from tester import * +import os.path + + +def test_to_pdf(): + # Arrange + im = lena() + outfile = tempfile("temp.pdf") + + # Act + im.save(outfile) + + # Assert + assert_true(os.path.isfile(outfile)) + assert_greater(os.path.getsize(outfile), 0) + +# End of file From c15601e0b06f5d6ebf28a0f9d6a9721fa54ed235 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sun, 11 May 2014 17:16:13 +0300 Subject: [PATCH 04/12] Add some more pdf tests --- Tests/test_file_pdf.py | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py index 7519d270f..c9ab8015a 100644 --- a/Tests/test_file_pdf.py +++ b/Tests/test_file_pdf.py @@ -2,10 +2,10 @@ from tester import * import os.path -def test_to_pdf(): +def helper_save_as_pdf(mode): # Arrange - im = lena() - outfile = tempfile("temp.pdf") + im = lena(mode) + outfile = tempfile("temp_" + mode + ".pdf") # Act im.save(outfile) @@ -14,4 +14,37 @@ def test_to_pdf(): assert_true(os.path.isfile(outfile)) assert_greater(os.path.getsize(outfile), 0) + +def test_greyscale(): + # Arrange + mode = "L" + + # Act / Assert + helper_save_as_pdf(mode) + + +def test_rgb(): + # Arrange + mode = "RGB" + + # Act / Assert + helper_save_as_pdf(mode) + + +def test_p_mode(): + # Arrange + mode = "P" + + # Act / Assert + helper_save_as_pdf(mode) + + +def test_cmyk_mode(): + # Arrange + mode = "P" + + # Act / Assert + helper_save_as_pdf(mode) + + # End of file From 3e2ff13aa8866af18de64a90e52ee8b7772fd907 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sun, 11 May 2014 17:23:10 +0300 Subject: [PATCH 05/12] Fix CMYK test --- Tests/test_file_pdf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py index c9ab8015a..81fd919d2 100644 --- a/Tests/test_file_pdf.py +++ b/Tests/test_file_pdf.py @@ -41,7 +41,7 @@ def test_p_mode(): def test_cmyk_mode(): # Arrange - mode = "P" + mode = "CMYK" # Act / Assert helper_save_as_pdf(mode) From 8f1a00ae92a949da0859114a970c04d8b7194bc4 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sun, 11 May 2014 17:28:41 +0300 Subject: [PATCH 06/12] Temporarily remove failing P-mode PDF test --- Tests/test_file_pdf.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py index 81fd919d2..4bc70d10c 100644 --- a/Tests/test_file_pdf.py +++ b/Tests/test_file_pdf.py @@ -31,12 +31,17 @@ def test_rgb(): helper_save_as_pdf(mode) -def test_p_mode(): - # Arrange - mode = "P" - - # Act / Assert - helper_save_as_pdf(mode) +# FIXME: P-mode test fails on Python 3. +# https://travis-ci.org/hugovk/Pillow/builds/24915249 +# File "/home/travis/build/hugovk/Pillow/PIL/PdfImagePlugin.py", line 108, in _save +# colorspace = colorspace + b"> ]" +# TypeError: Can't convert 'bytes' object to str implicitly +# def test_p_mode(): +# # Arrange +# mode = "P" +# +# # Act / Assert +# helper_save_as_pdf(mode) def test_cmyk_mode(): From 6520004289648e3611d43fab7190751f18912aef Mon Sep 17 00:00:00 2001 From: hugovk Date: Sun, 11 May 2014 17:35:49 +0300 Subject: [PATCH 07/12] Add monochrome PDF test --- Tests/test_file_pdf.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py index 4bc70d10c..ed6b50b5d 100644 --- a/Tests/test_file_pdf.py +++ b/Tests/test_file_pdf.py @@ -15,6 +15,14 @@ def helper_save_as_pdf(mode): assert_greater(os.path.getsize(outfile), 0) +def test_monochrome(): + # Arrange + mode = "1" + + # Act / Assert + helper_save_as_pdf(mode) + + def test_greyscale(): # Arrange mode = "L" @@ -33,9 +41,11 @@ def test_rgb(): # FIXME: P-mode test fails on Python 3. # https://travis-ci.org/hugovk/Pillow/builds/24915249 -# File "/home/travis/build/hugovk/Pillow/PIL/PdfImagePlugin.py", line 108, in _save +# File "/home/travis/build/hugovk/Pillow/PIL/PdfImagePlugin.py", line 108, +# in _save # colorspace = colorspace + b"> ]" # TypeError: Can't convert 'bytes' object to str implicitly + # def test_p_mode(): # # Arrange # mode = "P" From 741297326a030372fd8dfb6dc6e0a2ecc6dba2f8 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sun, 11 May 2014 17:41:07 +0300 Subject: [PATCH 08/12] Temporarily remove 'failing' 1-mode PDF test --- Tests/test_file_pdf.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py index ed6b50b5d..ddecdd75f 100644 --- a/Tests/test_file_pdf.py +++ b/Tests/test_file_pdf.py @@ -15,6 +15,12 @@ def helper_save_as_pdf(mode): assert_greater(os.path.getsize(outfile), 0) +# FIXME: 1-mode test "fails" because it produces a warning. +# https://travis-ci.org/hugovk/Pillow/builds/24916085 +# /home/travis/build/hugovk/Pillow/PIL/PdfImagePlugin.py:147: +# DeprecationWarning: tostring() is deprecated. Please call tobytes() instead. +# data = im.tostring("raw", "1") + def test_monochrome(): # Arrange mode = "1" From bcb8534dcf8ad5e8b10eece136f18062818b7071 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sun, 11 May 2014 17:46:13 +0300 Subject: [PATCH 09/12] Temporarily remove 'failing' 1-mode PDF test --- Tests/test_file_pdf.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py index ddecdd75f..9a4faff3f 100644 --- a/Tests/test_file_pdf.py +++ b/Tests/test_file_pdf.py @@ -20,13 +20,13 @@ def helper_save_as_pdf(mode): # /home/travis/build/hugovk/Pillow/PIL/PdfImagePlugin.py:147: # DeprecationWarning: tostring() is deprecated. Please call tobytes() instead. # data = im.tostring("raw", "1") - -def test_monochrome(): - # Arrange - mode = "1" - - # Act / Assert - helper_save_as_pdf(mode) +# +# def test_monochrome(): +# # Arrange +# mode = "1" +# +# # Act / Assert +# helper_save_as_pdf(mode) def test_greyscale(): @@ -51,7 +51,7 @@ def test_rgb(): # in _save # colorspace = colorspace + b"> ]" # TypeError: Can't convert 'bytes' object to str implicitly - +# # def test_p_mode(): # # Arrange # mode = "P" From c37aa0a9ca0db921e62ae289f7bc357b7a5aef55 Mon Sep 17 00:00:00 2001 From: hugovk Date: Mon, 12 May 2014 14:30:03 +0300 Subject: [PATCH 10/12] Fix tostring()/tobytes() warning and reinstate test --- PIL/PdfImagePlugin.py | 2 +- Tests/test_file_pdf.py | 18 ++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/PIL/PdfImagePlugin.py b/PIL/PdfImagePlugin.py index 725f22ecf..2a8a8d443 100644 --- a/PIL/PdfImagePlugin.py +++ b/PIL/PdfImagePlugin.py @@ -144,7 +144,7 @@ def _save(im, fp, filename): if bits == 1: # FIXME: the hex encoder doesn't support packed 1-bit # images; do things the hard way... - data = im.tostring("raw", "1") + data = im.tobytes("raw", "1") im = Image.new("L", (len(data), 1), None) im.putdata(data) ImageFile._save(im, op, [("hex", (0,0)+im.size, 0, im.mode)]) diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py index 9a4faff3f..e31878aef 100644 --- a/Tests/test_file_pdf.py +++ b/Tests/test_file_pdf.py @@ -15,18 +15,12 @@ def helper_save_as_pdf(mode): assert_greater(os.path.getsize(outfile), 0) -# FIXME: 1-mode test "fails" because it produces a warning. -# https://travis-ci.org/hugovk/Pillow/builds/24916085 -# /home/travis/build/hugovk/Pillow/PIL/PdfImagePlugin.py:147: -# DeprecationWarning: tostring() is deprecated. Please call tobytes() instead. -# data = im.tostring("raw", "1") -# -# def test_monochrome(): -# # Arrange -# mode = "1" -# -# # Act / Assert -# helper_save_as_pdf(mode) +def test_monochrome(): + # Arrange + mode = "1" + + # Act / Assert + helper_save_as_pdf(mode) def test_greyscale(): From 8cda5170c8f1c60f5537b623883ef6a9436f2df6 Mon Sep 17 00:00:00 2001 From: hugovk Date: Mon, 12 May 2014 14:45:54 +0300 Subject: [PATCH 11/12] Fix bytes/str and reinstate test --- PIL/PdfImagePlugin.py | 2 +- Tests/test_file_pdf.py | 19 ++++++------------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/PIL/PdfImagePlugin.py b/PIL/PdfImagePlugin.py index 2a8a8d443..c89ca3ee0 100644 --- a/PIL/PdfImagePlugin.py +++ b/PIL/PdfImagePlugin.py @@ -105,7 +105,7 @@ def _save(im, fp, filename): g = i8(palette[i*3+1]) b = i8(palette[i*3+2]) colorspace = colorspace + "%02x%02x%02x " % (r, g, b) - colorspace = colorspace + b"> ]" + colorspace = colorspace + "> ]" procset = "/ImageI" # indexed color elif im.mode == "RGB": filter = "/DCTDecode" diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py index e31878aef..e99f22db1 100644 --- a/Tests/test_file_pdf.py +++ b/Tests/test_file_pdf.py @@ -39,19 +39,12 @@ def test_rgb(): helper_save_as_pdf(mode) -# FIXME: P-mode test fails on Python 3. -# https://travis-ci.org/hugovk/Pillow/builds/24915249 -# File "/home/travis/build/hugovk/Pillow/PIL/PdfImagePlugin.py", line 108, -# in _save -# colorspace = colorspace + b"> ]" -# TypeError: Can't convert 'bytes' object to str implicitly -# -# def test_p_mode(): -# # Arrange -# mode = "P" -# -# # Act / Assert -# helper_save_as_pdf(mode) +def test_p_mode(): + # Arrange + mode = "P" + + # Act / Assert + helper_save_as_pdf(mode) def test_cmyk_mode(): From 3ff73688fe12373e4a4d1996962bf107b38a5e89 Mon Sep 17 00:00:00 2001 From: hugovk Date: Mon, 12 May 2014 14:56:55 +0300 Subject: [PATCH 12/12] pep8 and pyflakes --- PIL/PdfImagePlugin.py | 76 ++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/PIL/PdfImagePlugin.py b/PIL/PdfImagePlugin.py index c89ca3ee0..fcc841438 100644 --- a/PIL/PdfImagePlugin.py +++ b/PIL/PdfImagePlugin.py @@ -46,9 +46,11 @@ def _obj(fp, obj, **dict): fp.write("/%s %s\n" % (k, v)) fp.write(">>\n") + def _endobj(fp): fp.write("endobj\n") + ## # (Internal) Image save plugin for the PDF format. @@ -59,13 +61,15 @@ def _save(im, fp, filename): # make sure image data is available im.load() - xref = [0]*(5+1) # placeholders + xref = [0]*(5+1) # placeholders class TextWriter: def __init__(self, fp): self.fp = fp + def __getattr__(self, name): return getattr(self.fp, name) + def write(self, value): self.fp.write(value.encode('latin-1')) @@ -89,13 +93,13 @@ def _save(im, fp, filename): if im.mode == "1": filter = "/ASCIIHexDecode" colorspace = "/DeviceGray" - procset = "/ImageB" # grayscale + procset = "/ImageB" # grayscale bits = 1 elif im.mode == "L": filter = "/DCTDecode" # params = "<< /Predictor 15 /Columns %d >>" % (width-2) colorspace = "/DeviceGray" - procset = "/ImageB" # grayscale + procset = "/ImageB" # grayscale elif im.mode == "P": filter = "/ASCIIHexDecode" colorspace = "[ /Indexed /DeviceRGB 255 <" @@ -106,15 +110,15 @@ def _save(im, fp, filename): b = i8(palette[i*3+2]) colorspace = colorspace + "%02x%02x%02x " % (r, g, b) colorspace = colorspace + "> ]" - procset = "/ImageI" # indexed color + procset = "/ImageI" # indexed color elif im.mode == "RGB": filter = "/DCTDecode" colorspace = "/DeviceRGB" - procset = "/ImageC" # color images + procset = "/ImageC" # color images elif im.mode == "CMYK": filter = "/DCTDecode" colorspace = "/DeviceCMYK" - procset = "/ImageC" # color images + procset = "/ImageC" # color images else: raise ValueError("cannot save mode %s" % im.mode) @@ -122,17 +126,21 @@ def _save(im, fp, filename): # catalogue xref[1] = fp.tell() - _obj(fp, 1, Type = "/Catalog", - Pages = "2 0 R") + _obj( + fp, 1, + Type="/Catalog", + Pages="2 0 R") _endobj(fp) # # pages xref[2] = fp.tell() - _obj(fp, 2, Type = "/Pages", - Count = 1, - Kids = "[4 0 R]") + _obj( + fp, 2, + Type="/Pages", + Count=1, + Kids="[4 0 R]") _endobj(fp) # @@ -147,26 +155,28 @@ def _save(im, fp, filename): data = im.tobytes("raw", "1") im = Image.new("L", (len(data), 1), None) im.putdata(data) - ImageFile._save(im, op, [("hex", (0,0)+im.size, 0, im.mode)]) + ImageFile._save(im, op, [("hex", (0, 0)+im.size, 0, im.mode)]) elif filter == "/DCTDecode": Image.SAVE["JPEG"](im, op, filename) elif filter == "/FlateDecode": - ImageFile._save(im, op, [("zip", (0,0)+im.size, 0, im.mode)]) + ImageFile._save(im, op, [("zip", (0, 0)+im.size, 0, im.mode)]) elif filter == "/RunLengthDecode": - ImageFile._save(im, op, [("packbits", (0,0)+im.size, 0, im.mode)]) + ImageFile._save(im, op, [("packbits", (0, 0)+im.size, 0, im.mode)]) else: raise ValueError("unsupported PDF filter (%s)" % filter) xref[3] = fp.tell() - _obj(fp, 3, Type = "/XObject", - Subtype = "/Image", - Width = width, # * 72.0 / resolution, - Height = height, # * 72.0 / resolution, - Length = len(op.getvalue()), - Filter = filter, - BitsPerComponent = bits, - DecodeParams = params, - ColorSpace = colorspace) + _obj( + fp, 3, + Type="/XObject", + Subtype="/Image", + Width=width, # * 72.0 / resolution, + Height=height, # * 72.0 / resolution, + Length=len(op.getvalue()), + Filter=filter, + BitsPerComponent=bits, + DecodeParams=params, + ColorSpace=colorspace) fp.write("stream\n") fp.fp.write(op.getvalue()) @@ -179,11 +189,14 @@ def _save(im, fp, filename): xref[4] = fp.tell() _obj(fp, 4) - fp.write("<<\n/Type /Page\n/Parent 2 0 R\n"\ - "/Resources <<\n/ProcSet [ /PDF %s ]\n"\ - "/XObject << /image 3 0 R >>\n>>\n"\ - "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\ - (procset, int(width * 72.0 /resolution) , int(height * 72.0 / resolution))) + fp.write( + "<<\n/Type /Page\n/Parent 2 0 R\n" + "/Resources <<\n/ProcSet [ /PDF %s ]\n" + "/XObject << /image 3 0 R >>\n>>\n" + "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" % ( + procset, + int(width * 72.0 / resolution), + int(height * 72.0 / resolution))) _endobj(fp) # @@ -191,10 +204,13 @@ def _save(im, fp, filename): op = TextWriter(io.BytesIO()) - op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (int(width * 72.0 / resolution), int(height * 72.0 / resolution))) + op.write( + "q %d 0 0 %d 0 0 cm /image Do Q\n" % ( + int(width * 72.0 / resolution), + int(height * 72.0 / resolution))) xref[5] = fp.tell() - _obj(fp, 5, Length = len(op.fp.getvalue())) + _obj(fp, 5, Length=len(op.fp.getvalue())) fp.write("stream\n") fp.fp.write(op.fp.getvalue())