From 2a743c95279142af58cdf8ce16b0b8d35bede2e8 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Fri, 22 Mar 2013 22:27:12 -0700 Subject: [PATCH] JpegImagePlugin sets bufsize for optimized images --- PIL/ImageFile.py | 8 ++++++-- PIL/JpegImagePlugin.py | 10 +++++++++- Tests/test_file_jpeg.py | 7 +++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/PIL/ImageFile.py b/PIL/ImageFile.py index 2b4eeb7b4..b08f14b90 100644 --- a/PIL/ImageFile.py +++ b/PIL/ImageFile.py @@ -433,8 +433,9 @@ class Parser: # @param im Image object. # @param fp File object. # @param tile Tile list. +# @param bufsize Optional buffer size -def _save(im, fp, tile): +def _save(im, fp, tile, bufsize=0): "Helper to save image based on tile list" im.load() @@ -442,7 +443,10 @@ def _save(im, fp, tile): im.encoderconfig = () tile.sort(key=_tilesort) # FIXME: make MAXBLOCK a configuration parameter - bufsize = max(MAXBLOCK, im.size[0] * 4) # see RawEncode.c + # It would be great if we could have the encoder specifiy what it needs + # But, it would need at least the image size in most cases. RawEncode is + # a tricky case. + bufsize = max(MAXBLOCK, bufsize, im.size[0] * 4) # see RawEncode.c try: fh = fp.fileno() fp.flush() diff --git a/PIL/JpegImagePlugin.py b/PIL/JpegImagePlugin.py index 6df8b926c..a9bb120b9 100644 --- a/PIL/JpegImagePlugin.py +++ b/PIL/JpegImagePlugin.py @@ -554,7 +554,15 @@ def _save(im, fp, filename): info.get("exif", b"") ) - ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)]) + # if we optimize, libjpeg needs a buffer big enough to hold the whole image in a shot. + # Guessing on the size, at im.size bytes. (raw pizel size is channels*size, this + # is a value that's been used in a django patch. + # https://github.com/jdriscoll/django-imagekit/issues/50 + bufsize=0 + if "optimize" in info: + bufsize = im.size[0]*im.size[1] + + ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)], bufsize) def _save_cjpeg(im, fp, filename): # ALTERNATIVE: handle JPEGs via the IJG command line utilities. diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index 011405501..556786aa7 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -113,6 +113,13 @@ def test_optimize(): assert_image_equal(im1, im2) assert_true(im1.bytes >= im2.bytes) +def test_optimize_large_buffer(): + #https://github.com/python-imaging/Pillow/issues/148 + f = tempfile('temp.jpg') + # this requires ~ 1.5x Image.MAXBLOCK + im = Image.new("RGB", (4096,4096), 0xff3333) + im.save(f, format="JPEG", optimize=True) + def test_progressive(): im1 = roundtrip(lena()) im2 = roundtrip(lena(), progressive=1)