This commit is contained in:
Jon Dufresne 2017-12-19 18:51:33 +00:00 committed by GitHub
commit 46309e913f
65 changed files with 91 additions and 138 deletions

View File

@ -8,7 +8,7 @@
Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive. Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.
The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as plone, Django, or buildout, try to replicate the issue just using Pillow. The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as plone, Django, or buildout, try to replicate the issue just using Pillow.
```python ```python
code goes here code goes here

1
.gitignore vendored
View File

@ -68,4 +68,3 @@ docs/_build/
#OS #OS
.DS_Store .DS_Store

View File

@ -32,4 +32,3 @@ pushd depends && ./install_imagequant.sh && popd
# extra test images # extra test images
pushd depends && ./install_extra_test_images.sh && popd pushd depends && ./install_extra_test_images.sh && popd

View File

@ -1,4 +1,3 @@
Changelog (Pillow) Changelog (Pillow)
================== ==================

View File

@ -1,4 +1,3 @@
include *.c include *.c
include *.h include *.h
include *.in include *.in

View File

@ -42,7 +42,7 @@ class DcxImageFile(PcxImageFile):
format = "DCX" format = "DCX"
format_description = "Intel DCX" format_description = "Intel DCX"
_close_exclusive_fp_after_loading = False _close_exclusive_fp_after_loading = False
def _open(self): def _open(self):
# Header # Header

View File

@ -2100,7 +2100,7 @@ class Image(object):
in the output image. in the output image.
:returns: An :py:class:`~PIL.Image.Image` object. :returns: An :py:class:`~PIL.Image.Image` object.
""" """
if self.mode == 'LA': if self.mode == 'LA':
return self.convert('La').transform( return self.convert('La').transform(
size, method, data, resample, fill).convert('LA') size, method, data, resample, fill).convert('LA')

View File

@ -278,7 +278,7 @@ class BitmapImage(object):
def getimage(photo): def getimage(photo):
""" This function is unimplemented """ """ This function is unimplemented """
"""Copies the contents of a PhotoImage to a PIL image memory.""" """Copies the contents of a PhotoImage to a PIL image memory."""
photo.tk.call("PyImagingPhotoGet", photo) photo.tk.call("PyImagingPhotoGet", photo)

View File

@ -40,7 +40,7 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
format = "MPO" format = "MPO"
format_description = "MPO (CIPA DC-007)" format_description = "MPO (CIPA DC-007)"
_close_exclusive_fp_after_loading = False _close_exclusive_fp_after_loading = False
def _open(self): def _open(self):
self.fp.seek(0) # prep the fp in order to pass the JPEG test self.fp.seek(0) # prep the fp in order to pass the JPEG test
JpegImagePlugin.JpegImageFile._open(self) JpegImagePlugin.JpegImageFile._open(self)

View File

@ -143,7 +143,7 @@ TAGS_V2 = {
342: ("TransferRange", SHORT, 6), 342: ("TransferRange", SHORT, 6),
347: ("JPEGTables", UNDEFINED, 1), 347: ("JPEGTables", UNDEFINED, 1),
# obsolete JPEG tags # obsolete JPEG tags
512: ("JPEGProc", SHORT, 1), 512: ("JPEGProc", SHORT, 1),
513: ("JPEGInterchangeFormat", LONG, 1), 513: ("JPEGInterchangeFormat", LONG, 1),
@ -161,7 +161,7 @@ TAGS_V2 = {
532: ("ReferenceBlackWhite", LONG, 0), 532: ("ReferenceBlackWhite", LONG, 0),
700: ('XMP', BYTE, 1), 700: ('XMP', BYTE, 1),
33432: ("Copyright", ASCII, 1), 33432: ("Copyright", ASCII, 1),
34377: ('PhotoshopInfo', BYTE, 1), 34377: ('PhotoshopInfo', BYTE, 1),
@ -193,7 +193,7 @@ TAGS_V2 = {
50741: ("MakerNoteSafety", SHORT, 1, {"Unsafe": 0, "Safe": 1}), 50741: ("MakerNoteSafety", SHORT, 1, {"Unsafe": 0, "Safe": 1}),
50780: ("BestQualityScale", RATIONAL, 1), 50780: ("BestQualityScale", RATIONAL, 1),
50838: ("ImageJMetaDataByteCounts", LONG, 0), # Can be more than one 50838: ("ImageJMetaDataByteCounts", LONG, 0), # Can be more than one
50839: ("ImageJMetaData", UNDEFINED, 1) # see Issue #2006 50839: ("ImageJMetaData", UNDEFINED, 1) # see Issue #2006
} }

View File

@ -76,4 +76,3 @@ def get_supported():
ret.extend(get_supported_features()) ret.extend(get_supported_features())
ret.extend(get_supported_codecs()) ret.extend(get_supported_codecs())
return ret return ret

View File

@ -39,6 +39,3 @@ To run an individual test::
Run all the tests from the root of the Pillow source distribution:: Run all the tests from the root of the Pillow source distribution::
./test-installed.py ./test-installed.py

View File

@ -100,7 +100,7 @@ class PillowTestCase(unittest.TestCase):
logger.error("Url for test images: %s" %url) logger.error("Url for test images: %s" %url)
except: except:
pass pass
self.fail(msg or "got different content") self.fail(msg or "got different content")
def assert_image_similar(self, a, b, epsilon, msg=None): def assert_image_similar(self, a, b, epsilon, msg=None):
@ -206,7 +206,7 @@ class PillowLeakTestCase(PillowTestCase):
# requires unix/osx # requires unix/osx
iterations = 100 # count iterations = 100 # count
mem_limit = 512 # k mem_limit = 512 # k
def _get_mem_usage(self): def _get_mem_usage(self):
""" """
Gets the RUSAGE memory usage, returns in K. Encapsulates the difference Gets the RUSAGE memory usage, returns in K. Encapsulates the difference
@ -214,7 +214,7 @@ class PillowLeakTestCase(PillowTestCase):
:returns; memory usage in kilobytes :returns; memory usage in kilobytes
""" """
from resource import getpagesize, getrusage, RUSAGE_SELF from resource import getpagesize, getrusage, RUSAGE_SELF
mem = getrusage(RUSAGE_SELF).ru_maxrss mem = getrusage(RUSAGE_SELF).ru_maxrss
if sys.platform == 'darwin': if sys.platform == 'darwin':
@ -225,7 +225,7 @@ class PillowLeakTestCase(PillowTestCase):
# linux # linux
# man 2 getrusage # man 2 getrusage
# ru_maxrss (since Linux 2.6.32) # ru_maxrss (since Linux 2.6.32)
# This is the maximum resident set size used (in kilobytes). # This is the maximum resident set size used (in kilobytes).
return mem # Kb return mem # Kb
def _test_leak(self, core): def _test_leak(self, core):

View File

@ -22,4 +22,3 @@ and that the name of ICC shall not be used in advertising or publicity
pertaining to distribution of the software without specific, written pertaining to distribution of the software without specific, written
prior permission. ICC makes no representations about the suitability prior permission. ICC makes no representations about the suitability
of this software for any purpose. of this software for any purpose.

View File

@ -80,7 +80,7 @@ class TestFileSgi(PillowTestCase):
reloaded = Image.open(out) reloaded = Image.open(out)
self.assert_image_equal(im, reloaded) self.assert_image_equal(im, reloaded)
def test_unsupported_mode(self): def test_unsupported_mode(self):
im = hopper('LA') im = hopper('LA')
out = self.tempfile('temp.sgi') out = self.tempfile('temp.sgi')

View File

@ -70,7 +70,7 @@ class TestFileTiffMetadata(PillowTestCase):
self.assertAlmostEqual(loaded_double, doubledata) self.assertAlmostEqual(loaded_double, doubledata)
# check with 2 element ImageJMetaDataByteCounts, issue #2006 # check with 2 element ImageJMetaDataByteCounts, issue #2006
info[ImageJMetaDataByteCounts] = (8, len(bindata) - 8) info[ImageJMetaDataByteCounts] = (8, len(bindata) - 8)
img.save(f, tiffinfo=info) img.save(f, tiffinfo=info)
loaded = Image.open(f) loaded = Image.open(f)

View File

@ -14,7 +14,7 @@ class TestTTypeFontLeak(PillowLeakTestCase):
draw = ImageDraw.ImageDraw(im) draw = ImageDraw.ImageDraw(im)
self._test_leak(lambda: draw.text((0, 0), "some text "*1024, #~10k self._test_leak(lambda: draw.text((0, 0), "some text "*1024, #~10k
font=font, fill="black")) font=font, fill="black"))
@unittest.skipIf(not features.check('freetype2'), "Test requires freetype2") @unittest.skipIf(not features.check('freetype2'), "Test requires freetype2")
def test_leak(self): def test_leak(self):
ttype = ImageFont.truetype('Tests/fonts/FreeMono.ttf', 20) ttype = ImageFont.truetype('Tests/fonts/FreeMono.ttf', 20)
@ -24,7 +24,7 @@ class TestDefaultFontLeak(TestTTypeFontLeak):
# fails at iteration 37 in master # fails at iteration 37 in master
iterations = 100 iterations = 100
mem_limit = 1024 #k mem_limit = 1024 #k
def test_leak(self): def test_leak(self):
default_font = ImageFont.load_default() default_font = ImageFont.load_default()
self._test_font(default_font) self._test_font(default_font)

View File

@ -51,7 +51,7 @@ class TestFontPcf(PillowTestCase):
draw.text((0, 0), message, 'black', font=font) draw.text((0, 0), message, 'black', font=font)
with Image.open('Tests/images/test_draw_pbm_target.png') as target: with Image.open('Tests/images/test_draw_pbm_target.png') as target:
self.assert_image_similar(im, target, 0) self.assert_image_similar(im, target, 0)
def test_textsize(self): def test_textsize(self):
tempname = self.save_font() tempname = self.save_font()
font = ImageFont.load(tempname) font = ImageFont.load(tempname)

View File

@ -293,7 +293,7 @@ int main(int argc, char* argv[])
compiler = ccompiler.new_compiler() compiler = ccompiler.new_compiler()
compiler.add_include_dir(sysconfig.get_python_inc()) compiler.add_include_dir(sysconfig.get_python_inc())
libdir = sysconfig.get_config_var('LIBDIR') or sysconfig.get_python_inc().replace('include', 'libs') libdir = sysconfig.get_config_var('LIBDIR') or sysconfig.get_python_inc().replace('include', 'libs')
print (libdir) print (libdir)
compiler.add_library_dir(libdir) compiler.add_library_dir(libdir)
@ -302,10 +302,10 @@ int main(int argc, char* argv[])
env = os.environ.copy() env = os.environ.copy()
env["PATH"] = sys.prefix + ';' + env["PATH"] env["PATH"] = sys.prefix + ';' + env["PATH"]
# do not display the Windows Error Reporting dialog # do not display the Windows Error Reporting dialog
ctypes.windll.kernel32.SetErrorMode(0x0002) ctypes.windll.kernel32.SetErrorMode(0x0002)
process = subprocess.Popen(['embed_pil.exe'], env=env) process = subprocess.Popen(['embed_pil.exe'], env=env)
process.communicate() process.communicate()
self.assertEqual(process.returncode, 0) self.assertEqual(process.returncode, 0)

View File

@ -89,7 +89,7 @@ class TestImageConvert(PillowTestCase):
self.assertNotIn('transparency', rgba.info) self.assertNotIn('transparency', rgba.info)
# https://github.com/python-pillow/Pillow/issues/2702 # https://github.com/python-pillow/Pillow/issues/2702
self.assertEqual(rgba.palette, None) self.assertEqual(rgba.palette, None)
def test_trns_l(self): def test_trns_l(self):
im = hopper('L') im = hopper('L')

View File

@ -406,10 +406,10 @@ class TestImageFont(PillowTestCase):
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode='RGB', size=(300, 100))
target = im.copy() target = im.copy()
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
#should not crash here. #should not crash here.
draw.text((10, 10), '', font=font) draw.text((10, 10), '', font=font)
self.assert_image_equal(im, target) self.assert_image_equal(im, target)
def test_unicode_pilfont(self): def test_unicode_pilfont(self):
# should not segfault, should return UnicodeDecodeError # should not segfault, should return UnicodeDecodeError
# issue #2826 # issue #2826

View File

@ -15,8 +15,8 @@ class TestImagecomplextext(PillowTestCase):
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode='RGB', size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'TEST', font=ttf, fill=500, direction='ltr') draw.text((0, 0), 'TEST', font=ttf, fill=500, direction='ltr')
def test_complex_text(self): def test_complex_text(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
@ -102,7 +102,7 @@ class TestImagecomplextext(PillowTestCase):
liga_size = ttf.getsize('fi', features=['-liga']) liga_size = ttf.getsize('fi', features=['-liga'])
self.assertEqual(liga_size,(13,19)) self.assertEqual(liga_size,(13,19))
def test_kerning_features(self): def test_kerning_features(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)

View File

@ -223,7 +223,7 @@ class TestLibUnpack(PillowTestCase):
self.assert_unpack("L", "L;R", 1, 128, 64, 192, 32) self.assert_unpack("L", "L;R", 1, 128, 64, 192, 32)
self.assert_unpack("L", "L;16", 2, 2, 4, 6, 8) self.assert_unpack("L", "L;16", 2, 2, 4, 6, 8)
self.assert_unpack("L", "L;16B", 2, 1, 3, 5, 7) self.assert_unpack("L", "L;16B", 2, 1, 3, 5, 7)
self.assert_unpack("L", "L;16", b'\x00\xc6\x00\xaf', 198, 175) self.assert_unpack("L", "L;16", b'\x00\xc6\x00\xaf', 198, 175)
self.assert_unpack("L", "L;16B", b'\xc6\x00\xaf\x00', 198, 175) self.assert_unpack("L", "L;16B", b'\xc6\x00\xaf\x00', 198, 175)

View File

@ -1499,11 +1499,11 @@ _resize(ImagingObject* self, PyObject* args)
int xsize, ysize; int xsize, ysize;
int filter = IMAGING_TRANSFORM_NEAREST; int filter = IMAGING_TRANSFORM_NEAREST;
float box[4] = {0, 0, 0, 0}; float box[4] = {0, 0, 0, 0};
imIn = self->image; imIn = self->image;
box[2] = imIn->xsize; box[2] = imIn->xsize;
box[3] = imIn->ysize; box[3] = imIn->ysize;
if (!PyArg_ParseTuple(args, "(ii)|i(ffff)", &xsize, &ysize, &filter, if (!PyArg_ParseTuple(args, "(ii)|i(ffff)", &xsize, &ysize, &filter,
&box[0], &box[1], &box[2], &box[3])) &box[0], &box[1], &box[2], &box[3]))
return NULL; return NULL;
@ -3345,7 +3345,7 @@ _reset_stats(PyObject* self, PyObject* args)
if (!PyArg_ParseTuple(args, ":reset_stats")) if (!PyArg_ParseTuple(args, ":reset_stats"))
return NULL; return NULL;
arena->stats_new_count = 0; arena->stats_new_count = 0;
arena->stats_allocated_blocks = 0; arena->stats_allocated_blocks = 0;
arena->stats_reused_blocks = 0; arena->stats_reused_blocks = 0;
@ -3361,7 +3361,7 @@ _get_alignment(PyObject* self, PyObject* args)
{ {
if (!PyArg_ParseTuple(args, ":get_alignment")) if (!PyArg_ParseTuple(args, ":get_alignment"))
return NULL; return NULL;
return PyInt_FromLong(ImagingDefaultArena.alignment); return PyInt_FromLong(ImagingDefaultArena.alignment);
} }
@ -3370,7 +3370,7 @@ _get_block_size(PyObject* self, PyObject* args)
{ {
if (!PyArg_ParseTuple(args, ":get_block_size")) if (!PyArg_ParseTuple(args, ":get_block_size"))
return NULL; return NULL;
return PyInt_FromLong(ImagingDefaultArena.block_size); return PyInt_FromLong(ImagingDefaultArena.block_size);
} }
@ -3379,7 +3379,7 @@ _get_blocks_max(PyObject* self, PyObject* args)
{ {
if (!PyArg_ParseTuple(args, ":get_blocks_max")) if (!PyArg_ParseTuple(args, ":get_blocks_max"))
return NULL; return NULL;
return PyInt_FromLong(ImagingDefaultArena.blocks_max); return PyInt_FromLong(ImagingDefaultArena.blocks_max);
} }
@ -3389,7 +3389,7 @@ _set_alignment(PyObject* self, PyObject* args)
int alignment; int alignment;
if (!PyArg_ParseTuple(args, "i:set_alignment", &alignment)) if (!PyArg_ParseTuple(args, "i:set_alignment", &alignment))
return NULL; return NULL;
if (alignment < 1 || alignment > 128) { if (alignment < 1 || alignment > 128) {
PyErr_SetString(PyExc_ValueError, "alignment should be from 1 to 128"); PyErr_SetString(PyExc_ValueError, "alignment should be from 1 to 128");
return NULL; return NULL;
@ -3412,7 +3412,7 @@ _set_block_size(PyObject* self, PyObject* args)
int block_size; int block_size;
if (!PyArg_ParseTuple(args, "i:set_block_size", &block_size)) if (!PyArg_ParseTuple(args, "i:set_block_size", &block_size))
return NULL; return NULL;
if (block_size <= 0) { if (block_size <= 0) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"block_size should be greater than 0"); "block_size should be greater than 0");
@ -3437,7 +3437,7 @@ _set_blocks_max(PyObject* self, PyObject* args)
int blocks_max; int blocks_max;
if (!PyArg_ParseTuple(args, "i:set_blocks_max", &blocks_max)) if (!PyArg_ParseTuple(args, "i:set_blocks_max", &blocks_max))
return NULL; return NULL;
if (blocks_max < 0) { if (blocks_max < 0) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"blocks_max should be greater than 0"); "blocks_max should be greater than 0");
@ -3460,7 +3460,7 @@ _clear_cache(PyObject* self, PyObject* args)
if (!PyArg_ParseTuple(args, "|i:clear_cache", &i)) if (!PyArg_ParseTuple(args, "|i:clear_cache", &i))
return NULL; return NULL;
ImagingMemoryClearCache(&ImagingDefaultArena, i); ImagingMemoryClearCache(&ImagingDefaultArena, i);
Py_INCREF(Py_None); Py_INCREF(Py_None);
@ -3718,4 +3718,3 @@ init_imaging(void)
setup_module(m); setup_module(m);
} }
#endif #endif

View File

@ -121,7 +121,7 @@ getfont(PyObject* self_, PyObject* args, PyObject* kw)
return NULL; return NULL;
} }
if (!PyArg_ParseTupleAndKeywords(args, kw, "eti|is"PY_ARG_BYTES_LENGTH"i", if (!PyArg_ParseTupleAndKeywords(args, kw, "eti|is"PY_ARG_BYTES_LENGTH"i",
kwlist, kwlist,
Py_FileSystemDefaultEncoding, &filename, Py_FileSystemDefaultEncoding, &filename,
&size, &index, &encoding, &font_bytes, &size, &index, &encoding, &font_bytes,
@ -513,7 +513,7 @@ font_getsize(FontObject* self, PyObject* args)
PyMem_Free(glyph_info); PyMem_Free(glyph_info);
glyph_info = NULL; glyph_info = NULL;
} }
if (face) { if (face) {
/* left bearing */ /* left bearing */
@ -891,4 +891,3 @@ init_imagingft(void)
setup_module(m); setup_module(m);
} }
#endif #endif

View File

@ -301,4 +301,3 @@ init_imagingmath(void)
setup_module(m); setup_module(m);
} }
#endif #endif

View File

@ -301,4 +301,3 @@ init_imagingmorph(void)
setup_module(m); setup_module(m);
} }
#endif #endif

View File

@ -86,4 +86,3 @@ init_imagingtk(void)
load_tkinter_funcs(); load_tkinter_funcs();
} }
#endif #endif

View File

@ -942,4 +942,3 @@ PyImaging_Jpeg2KDecoderNew(PyObject* self, PyObject* args)
return (PyObject*) decoder; return (PyObject*) decoder;
} }
#endif /* HAVE_OPENJPEG */ #endif /* HAVE_OPENJPEG */

View File

@ -24,4 +24,3 @@ e.g.::
$ source ~/vpy27/bin/activate $ source ~/vpy27/bin/activate
$ make install $ make install
$ make test $ make test

View File

@ -11,4 +11,3 @@ pushd $archive
./configure --prefix=/usr && make -j4 && sudo make -j4 install ./configure --prefix=/usr && make -j4 && sudo make -j4 install
popd popd

View File

@ -15,4 +15,3 @@ make && sudo make install
cd .. cd ..
popd popd

View File

@ -1,5 +1,4 @@
#!/bin/sh #!/bin/sh
pkg -y install python python-dev ndk-sysroot clang make \ pkg -y install python python-dev ndk-sysroot clang make \
libjpeg-turbo-dev libjpeg-turbo-dev

View File

@ -150,4 +150,3 @@ can be found here.
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:

View File

@ -413,5 +413,3 @@ Python-based file decoder:
called with a buffer of data to be interpreted. called with a buffer of data to be interpreted.
3. Cleanup: The decoder instance's ``cleanup`` method is called. 3. Cleanup: The decoder instance's ``cleanup`` method is called.

View File

@ -168,10 +168,10 @@ Instances of the :py:class:`Image` class have the following attributes:
.. py:attribute:: filename .. py:attribute:: filename
The filename or path of the source file. Only images created with the The filename or path of the source file. Only images created with the
factory function `open` have a filename attribute. If the input is a factory function `open` have a filename attribute. If the input is a
file like object, the filename attribute is set to an empty string. file like object, the filename attribute is set to an empty string.
:type: :py:class: `string` :type: :py:class: `string`
.. py:attribute:: format .. py:attribute:: format

View File

@ -40,8 +40,8 @@ variables:
* ``PILLOW_BLOCK_SIZE``, in bytes, K, or M. Specifies the maximum * ``PILLOW_BLOCK_SIZE``, in bytes, K, or M. Specifies the maximum
block size for ``ImagingAllocateArray``. Valid values are block size for ``ImagingAllocateArray``. Valid values are
integers, with an optional `k` or `m` suffix. Defaults to 16M. integers, with an optional `k` or `m` suffix. Defaults to 16M.
* ``PILLOW_BLOCKS_MAX`` Specifies the number of freed blocks to * ``PILLOW_BLOCKS_MAX`` Specifies the number of freed blocks to
retain to fill future memory requests. Any freed blocks over this retain to fill future memory requests. Any freed blocks over this
threshold will be returned to the OS immediately. Defaults to 0. threshold will be returned to the OS immediately. Defaults to 0.

View File

@ -3,8 +3,7 @@ Internal Reference Docs
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
open_files open_files
limits limits
block_allocator block_allocator

View File

@ -4,7 +4,7 @@ File Handling in Pillow
When opening a file as an image, Pillow requires a filename, When opening a file as an image, Pillow requires a filename,
pathlib.Path object, or a file-like object. Pillow uses the filename pathlib.Path object, or a file-like object. Pillow uses the filename
or Path to open a file, so for the rest of this article, they will all or Path to open a file, so for the rest of this article, they will all
be treated as a file-like object. be treated as a file-like object.
The first four of these items are equivalent, the last is dangerous The first four of these items are equivalent, the last is dangerous
and may fail:: and may fail::
@ -12,14 +12,14 @@ and may fail::
from PIL import Image from PIL import Image
import io import io
import pathlib import pathlib
im = Image.open('test.jpg') im = Image.open('test.jpg')
im2 = Image.open(pathlib.Path('test.jpg')) im2 = Image.open(pathlib.Path('test.jpg'))
f = open('test.jpg', 'rb') f = open('test.jpg', 'rb')
im3 = Image.open(f) im3 = Image.open(f)
with open('test.jpg', 'rb') as f: with open('test.jpg', 'rb') as f:
im4 = Image.open(io.BytesIO(f.read())) im4 = Image.open(io.BytesIO(f.read()))
@ -31,10 +31,10 @@ and may fail::
The documentation specifies that the file will be closed after the The documentation specifies that the file will be closed after the
``Image.Image.load()`` method is called. This is an aspirational ``Image.Image.load()`` method is called. This is an aspirational
specification rather than an accurate reflection of the state of the specification rather than an accurate reflection of the state of the
code. code.
Pillow cannot in general close and reopen a file, so any access to Pillow cannot in general close and reopen a file, so any access to
that file needs to be prior to the close. that file needs to be prior to the close.
Issues Issues
------ ------
@ -44,10 +44,10 @@ The current open file handling is inconsistent at best:
* Most of the image plugins do not close the input file. * Most of the image plugins do not close the input file.
* Multi-frame images behave badly when seeking through the file, as * Multi-frame images behave badly when seeking through the file, as
it's legal to seek backward in the file until the last image is it's legal to seek backward in the file until the last image is
read, and then it's not. read, and then it's not.
* Using the file context manager to provide a file-like object to * Using the file context manager to provide a file-like object to
Pillow is dangerous unless the context of the image is limited to Pillow is dangerous unless the context of the image is limited to
the context of the file. the context of the file.
Image Lifecycle Image Lifecycle
--------------- ---------------
@ -59,7 +59,7 @@ Image Lifecycle
* ``Image.Image.load()`` when the pixel data from the image is * ``Image.Image.load()`` when the pixel data from the image is
required, ``load()`` is called. The current frame is read into required, ``load()`` is called. The current frame is read into
memory. The image can now be used independently of the underlying memory. The image can now be used independently of the underlying
image file. image file.
* ``Image.Image.seek()`` in the case of multi-frame images * ``Image.Image.seek()`` in the case of multi-frame images
(e.g. multipage TIFF and animated GIF) the image file left open so (e.g. multipage TIFF and animated GIF) the image file left open so
@ -72,12 +72,12 @@ Image Lifecycle
support. e.g.:: support. e.g.::
with Image.open('test.jpg') as img: with Image.open('test.jpg') as img:
... # image operations here. ... # image operations here.
The lifecycle of a single frame image is relatively simple. The file The lifecycle of a single frame image is relatively simple. The file
must remain open until the ``load()`` or ``close()`` function is must remain open until the ``load()`` or ``close()`` function is
called. called.
Multi-frame images are more complicated. The ``load()`` method is not Multi-frame images are more complicated. The ``load()`` method is not
a terminal method, so it should not close the underlying file. The a terminal method, so it should not close the underlying file. The
@ -85,7 +85,7 @@ current behavior of ``seek()`` closing the underlying file on
accessing the last frame is presumably a heuristic for closing the accessing the last frame is presumably a heuristic for closing the
file after iterating through the entire sequence. In general, Pillow file after iterating through the entire sequence. In general, Pillow
does not know if there are going to be any requests for additional does not know if there are going to be any requests for additional
data until the caller has explicitly closed the image. data until the caller has explicitly closed the image.
Complications Complications
@ -94,7 +94,7 @@ Complications
* TiffImagePlugin has some code to pass the underlying file descriptor * TiffImagePlugin has some code to pass the underlying file descriptor
into libtiff (if working on an actual file). Since libtiff closes into libtiff (if working on an actual file). Since libtiff closes
the file descriptor internally, it is duplicated prior to passing it the file descriptor internally, it is duplicated prior to passing it
into libtiff. into libtiff.
* ``decoder.handles_eof`` This slightly misnamed flag indicates that * ``decoder.handles_eof`` This slightly misnamed flag indicates that
the decoder wants to be called with a 0 length buffer when reads are the decoder wants to be called with a 0 length buffer when reads are
@ -118,8 +118,7 @@ Proposed File Handling
* ``Image.Image.load()`` should close the image file, unless there are * ``Image.Image.load()`` should close the image file, unless there are
multiple frames. multiple frames.
* ``Image.Image.seek()`` should never close the image file. * ``Image.Image.seek()`` should never close the image file.
* Users of the library should call ``Image.Image.close()`` on any * Users of the library should call ``Image.Image.close()`` on any
multi-frame image to ensure that the underlying file is closed. multi-frame image to ensure that the underlying file is closed.

View File

@ -1,4 +1,3 @@
3.0.0 3.0.0
===== =====
@ -49,4 +48,3 @@ The external dependencies on libjpeg and zlib are now required by default.
If the headers or libraries are not found, then installation will abort If the headers or libraries are not found, then installation will abort
with an error. This behaviour can be disabled with the ``--disable-libjpeg`` with an error. This behaviour can be disabled with the ``--disable-libjpeg``
and ``--disable-zlib`` flags. and ``--disable-zlib`` flags.

View File

@ -1,4 +1,3 @@
3.1.0 3.1.0
===== =====

View File

@ -1,4 +1,3 @@
3.1.1 3.1.1
===== =====

View File

@ -1,4 +1,3 @@
3.1.2 3.1.2
===== =====

View File

@ -1,4 +1,3 @@
3.2.0 3.2.0
----- -----

View File

@ -1,4 +1,3 @@
3.3.2 3.3.2
===== =====
@ -34,7 +33,3 @@ image size can lead to a smaller allocation than expected, leading to
arbitrary writes. arbitrary writes.
This issue was found by Cris Neckar at Divergent Security. This issue was found by Cris Neckar at Divergent Security.

View File

@ -1,4 +1,3 @@
3.4.0 3.4.0
----- -----

View File

@ -23,17 +23,17 @@ redirected to the olefile package. Direct accesses to
``PIL.OlefileIO`` raises a deprecation warning, then patches the ``PIL.OlefileIO`` raises a deprecation warning, then patches the
upstream olefile into ``sys.modules`` in its place. upstream olefile into ``sys.modules`` in its place.
SGI image save SGI image save
============== ==============
It is now possible to save images in modes ``L``, ``RGB``, and It is now possible to save images in modes ``L``, ``RGB``, and
``RGBA`` to the uncompressed SGI image format. ``RGBA`` to the uncompressed SGI image format.
Zero sized images Zero sized images
================= =================
Pillow 3.4.0 removed support for creating images with (0,0) size. This Pillow 3.4.0 removed support for creating images with (0,0) size. This
has been reenabled, restoring pre 3.4 behavior. has been reenabled, restoring pre 3.4 behavior.
Internal handles_eof flag Internal handles_eof flag
========================= =========================
@ -41,11 +41,11 @@ Internal handles_eof flag
The ``handles_eof flag`` for decoding images has been removed, as there The ``handles_eof flag`` for decoding images has been removed, as there
were no internal users of the flag. Anyone maintaining image decoders were no internal users of the flag. Anyone maintaining image decoders
outside of the Pillow source tree should consider using the cleanup outside of the Pillow source tree should consider using the cleanup
function pointers instead. function pointers instead.
Image.core.stretch removed Image.core.stretch removed
========================== ==========================
The stretch function on the core image object has been removed. This The stretch function on the core image object has been removed. This
used to be for enlarging the image, but has been aliased to resize used to be for enlarging the image, but has been aliased to resize
recently. recently.

View File

@ -12,7 +12,7 @@ Several deprecated items have been removed.
* The methods :py:meth:`PIL.ImageDraw.ImageDraw.setink`, * The methods :py:meth:`PIL.ImageDraw.ImageDraw.setink`,
:py:meth:`PIL.ImageDraw.ImageDraw.setfill`, and :py:meth:`PIL.ImageDraw.ImageDraw.setfill`, and
:py:meth:`PIL.ImageDraw.ImageDraw.setfont` have been removed. :py:meth:`PIL.ImageDraw.ImageDraw.setfont` have been removed.
Closing Files When Opening Images Closing Files When Opening Images
@ -27,7 +27,7 @@ is specified:
responsibility of the calling code to close the file. responsibility of the calling code to close the file.
* For images where Pillow opens the file and the file is known to have * For images where Pillow opens the file and the file is known to have
only one frame, the file is closed after loading. only one frame, the file is closed after loading.
* If the file has more than one frame, or if it can't be determined, * If the file has more than one frame, or if it can't be determined,
then the file is left open to permit seeking to subsequent then the file is left open to permit seeking to subsequent
@ -36,7 +36,7 @@ is specified:
* If the image is memory mapped, then we can't close the mapping to * If the image is memory mapped, then we can't close the mapping to
the underlying file until we are done with the image. The mapping the underlying file until we are done with the image. The mapping
will be closed in the ``close`` or ``__del__`` method. will be closed in the ``close`` or ``__del__`` method.
Changes to GIF Handling When Saving Changes to GIF Handling When Saving
@ -50,7 +50,7 @@ saving images. There are two external changes that arise from this:
* The image to be saved is no longer modified in place by any of the * The image to be saved is no longer modified in place by any of the
operations of the save function. Previously it was modified when operations of the save function. Previously it was modified when
optimizing the image palette. optimizing the image palette.
This refactor fixed some bugs with palette handling when saving This refactor fixed some bugs with palette handling when saving
multiple frame GIFs. multiple frame GIFs.
@ -60,7 +60,7 @@ New Method: Image.remap_palette
The method :py:meth:`PIL.Image.Image.remap_palette()` has been The method :py:meth:`PIL.Image.Image.remap_palette()` has been
added. This method was hoisted from the GifImagePlugin code used to added. This method was hoisted from the GifImagePlugin code used to
optimize the palette. optimize the palette.
Added Decoder Registry and Support for Python Based Decoders Added Decoder Registry and Support for Python Based Decoders
============================================================ ============================================================
@ -76,7 +76,7 @@ Tests
===== =====
Many tests have been added, including correctness tests for image Many tests have been added, including correctness tests for image
formats that have been previously untested. formats that have been previously untested.
We are now running automated tests in Docker containers against more We are now running automated tests in Docker containers against more
Linux versions than are provided on Travis CI, which is currently Linux versions than are provided on Travis CI, which is currently

View File

@ -20,5 +20,3 @@ CPython 3.6.1 to not work on installations of C-Python 3.6.0. This fix
undefines PySlice_GetIndicesEx if it exists to restore compatibility undefines PySlice_GetIndicesEx if it exists to restore compatibility
with both 3.6.0 and 3.6.1. See https://bugs.python.org/issue29943 for with both 3.6.0 and 3.6.1. See https://bugs.python.org/issue29943 for
more details. more details.

View File

@ -8,4 +8,3 @@ Fixed Windows PyPy Build
A change in the 4.2.0 cycle broke the Windows PyPy build. This has A change in the 4.2.0 cycle broke the Windows PyPy build. This has
been fixed, and PyPy is now part of the Windows CI matrix. been fixed, and PyPy is now part of the Windows CI matrix.

View File

@ -20,7 +20,7 @@ TIFF Metadata Changes
single element tuple. This is only with the new api, not the legacy single element tuple. This is only with the new api, not the legacy
api. This normalizes the handling of fields, so that the metadata api. This normalizes the handling of fields, so that the metadata
with inferred or image specified counts are handled the same as with inferred or image specified counts are handled the same as
metadata with count specified in the TIFF spec. metadata with count specified in the TIFF spec.
* The ``PhotoshopInfo``, ``XMP``, and ``JPEGTables`` tags now have a * The ``PhotoshopInfo``, ``XMP``, and ``JPEGTables`` tags now have a
defined type (bytes) and a count of 1. defined type (bytes) and a count of 1.
* The ``ImageJMetaDataByteCounts`` tag now has an arbitrary number of * The ``ImageJMetaDataByteCounts`` tag now has an arbitrary number of
@ -85,7 +85,7 @@ There is a new :py:class:`PIL.ImageFilter.MultibandFilter` base class
for image filters that can run on all channels of an image in one for image filters that can run on all channels of an image in one
operation. The original :py:class:`PIL.ImageFilter.Filter` class operation. The original :py:class:`PIL.ImageFilter.Filter` class
remains for image filters that can process only single band images, or remains for image filters that can process only single band images, or
require splitting of channels prior to filtering. require splitting of channels prior to filtering.
Other Changes Other Changes
============= =============
@ -109,7 +109,7 @@ images to and from RGB and RGBA formats. The image data is truncated
to 8-bit precision. to 8-bit precision.
Pillow can now read RLE encoded SGI images in both 8 and 16-bit Pillow can now read RLE encoded SGI images in both 8 and 16-bit
precision. precision.
Performance Performance
^^^^^^^^^^^ ^^^^^^^^^^^
@ -124,7 +124,7 @@ This release contains several performance improvements:
* ``Image.transpose`` has been accelerated 15% or more by using a cache * ``Image.transpose`` has been accelerated 15% or more by using a cache
friendly algorithm. friendly algorithm.
* ImageFilters based on Kernel convolution are significantly faster * ImageFilters based on Kernel convolution are significantly faster
due to the new MultibandFilter feature. due to the new MultibandFilter feature.
* All memory allocation for images is now done in blocks, rather than * All memory allocation for images is now done in blocks, rather than
falling back to an allocation for each scan line for images larger falling back to an allocation for each scan line for images larger
than the block size. than the block size.

View File

@ -80,4 +80,3 @@ ImagingSavePPM(Imaging im, const char* outfile)
return 1; return 1;
} }

View File

@ -344,4 +344,3 @@ ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32* kernel,
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
return imOut; return imOut;
} }

View File

@ -312,4 +312,3 @@ int ImagingJpegDecodeCleanup(ImagingCodecState state){
} }
#endif #endif

View File

@ -39,4 +39,3 @@ ImagingNegative(Imaging im)
return imOut; return imOut;
} }

View File

@ -188,4 +188,3 @@ ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
} }
} }
} }

View File

@ -226,7 +226,7 @@ normalize_coeffs_8bpc(int outSize, int ksize, double *prekk)
void void
ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset, ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset,
int ksize, int *bounds, double *prekk) int ksize, int *bounds, double *prekk)
{ {

View File

@ -28,7 +28,7 @@ static void read4B(UINT32* dest, UINT8* buf)
static int expandrow(UINT8* dest, UINT8* src, int n, int z) static int expandrow(UINT8* dest, UINT8* src, int n, int z)
{ {
UINT8 pixel, count; UINT8 pixel, count;
for (;n > 0; n--) for (;n > 0; n--)
{ {
pixel = *src++; pixel = *src++;
@ -42,7 +42,7 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z)
*dest = *src++; *dest = *src++;
dest += z; dest += z;
} }
} }
else { else {
pixel = *src++; pixel = *src++;
@ -51,7 +51,7 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z)
dest += z; dest += z;
} }
} }
} }
return 0; return 0;
} }
@ -60,7 +60,7 @@ static int expandrow2(UINT16* dest, UINT16* src, int n, int z)
{ {
UINT8 pixel, count; UINT8 pixel, count;
for (;n > 0; n--) for (;n > 0; n--)
{ {
pixel = ((UINT8*)src)[1]; pixel = ((UINT8*)src)[1];
@ -96,7 +96,7 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
SGISTATE *c; SGISTATE *c;
int err = 0; int err = 0;
/* Get all data from File descriptor */ /* Get all data from File descriptor */
c = (SGISTATE*)state->context; c = (SGISTATE*)state->context;
_imaging_seek_pyFd(state->fd, 0L, SEEK_END); _imaging_seek_pyFd(state->fd, 0L, SEEK_END);
c->bufsize = _imaging_tell_pyFd(state->fd); c->bufsize = _imaging_tell_pyFd(state->fd);
@ -155,7 +155,7 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
c->rleoffset = c->starttab[c->rowno + c->channo * im->ysize]; c->rleoffset = c->starttab[c->rowno + c->channo * im->ysize];
c->rlelength = c->lengthtab[c->rowno + c->channo * im->ysize]; c->rlelength = c->lengthtab[c->rowno + c->channo * im->ysize];
c->rleoffset -= SGI_HEADER_SIZE; c->rleoffset -= SGI_HEADER_SIZE;
/* row decompression */ /* row decompression */
if (c->bpc ==1) { if (c->bpc ==1) {
if(expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands)) if(expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands))
@ -165,19 +165,19 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
if(expandrow2((UINT16*)&state->buffer[c->channo * 2], (UINT16*)&ptr[c->rleoffset], c->rlelength, im->bands)) if(expandrow2((UINT16*)&state->buffer[c->channo * 2], (UINT16*)&ptr[c->rleoffset], c->rlelength, im->bands))
goto sgi_finish_decode; goto sgi_finish_decode;
} }
state->count += c->rlelength; state->count += c->rlelength;
} }
/* store decompressed data in image */ /* store decompressed data in image */
state->shuffle((UINT8*)im->image[state->y], state->buffer, im->xsize); state->shuffle((UINT8*)im->image[state->y], state->buffer, im->xsize);
} }
c->bufsize++; c->bufsize++;
sgi_finish_decode: ; sgi_finish_decode: ;
free(c->starttab); free(c->starttab);
free(c->lengthtab); free(c->lengthtab);
free(ptr); free(ptr);

View File

@ -490,7 +490,7 @@ ImagingAllocateBlock(Imaging im)
im->image[y] = im->block + i; im->image[y] = im->block + i;
i += im->linesize; i += im->linesize;
} }
im->destroy = ImagingDestroyBlock; im->destroy = ImagingDestroyBlock;
return im; return im;

View File

@ -188,7 +188,7 @@ unpack1IR(UINT8* out, const UINT8* in, int pixels)
static void static void
unpack18(UINT8* out, const UINT8* in, int pixels) unpack18(UINT8* out, const UINT8* in, int pixels)
{ {
/* Unpack a '|b1' image, which is a numpy boolean. /* Unpack a '|b1' image, which is a numpy boolean.
1 == true, 0==false, in bytes */ 1 == true, 0==false, in bytes */
int i; int i;

1
map.c
View File

@ -385,4 +385,3 @@ PyImaging_MapBuffer(PyObject* self, PyObject* args)
return PyImagingNew(im); return PyImagingNew(im);
} }

1
path.c
View File

@ -625,4 +625,3 @@ static PyTypeObject PyPathType = {
0, /*tp_members*/ 0, /*tp_members*/
getsetters, /*tp_getset*/ getsetters, /*tp_getset*/
}; };

View File

@ -1,9 +1,9 @@
Quick README Quick README
------------ ------------
For more extensive info, see the windows build instructions `docs/build.rst`. For more extensive info, see the windows build instructions `docs/build.rst`.
* See https://github.com/python-pillow/Pillow/issues/553#issuecomment-37877416 and https://github.com/matplotlib/matplotlib/issues/1717#issuecomment-13343859 * See https://github.com/python-pillow/Pillow/issues/553#issuecomment-37877416 and https://github.com/matplotlib/matplotlib/issues/1717#issuecomment-13343859
* Works best with Python 3.4, due to virtualenv and pip batteries included. Python3+ required for fetch command. * Works best with Python 3.4, due to virtualenv and pip batteries included. Python3+ required for fetch command.
* Check config.py for virtual env paths, suffix for 64-bit releases. Defaults to `x64`, set `X64_EXT` to change. * Check config.py for virtual env paths, suffix for 64-bit releases. Defaults to `x64`, set `X64_EXT` to change.

View File

@ -76,7 +76,7 @@ def build_one(py_ver, compiler):
args['executable'] = "python.exe" args['executable'] = "python.exe"
if 'EXECUTABLE' in os.environ: if 'EXECUTABLE' in os.environ:
args['executable'] = "%EXECUTABLE%" args['executable'] = "%EXECUTABLE%"
args['py_ver'] = py_ver args['py_ver'] = py_ver
if '34' in py_ver: if '34' in py_ver:
args['tcl_ver'] = '86' args['tcl_ver'] = '86'

View File

@ -91,4 +91,3 @@ Testing Pillow
Build and install Pillow, then run `python test.py` from the Build and install Pillow, then run `python test.py` from the
`winbuild` directory. `winbuild` directory.