mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-12 02:06:18 +03:00
Code to ensure buffer space for exif write and jpeg_write_scanline calls, tests, corrected buffer length calculation
This commit is contained in:
parent
11ce826121
commit
37359369ce
|
@ -554,6 +554,7 @@ def _save(im, fp, filename):
|
|||
info.get("exif", b"")
|
||||
)
|
||||
|
||||
|
||||
# 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.
|
||||
|
@ -562,9 +563,9 @@ def _save(im, fp, filename):
|
|||
if "optimize" in info:
|
||||
bufsize = im.size[0]*im.size[1]
|
||||
|
||||
# The exif info needs to be written as one block. Ensure that our buffer is big enough
|
||||
if len(info.get("exif",b"")) > max(ImageFile.MAXBLOCK, bufsize):
|
||||
bufsize = 2*len(info.get("exif",b""))
|
||||
# The exif info needs to be written as one block, + APP1, + one spare byte.
|
||||
# Ensure that our buffer is big enough
|
||||
bufsize = max(ImageFile.MAXBLOCK, bufsize, len(info.get("exif",b"")) + 5 )
|
||||
|
||||
ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)], bufsize)
|
||||
|
||||
|
|
|
@ -120,6 +120,12 @@ def test_optimize_large_buffer():
|
|||
im = Image.new("RGB", (4096,4096), 0xff3333)
|
||||
im.save(f, format="JPEG", optimize=True)
|
||||
|
||||
def test_large_exif():
|
||||
#https://github.com/python-imaging/Pillow/issues/148
|
||||
f = tempfile('temp.jpg')
|
||||
im = lena()
|
||||
im.save(f,'JPEG', quality=90, exif=b"1"*65532)
|
||||
|
||||
def test_progressive():
|
||||
im1 = roundtrip(lena())
|
||||
im2 = roundtrip(lena(), progressive=1)
|
||||
|
|
|
@ -219,24 +219,29 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
|||
jpeg_start_compress(&context->cinfo, FALSE);
|
||||
/* suppress extra section */
|
||||
context->extra_offset = context->extra_size;
|
||||
//add exif header
|
||||
if (context->rawExifLen > 0)
|
||||
jpeg_write_marker(&context->cinfo, JPEG_APP0+1, (unsigned char*)context->rawExif, context->rawExifLen);
|
||||
|
||||
break;
|
||||
default:
|
||||
/* interchange stream */
|
||||
jpeg_start_compress(&context->cinfo, TRUE);
|
||||
//add exif header
|
||||
if (context->rawExifLen > 0)
|
||||
jpeg_write_marker(&context->cinfo, JPEG_APP0+1, (unsigned char*)context->rawExif, context->rawExifLen);
|
||||
|
||||
break;
|
||||
}
|
||||
state->state++;
|
||||
/* fall through */
|
||||
|
||||
case 2:
|
||||
// check for exif len + 'APP1' header bytes
|
||||
if (context->rawExifLen + 5 > context->destination.pub.free_in_buffer){
|
||||
break;
|
||||
}
|
||||
//add exif header
|
||||
if (context->rawExifLen > 0){
|
||||
jpeg_write_marker(&context->cinfo, JPEG_APP0+1,
|
||||
(unsigned char*)context->rawExif, context->rawExifLen);
|
||||
}
|
||||
|
||||
state->state++;
|
||||
/* fall through */
|
||||
case 3:
|
||||
|
||||
if (context->extra) {
|
||||
/* copy extra buffer to output buffer */
|
||||
|
@ -255,7 +260,10 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
|||
} else
|
||||
state->state++;
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
if (1024 > context->destination.pub.free_in_buffer){
|
||||
break;
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
while (state->y < state->ysize) {
|
||||
|
@ -273,7 +281,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
|||
state->state++;
|
||||
/* fall through */
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
|
||||
/* Finish compression */
|
||||
if (context->destination.pub.free_in_buffer < 100)
|
||||
|
|
Loading…
Reference in New Issue
Block a user