JpegImagePlugin sets bufsize for optimized images

This commit is contained in:
wiredfool 2013-03-22 22:27:12 -07:00
parent 5aeb7b584b
commit 2a743c9527
3 changed files with 22 additions and 3 deletions

View File

@ -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()

View File

@ -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.

View File

@ -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)