Compare commits

...

30 Commits
main ... 8.3.x

Author SHA1 Message Date
Hugo van Kemenade
8013f130a5 8.3.2 version bump 2021-09-02 15:13:00 +03:00
Hugo van Kemenade
23c7ca82f0 Update CHANGES.rst 2021-09-02 15:08:30 +03:00
Hugo van Kemenade
8450366be3 Update release notes 2021-09-02 15:08:18 +03:00
Hugo van Kemenade
a0afe89990 Update test case
Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com>
2021-09-02 15:08:14 +03:00
Hugo van Kemenade
9e08eb8f78 Raise ValueError if color specifier is too long 2021-09-02 15:08:09 +03:00
Eric Soroos
bd5cf7db87 FLI tests for Oss-fuzz crash.
* Note, valgrind doesn't pick this up, it's only the oss-fuzz
  reproducer that catches it OMM.
2021-09-02 15:08:04 +03:00
Eric Soroos
94a0cf1b14 Fix 6-byte OOB read in FliDecode 2021-09-02 15:08:00 +03:00
Hugo van Kemenade
cece64f4be Add 8.3.2 (2021-09-02) [CI skip] 2021-09-01 19:27:44 +03:00
Hugo van Kemenade
e422386376 Add release notes for Pillow 8.3.2 2021-09-01 19:27:02 +03:00
Andrew Murray
08dcbb8732 Pillow 8.3.2 supports Python 3.10 [ci skip] 2021-09-01 19:25:35 +03:00
nulano
cce1244562 hide FriBiDi shim symbols to avoid conflict with real FriBiDi library 2021-09-01 19:22:14 +03:00
Andrew Murray
64edb9cd6d Fixed generated palettes 2021-09-01 19:21:26 +03:00
Andrew Murray
8f1524edd8 Updated documentation 2021-09-01 19:21:22 +03:00
Andrew Murray
bac474402c Do not rearrange palette channels 2021-09-01 19:16:36 +03:00
Andrew Murray
8cc3ac3093 Added test 2021-09-01 19:16:27 +03:00
Miloš Komarčević
39e36368e7 Ensure TIFF RowsPerStrip is multiple of 8 for JPEG compression 2021-09-01 19:16:23 +03:00
Andrew Murray
c0615e74b2 Used line block in table heading 2021-09-01 19:11:28 +03:00
Andrew Murray
1b11694a2b Removed bottom gap in table headings 2021-09-01 19:11:17 +03:00
Andrew Murray
49b8c7e548 Use line blocks instead of blank lines 2021-09-01 19:11:13 +03:00
Hugo van Kemenade
0fbd20118d Split support table to fit on page 2021-09-01 19:07:29 +03:00
Hugo van Kemenade
e10a5ec7e0 Add th headers to tables, newlines, fix typo 2021-09-01 19:07:25 +03:00
Hugo van Kemenade
db774eeaa7 Add support for Python 3.10 2021-09-01 19:07:18 +03:00
Andrew Murray
92933b8657 8.3.1 version bump 2021-07-07 00:05:28 +10:00
Andrew Murray
31bd320791 Added release notes for 8.3.1 2021-07-07 00:05:14 +10:00
Andrew Murray
afca674cd4 Update CHANGES.rst [ci skip] 2021-07-06 18:00:09 +10:00
Andrew Murray
c712d68df2 Catch OSError when checking if fp is sys.stdout 2021-07-06 17:58:58 +10:00
Andrew Murray
9b4fff85b3 Handle removing orientation from alternate types of EXIF data 2021-07-06 17:58:53 +10:00
Thomas Viehmann
76037e514f Use numpy.array with dtype
Thank you @radarhere.

Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com>
2021-07-06 17:58:44 +10:00
Thomas Viehmann
2ebb695a3a Use numpy.float64 instead of numpy.float to avoid deprecation (thank you radarhere) 2021-07-06 17:58:39 +10:00
Thomas Viehmann
7e8cefaee4 Make Image.__array__ take optional dtype argument
This is required by the numpy protocol.
2021-07-06 17:58:32 +10:00
36 changed files with 410 additions and 202 deletions

View File

@ -2,6 +2,39 @@
Changelog (Pillow)
==================
8.3.2 (2021-09-02)
------------------
- CVE-2021-23437 Raise ValueError if color specifier is too long
[hugovk, radarhere]
- Fix 6-byte OOB read in FliDecode
[wiredfool]
- Add support for Python 3.10 #5569, #5570
[hugovk, radarhere]
- Ensure TIFF ``RowsPerStrip`` is multiple of 8 for JPEG compression #5588
[kmilos, radarhere]
- Updates for ``ImagePalette`` channel order #5599
[radarhere]
- Hide FriBiDi shim symbols to avoid conflict with real FriBiDi library #5651
[nulano]
8.3.1 (2021-07-06)
------------------
- Catch OSError when checking if fp is sys.stdout #5585
[radarhere]
- Handle removing orientation from alternate types of EXIF data #5584
[radarhere]
- Make Image.__array__ take optional dtype argument #5572
[t-vi, radarhere]
8.3.0 (2021-07-01)
------------------

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -138,3 +138,16 @@ def test_timeouts(test_file):
with Image.open(f) as im:
with pytest.raises(OSError):
im.load()
@pytest.mark.parametrize(
"test_file",
[
"Tests/images/crash-5762152299364352.fli",
],
)
def test_crash(test_file):
with open(test_file, "rb") as f:
with Image.open(f) as im:
with pytest.raises(OSError):
im.load()

View File

@ -833,7 +833,7 @@ def test_palette_save_ImagePalette(tmp_path):
with Image.open(out) as reloaded:
im.putpalette(palette)
assert_image_equal(reloaded, im)
assert_image_equal(reloaded.convert("RGB"), im.convert("RGB"))
def test_save_I(tmp_path):

View File

@ -968,10 +968,11 @@ class TestFileLibTiff(LibTiffTestCase):
assert str(e.value) == "-9"
TiffImagePlugin.READ_LIBTIFF = False
def test_save_multistrip(self, tmp_path):
@pytest.mark.parametrize("compression", ("tiff_adobe_deflate", "jpeg"))
def test_save_multistrip(self, compression, tmp_path):
im = hopper("RGB").resize((256, 256))
out = str(tmp_path / "temp.tif")
im.save(out, compression="tiff_adobe_deflate")
im.save(out, compression=compression)
with Image.open(out) as im:
# Assert that there are multiple strips

View File

@ -14,6 +14,10 @@ def test_toarray():
ai = numpy.array(im.convert(mode))
return ai.shape, ai.dtype.str, ai.nbytes
def test_with_dtype(dtype):
ai = numpy.array(im, dtype=dtype)
assert ai.dtype == dtype
# assert test("1") == ((100, 128), '|b1', 1600))
assert test("L") == ((100, 128), "|u1", 12800)
@ -27,6 +31,9 @@ def test_toarray():
assert test("RGBA") == ((100, 128, 4), "|u1", 51200)
assert test("RGBX") == ((100, 128, 4), "|u1", 51200)
test_with_dtype(numpy.float64)
test_with_dtype(numpy.uint8)
with Image.open("Tests/images/truncated_jpeg.jpg") as im_truncated:
with pytest.raises(OSError):
numpy.array(im_truncated)

View File

@ -2,7 +2,7 @@ import pytest
from PIL import Image, ImagePalette
from .helper import assert_image_equal, hopper
from .helper import assert_image_equal, assert_image_equal_tofile, hopper
def test_putpalette():
@ -36,9 +36,15 @@ def test_putpalette():
def test_imagepalette():
im = hopper("P")
im.putpalette(ImagePalette.negative())
assert_image_equal_tofile(im.convert("RGB"), "Tests/images/palette_negative.png")
im.putpalette(ImagePalette.random())
im.putpalette(ImagePalette.sepia())
assert_image_equal_tofile(im.convert("RGB"), "Tests/images/palette_sepia.png")
im.putpalette(ImagePalette.wedge())
assert_image_equal_tofile(im.convert("RGB"), "Tests/images/palette_wedge.png")
def test_putpalette_with_alpha_values():

View File

@ -191,3 +191,12 @@ def test_rounding_errors():
assert (255, 255) == ImageColor.getcolor("white", "LA")
assert (163, 33) == ImageColor.getcolor("rgba(0, 255, 115, 33)", "LA")
Image.new("LA", (1, 1), "white")
def test_color_too_long():
# Arrange
color_too_long = "hsl(" + "1" * 40 + "," + "1" * 40 + "%," + "1" * 40 + "%)"
# Act / Assert
with pytest.raises(ValueError):
ImageColor.getrgb(color_too_long)

View File

@ -335,6 +335,28 @@ def test_exif_transpose():
) as orientation_im:
check(orientation_im)
# Orientation from "XML:com.adobe.xmp" info key
with Image.open("Tests/images/xmp_tags_orientation.png") as im:
assert im.getexif()[0x0112] == 3
transposed_im = ImageOps.exif_transpose(im)
assert 0x0112 not in transposed_im.getexif()
# Orientation from "Raw profile type exif" info key
# This test image has been manually hexedited from exif_imagemagick.png
# to have a different orientation
with Image.open("Tests/images/exif_imagemagick_orientation.png") as im:
assert im.getexif()[0x0112] == 3
transposed_im = ImageOps.exif_transpose(im)
assert 0x0112 not in transposed_im.getexif()
# Orientation set directly on Image.Exif
im = hopper()
im.getexif()[0x0112] = 3
transposed_im = ImageOps.exif_transpose(im)
assert 0x0112 not in transposed_im.getexif()
def test_autocontrast_cutoff():
# Test the cutoff argument of autocontrast

View File

@ -312,6 +312,7 @@ texinfo_documents = [
def setup(app):
app.add_js_file("js/script.js")
app.add_css_file("css/styles.css")
app.add_css_file("css/dark.css")
app.add_css_file("css/light.css")

View File

@ -135,7 +135,6 @@ Some attributes in :py:class:`PIL.ImageCms.CmsProfile` have been removed. From 6
they issued a ``DeprecationWarning``:
======================== ===================================================
Removed Use instead
======================== ===================================================
``color_space`` Padded :py:attr:`~.CmsProfile.xcolor_space`
@ -261,7 +260,7 @@ PIL.OleFileIO
.. deprecated:: 4.0.0
.. versionremoved:: 6.0.0
PIL.OleFileIO was removed as a vendored file and in Pillow 4.0.0 (2017-01) in favour of
PIL.OleFileIO was removed as a vendored file in Pillow 4.0.0 (2017-01) in favour of
the upstream olefile Python package, and replaced with an ``ImportError`` in 5.0.0
(2018-01). The deprecated file has now been removed from Pillow. If needed, install from
PyPI (eg. ``python3 -m pip install olefile``).

View File

@ -191,34 +191,34 @@ match PILs internal pixel layout. PIL supports a large set of raw modes; for
complete list, see the table in the :file:`Unpack.c` module. The following
table describes some commonly used **raw modes**:
+-----------+-----------------------------------------------------------------+
| mode | description |
+===========+=================================================================+
| ``1`` | 1-bit bilevel, stored with the leftmost pixel in the most |
| | significant bit. 0 means black, 1 means white. |
+-----------+-----------------------------------------------------------------+
| ``1;I`` | 1-bit inverted bilevel, stored with the leftmost pixel in the |
| | most significant bit. 0 means white, 1 means black. |
+-----------+-----------------------------------------------------------------+
| ``1;R`` | 1-bit reversed bilevel, stored with the leftmost pixel in the |
| | least significant bit. 0 means black, 1 means white. |
+-----------+-----------------------------------------------------------------+
| ``L`` | 8-bit greyscale. 0 means black, 255 means white. |
+-----------+-----------------------------------------------------------------+
| ``L;I`` | 8-bit inverted greyscale. 0 means white, 255 means black. |
+-----------+-----------------------------------------------------------------+
| ``P`` | 8-bit palette-mapped image. |
+-----------+-----------------------------------------------------------------+
| ``RGB`` | 24-bit true colour, stored as (red, green, blue). |
+-----------+-----------------------------------------------------------------+
| ``BGR`` | 24-bit true colour, stored as (blue, green, red). |
+-----------+-----------------------------------------------------------------+
| ``RGBX`` | 24-bit true colour, stored as (red, green, blue, pad). The pad |
| | pixels may vary. |
+-----------+-----------------------------------------------------------------+
| ``RGB;L`` | 24-bit true colour, line interleaved (first all red pixels, then|
| | all green pixels, finally all blue pixels). |
+-----------+-----------------------------------------------------------------+
+-----------+-------------------------------------------------------------------+
| mode | description |
+===========+===================================================================+
| ``1`` | | 1-bit bilevel, stored with the leftmost pixel in the most |
| | | significant bit. 0 means black, 1 means white. |
+-----------+-------------------------------------------------------------------+
| ``1;I`` | | 1-bit inverted bilevel, stored with the leftmost pixel in the |
| | | most significant bit. 0 means white, 1 means black. |
+-----------+-------------------------------------------------------------------+
| ``1;R`` | | 1-bit reversed bilevel, stored with the leftmost pixel in the |
| | | least significant bit. 0 means black, 1 means white. |
+-----------+-------------------------------------------------------------------+
| ``L`` | 8-bit greyscale. 0 means black, 255 means white. |
+-----------+-------------------------------------------------------------------+
| ``L;I`` | 8-bit inverted greyscale. 0 means white, 255 means black. |
+-----------+-------------------------------------------------------------------+
| ``P`` | 8-bit palette-mapped image. |
+-----------+-------------------------------------------------------------------+
| ``RGB`` | 24-bit true colour, stored as (red, green, blue). |
+-----------+-------------------------------------------------------------------+
| ``BGR`` | 24-bit true colour, stored as (blue, green, red). |
+-----------+-------------------------------------------------------------------+
| ``RGBX`` | | 24-bit true colour, stored as (red, green, blue, pad). The pad |
| | | pixels may vary. |
+-----------+-------------------------------------------------------------------+
| ``RGB;L`` | | 24-bit true colour, line interleaved (first all red pixels, then|
| | | all green pixels, finally all blue pixels). |
+-----------+-------------------------------------------------------------------+
Note that for the most common cases, the raw mode is simply the same as the mode.

View File

@ -15,27 +15,33 @@ Python Support
Pillow supports these Python versions.
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| **Python** |**3.9**|**3.8**|**3.7**|**3.6**|**3.5**|**3.4**|**3.3**|**3.2**|**2.7**|**2.6**|**2.5**|**2.4**|
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pillow >= 8.0 | Yes | Yes | Yes | Yes | | | | | | | | |
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pillow 7.0 - 7.2 | | Yes | Yes | Yes | Yes | | | | | | | |
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pillow 6.2.1 - 6.2.2 | | Yes | Yes | Yes | Yes | | | | Yes | | | |
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pillow 6.0 - 6.2.0 | | | Yes | Yes | Yes | | | | Yes | | | |
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pillow 5.2 - 5.4 | | | Yes | Yes | Yes | Yes | | | Yes | | | |
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pillow 5.0 - 5.1 | | | | Yes | Yes | Yes | | | Yes | | | |
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pillow 4 | | | | Yes | Yes | Yes | Yes | | Yes | | | |
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pillow 2 - 3 | | | | | Yes | Yes | Yes | Yes | Yes | Yes | | |
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pillow < 2 | | | | | | | | | Yes | Yes | Yes | Yes |
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
+----------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| Python |3.10 | 3.9 | 3.8 | 3.7 | 3.6 | 3.5 | 3.4 | 2.7 |
+======================+=====+=====+=====+=====+=====+=====+=====+=====+
| Pillow >= 8.3.2 | Yes | Yes | Yes | Yes | Yes | | | |
+----------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| Pillow 8.0 - 8.3.1 | | Yes | Yes | Yes | Yes | | | |
+----------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| Pillow 7.0 - 7.2 | | | Yes | Yes | Yes | Yes | | |
+----------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| Pillow 6.2.1 - 6.2.2 | | | Yes | Yes | Yes | Yes | | Yes |
+----------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| Pillow 6.0 - 6.2.0 | | | | Yes | Yes | Yes | | Yes |
+----------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| Pillow 5.2 - 5.4 | | | | Yes | Yes | Yes | Yes | Yes |
+----------------------+-----+-----+-----+-----+-----+-----+-----+-----+
+------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| Python | 3.6 | 3.5 | 3.4 | 3.3 | 3.2 | 2.7 | 2.6 | 2.5 | 2.4 |
+==================+=====+=====+=====+=====+=====+=====+=====+=====+=====+
| Pillow 5.0 - 5.1 | Yes | Yes | Yes | | | Yes | | | |
+------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| Pillow 4 | Yes | Yes | Yes | Yes | | Yes | | | |
+------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| Pillow 2 - 3 | | Yes | Yes | Yes | Yes | Yes | Yes | | |
+------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| Pillow < 2 | | | | | | Yes | Yes | Yes | Yes |
+------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
Basic Installation
------------------
@ -437,41 +443,41 @@ Continuous Integration Targets
These platforms are built and tested for every change.
+----------------------------------+--------------------------+-----------------------+
|**Operating system** |**Tested Python versions**|**Tested architecture**|
+----------------------------------+--------------------------+-----------------------+
| Alpine | 3.8 |x86-64 |
+----------------------------------+--------------------------+-----------------------+
| Arch | 3.8 |x86-64 |
+----------------------------------+--------------------------+-----------------------+
| Amazon Linux 2 | 3.7 |x86-64 |
+----------------------------------+--------------------------+-----------------------+
| CentOS 7 | 3.6 |x86-64 |
+----------------------------------+--------------------------+-----------------------+
| CentOS 8 | 3.6 |x86-64 |
+----------------------------------+--------------------------+-----------------------+
| Debian 10 Buster | 3.7 |x86 |
+----------------------------------+--------------------------+-----------------------+
| Fedora 33 | 3.9 |x86-64 |
+----------------------------------+--------------------------+-----------------------+
| Fedora 34 | 3.9 |x86-64 |
+----------------------------------+--------------------------+-----------------------+
| macOS 10.15 Catalina | 3.6, 3.7, 3.8, 3.9, PyPy3|x86-64 |
+----------------------------------+--------------------------+-----------------------+
| Ubuntu Linux 16.04 LTS (Xenial) | 3.6, 3.7, 3.8, 3.9, PyPy3|x86-64 |
+----------------------------------+--------------------------+-----------------------+
| Ubuntu Linux 18.04 LTS (Bionic) | 3.6, 3.7, 3.8, 3.9, PyPy3|x86-64 |
+----------------------------------+--------------------------+-----------------------+
| Ubuntu Linux 20.04 LTS (Focal) | 3.8 |x86-64 |
+----------------------------------+--------------------------+-----------------------+
| Windows Server 2016 | 3.6 |x86-64 |
+----------------------------------+--------------------------+-----------------------+
| Windows Server 2019 | 3.6, 3.7, 3.8, 3.9 |x86, x86-64 |
| +--------------------------+-----------------------+
| | PyPy3 |x86 |
| +--------------------------+-----------------------+
| | 3.8/MinGW |x86, x86-64 |
+----------------------------------+--------------------------+-----------------------+
+----------------------------------+---------------------------+---------------------+
| Operating system | Tested Python versions | Tested architecture |
+==================================+===========================+=====================+
| Alpine | 3.8 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| Arch | 3.8 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| Amazon Linux 2 | 3.7 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| CentOS 7 | 3.6 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| CentOS 8 | 3.6 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| Debian 10 Buster | 3.7 | x86 |
+----------------------------------+---------------------------+---------------------+
| Fedora 33 | 3.9 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| Fedora 34 | 3.9 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| macOS 10.15 Catalina | 3.6, 3.7, 3.8, 3.9, PyPy3 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| Ubuntu Linux 16.04 LTS (Xenial) | 3.6, 3.7, 3.8, 3.9, PyPy3 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| Ubuntu Linux 18.04 LTS (Bionic) | 3.6, 3.7, 3.8, 3.9, PyPy3 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| Ubuntu Linux 20.04 LTS (Focal) | 3.8 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| Windows Server 2016 | 3.6 | x86-64 |
+----------------------------------+---------------------------+---------------------+
| Windows Server 2019 | 3.6, 3.7, 3.8, 3.9 | x86, x86-64 |
| +---------------------------+---------------------+
| | PyPy3 | x86 |
| +---------------------------+---------------------+
| | 3.8/MinGW | x86, x86-64 |
+----------------------------------+---------------------------+---------------------+
Other Platforms
@ -484,78 +490,79 @@ These platforms have been reported to work at the versions mentioned.
Contributors please test Pillow on your platform then update this
document and send a pull request.
+----------------------------------+------------------------------+--------------------------------+-----------------------+
|**Operating system** |**Tested Python versions** |**Latest tested Pillow version**|**Tested processors** |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 11.0 Big Sur | 3.7, 3.8, 3.9 | 8.2.0 |arm |
| +------------------------------+--------------------------------+-----------------------+
| | 3.6, 3.7, 3.8, 3.9 | 8.2.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 10.15 Catalina | 3.6, 3.7, 3.8, 3.9 | 8.0.1 |x86-64 |
| +------------------------------+--------------------------------+ |
| | 3.5 | 7.2.0 | |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 10.14 Mojave | 3.5, 3.6, 3.7, 3.8 | 7.2.0 |x86-64 |
| +------------------------------+--------------------------------+ |
| | 2.7 | 6.0.0 | |
| +------------------------------+--------------------------------+ |
| | 3.4 | 5.4.1 | |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 10.13 High Sierra | 2.7, 3.4, 3.5, 3.6 | 4.2.1 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 10.12 Sierra | 2.7, 3.4, 3.5, 3.6 | 4.1.1 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Mac OS X 10.11 El Capitan | 2.7, 3.4, 3.5, 3.6, 3.7 | 5.4.1 |x86-64 |
| +------------------------------+--------------------------------+ |
| | 3.3 | 4.1.0 | |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Mac OS X 10.9 Mavericks | 2.7, 3.2, 3.3, 3.4 | 3.0.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Mac OS X 10.8 Mountain Lion | 2.6, 2.7, 3.2, 3.3 | |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Redhat Linux 6 | 2.6 | |x86 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| CentOS 6.3 | 2.7, 3.3 | |x86 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Fedora 23 | 2.7, 3.4 | 3.1.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Ubuntu Linux 12.04 LTS (Precise) | 2.6, 3.2, 3.3, 3.4, 3.5 | 3.4.1 |x86,x86-64 |
| | PyPy5.3.1, PyPy3 v2.4.0 | | |
| +------------------------------+--------------------------------+-----------------------+
| | 2.7 | 4.3.0 |x86-64 |
| +------------------------------+--------------------------------+-----------------------+
| | 2.7, 3.2 | 3.4.1 |ppc |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Ubuntu Linux 10.04 LTS (Lucid) | 2.6 | 2.3.0 |x86,x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Debian 8.2 Jessie | 2.7, 3.4 | 3.1.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Raspbian Jessie | 2.7, 3.4 | 3.1.0 |arm |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Raspbian Stretch | 2.7, 3.5 | 4.0.0 |arm |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Raspberry Pi OS | 3.6, 3.7, 3.8, 3.9 | 8.2.0 |arm |
| +------------------------------+--------------------------------+ |
| | 2.7 | 6.2.2 | |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Gentoo Linux | 2.7, 3.2 | 2.1.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| FreeBSD 11.1 | 2.7, 3.4, 3.5, 3.6 | 4.3.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| FreeBSD 10.3 | 2.7, 3.4, 3.5 | 4.2.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| FreeBSD 10.2 | 2.7, 3.4 | 3.1.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Windows 10 | 3.7 | 7.1.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Windows 8.1 Pro | 2.6, 2.7, 3.2, 3.3, 3.4 | 2.4.0 |x86,x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Windows 8 Pro | 2.6, 2.7, 3.2, 3.3, 3.4a3 | 2.2.0 |x86,x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Windows 7 Professional | 3.7 | 7.0.0 |x86,x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| Windows Server 2008 R2 Enterprise| 3.3 | |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
+----------------------------------+---------------------------+------------------+--------------+
| Operating system | | Tested Python | | Latest tested | | Tested |
| | | versions | | Pillow version | | processors |
+==================================+===========================+==================+==============+
| macOS 11.0 Big Sur | 3.7, 3.8, 3.9 | 8.2.0 |arm |
| +---------------------------+------------------+--------------+
| | 3.6, 3.7, 3.8, 3.9 | 8.2.0 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| macOS 10.15 Catalina | 3.6, 3.7, 3.8, 3.9 | 8.0.1 |x86-64 |
| +---------------------------+------------------+ |
| | 3.5 | 7.2.0 | |
+----------------------------------+---------------------------+------------------+--------------+
| macOS 10.14 Mojave | 3.5, 3.6, 3.7, 3.8 | 7.2.0 |x86-64 |
| +---------------------------+------------------+ |
| | 2.7 | 6.0.0 | |
| +---------------------------+------------------+ |
| | 3.4 | 5.4.1 | |
+----------------------------------+---------------------------+------------------+--------------+
| macOS 10.13 High Sierra | 2.7, 3.4, 3.5, 3.6 | 4.2.1 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| macOS 10.12 Sierra | 2.7, 3.4, 3.5, 3.6 | 4.1.1 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Mac OS X 10.11 El Capitan | 2.7, 3.4, 3.5, 3.6, 3.7 | 5.4.1 |x86-64 |
| +---------------------------+------------------+ |
| | 3.3 | 4.1.0 | |
+----------------------------------+---------------------------+------------------+--------------+
| Mac OS X 10.9 Mavericks | 2.7, 3.2, 3.3, 3.4 | 3.0.0 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Mac OS X 10.8 Mountain Lion | 2.6, 2.7, 3.2, 3.3 | |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Redhat Linux 6 | 2.6 | |x86 |
+----------------------------------+---------------------------+------------------+--------------+
| CentOS 6.3 | 2.7, 3.3 | |x86 |
+----------------------------------+---------------------------+------------------+--------------+
| Fedora 23 | 2.7, 3.4 | 3.1.0 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Ubuntu Linux 12.04 LTS (Precise) | | 2.6, 3.2, 3.3, 3.4, 3.5 | 3.4.1 |x86,x86-64 |
| | | PyPy5.3.1, PyPy3 v2.4.0 | | |
| +---------------------------+------------------+--------------+
| | 2.7 | 4.3.0 |x86-64 |
| +---------------------------+------------------+--------------+
| | 2.7, 3.2 | 3.4.1 |ppc |
+----------------------------------+---------------------------+------------------+--------------+
| Ubuntu Linux 10.04 LTS (Lucid) | 2.6 | 2.3.0 |x86,x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Debian 8.2 Jessie | 2.7, 3.4 | 3.1.0 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Raspbian Jessie | 2.7, 3.4 | 3.1.0 |arm |
+----------------------------------+---------------------------+------------------+--------------+
| Raspbian Stretch | 2.7, 3.5 | 4.0.0 |arm |
+----------------------------------+---------------------------+------------------+--------------+
| Raspberry Pi OS | 3.6, 3.7, 3.8, 3.9 | 8.2.0 |arm |
| +---------------------------+------------------+ |
| | 2.7 | 6.2.2 | |
+----------------------------------+---------------------------+------------------+--------------+
| Gentoo Linux | 2.7, 3.2 | 2.1.0 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| FreeBSD 11.1 | 2.7, 3.4, 3.5, 3.6 | 4.3.0 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| FreeBSD 10.3 | 2.7, 3.4, 3.5 | 4.2.0 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| FreeBSD 10.2 | 2.7, 3.4 | 3.1.0 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Windows 10 | 3.7 | 7.1.0 |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Windows 8.1 Pro | 2.6, 2.7, 3.2, 3.3, 3.4 | 2.4.0 |x86,x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Windows 8 Pro | 2.6, 2.7, 3.2, 3.3, 3.4a3 | 2.2.0 |x86,x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Windows 7 Professional | 3.7 | 7.0.0 |x86,x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
| Windows Server 2008 R2 Enterprise| 3.3 | |x86-64 |
+----------------------------------+---------------------------+------------------+--------------+
Old Versions
------------

View File

@ -9,10 +9,6 @@ represent the color palette of palette mapped images.
.. note::
This module was never well-documented. It hasn't changed since 2001,
though, so it's probably safe for you to read the source code and puzzle
out the internals if you need to.
The :py:class:`~PIL.ImagePalette.ImagePalette` class has several methods,
but they are all marked as "experimental." Read that as you will. The
``[source]`` link is there for a reason.

View File

@ -14,7 +14,7 @@ Png text chunk size limits
To prevent potential denial of service attacks using compressed text
chunks, there are now limits to the decompressed size of text chunks
decoded from PNG images. If the limits are exceeded when opening a PNG
image a ``ValueError`` will be raised.
image a :py:exc:`ValueError` will be raised.
Individual text chunks are limited to
:py:attr:`PIL.PngImagePlugin.MAX_TEXT_CHUNK`, set to 1MB by

View File

@ -0,0 +1,40 @@
8.3.1
-----
Fixed regression converting to NumPy arrays
===========================================
This fixes a regression introduced in 8.3.0 when converting an image to a NumPy array
with a ``dtype`` argument.
.. code-block:: pycon
>>> from PIL import Image
>>> import numpy
>>> im = Image.new("RGB", (100, 100))
>>> numpy.array(im, dtype=numpy.float64)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __array__() takes 1 positional argument but 2 were given
>>>
Catch OSError when checking if destination is sys.stdout
========================================================
In 8.3.0, a check to see if the destination was ``sys.stdout`` when saving an image was
updated. This lead to an OSError being raised if the environment restricted access.
The OSError is now silently caught.
Fixed removing orientation in ImageOps.exif_transpose
=====================================================
In 8.3.0, :py:meth:`~PIL.ImageOps.exif_transpose` was changed to ensure that the
original image EXIF data was not modified, and the orientation was only removed from
the modified copy.
However, for certain images the orientation was already missing from the modified
image, leading to a KeyError.
This error has been resolved, and the copying of metadata to the modified image
improved.

View File

@ -0,0 +1,41 @@
8.3.2
-----
Security
========
* :cve:`CVE-2021-23437`: Avoid a potential ReDoS (regular expression denial of service)
in :py:class:`~PIL.ImageColor`'s :py:meth:`~PIL.ImageColor.getrgb` by raising
:py:exc:`ValueError` if the color specifier is too long. Present since Pillow 5.2.0.
* Fix 6-byte out-of-bounds (OOB) read. The previous bounds check in ``FliDecode.c``
incorrectly calculated the required read buffer size when copying a chunk, potentially
reading six extra bytes off the end of the allocated buffer from the heap. Present
since Pillow 7.1.0. This bug was found by Google's `OSS-Fuzz`_ `CIFuzz`_ runs.
Other Changes
=============
Python 3.10 wheels
^^^^^^^^^^^^^^^^^^
Pillow now includes binary wheels for Python 3.10.
The Python 3.10 release candidate was released on 2021-08-03 with the final release due
2021-10-04 (:pep:`619`). The CPython core team strongly encourages maintainers of
third-party Python projects to prepare for 3.10 compatibility. And as there are `no ABI
changes`_ planned we are releasing wheels to help others prepare for 3.10, and ensure
Pillow can be used immediately on release day of 3.10.0 final.
Fixed regressions
^^^^^^^^^^^^^^^^^
* Ensure TIFF ``RowsPerStrip`` is multiple of 8 for JPEG compression (:pr:`5588`).
* Updates for :py:class:`~PIL.ImagePalette` channel order (:pr:`5599`).
* Hide FriBiDi shim symbols to avoid conflict with real FriBiDi library (:pr:`5651`).
.. _OSS-Fuzz: https://github.com/google/oss-fuzz
.. _CIFuzz: https://google.github.io/oss-fuzz/getting-started/continuous-integration/
.. _no ABI changes: https://www.python.org/downloads/release/python-3100rc1/

View File

@ -14,6 +14,8 @@ expected to be backported to earlier versions.
.. toctree::
:maxdepth: 2
8.3.2
8.3.1
8.3.0
8.2.0
8.1.2

View File

@ -0,0 +1,8 @@
th p {
margin-bottom: 0;
}
.rst-content tr .line-block {
font-size: 1rem;
margin-bottom: 0;
}

View File

@ -39,7 +39,7 @@ TIFF_ROOT = None
ZLIB_ROOT = None
FUZZING_BUILD = "LIB_FUZZING_ENGINE" in os.environ
if sys.platform == "win32" and sys.version_info >= (3, 10):
if sys.platform == "win32" and sys.version_info >= (3, 11):
import atexit
atexit.register(
@ -1002,6 +1002,7 @@ try:
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",

View File

@ -396,15 +396,7 @@ def _normalize_palette(im, palette, info):
if isinstance(palette, (bytes, bytearray, list)):
source_palette = bytearray(palette[:768])
if isinstance(palette, ImagePalette.ImagePalette):
source_palette = bytearray(
itertools.chain.from_iterable(
zip(
palette.palette[:256],
palette.palette[256:512],
palette.palette[512:768],
)
)
)
source_palette = bytearray(palette.palette)
if im.mode == "P":
if not source_palette:

View File

@ -681,7 +681,7 @@ class Image:
raise ValueError("Could not save to PNG for display") from e
return b.getvalue()
def __array__(self):
def __array__(self, dtype=None):
# numpy array interface support
import numpy as np
@ -700,7 +700,7 @@ class Image:
class ArrayData:
__array_interface__ = new
return np.array(ArrayData())
return np.array(ArrayData(), dtype)
def __getstate__(self):
return [self.info, self.mode, self.size, self.getpalette(), self.tobytes()]

View File

@ -32,6 +32,8 @@ def getrgb(color):
:param color: A color string
:return: ``(red, green, blue[, alpha])``
"""
if len(color) > 100:
raise ValueError("color specifier is too long")
color = color.lower()
rgb = colormap.get(color, None)

View File

@ -493,7 +493,11 @@ def _save(im, fp, tile, bufsize=0):
# 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
if fp == sys.stdout or (hasattr(sys.stdout, "buffer") and fp == sys.stdout.buffer):
try:
stdout = fp == sys.stdout or fp == sys.stdout.buffer
except (OSError, AttributeError):
stdout = False
if stdout:
fp.flush()
return
try:

View File

@ -19,6 +19,7 @@
import functools
import operator
import re
from . import Image, ImageDraw
@ -588,7 +589,19 @@ def exif_transpose(image):
if method is not None:
transposed_image = image.transpose(method)
transposed_exif = transposed_image.getexif()
del transposed_exif[0x0112]
transposed_image.info["exif"] = transposed_exif.tobytes()
if 0x0112 in transposed_exif:
del transposed_exif[0x0112]
if "exif" in transposed_image.info:
transposed_image.info["exif"] = transposed_exif.tobytes()
elif "Raw profile type exif" in transposed_image.info:
transposed_image.info[
"Raw profile type exif"
] = transposed_exif.tobytes().hex()
elif "XML:com.adobe.xmp" in transposed_image.info:
transposed_image.info["XML:com.adobe.xmp"] = re.sub(
r'tiff:Orientation="([0-9])"',
"",
transposed_image.info["XML:com.adobe.xmp"],
)
return transposed_image
return image.copy()

View File

@ -25,15 +25,14 @@ class ImagePalette:
"""
Color palette for palette mapped images
:param mode: The mode to use for the Palette. See:
:param mode: The mode to use for the palette. See:
:ref:`concept-modes`. Defaults to "RGB"
:param palette: An optional palette. If given, it must be a bytearray,
an array or a list of ints between 0-255 and of length ``size``
times the number of colors in ``mode``. The list must be aligned
by channel (All R values must be contiguous in the list before G
and B values.) Defaults to 0 through 255 per channel.
:param size: An optional palette size. If given, it cannot be equal to
or greater than 256. Defaults to 0.
an array or a list of ints between 0-255. The list must consist of
all channels for one color followed by the next color (e.g. RGBRGBRGB).
Defaults to an empty palette.
:param size: An optional palette size. If given, an error is raised
if ``palette`` is not of equal length.
"""
def __init__(self, mode="RGB", palette=None, size=0):
@ -205,9 +204,9 @@ def make_gamma_lut(exp):
def negative(mode="RGB"):
palette = list(range(256))
palette = list(range(256 * len(mode)))
palette.reverse()
return ImagePalette(mode, palette * len(mode))
return ImagePalette(mode, [i // len(mode) for i in palette])
def random(mode="RGB"):
@ -220,15 +219,13 @@ def random(mode="RGB"):
def sepia(white="#fff0c0"):
r, g, b = ImageColor.getrgb(white)
r = make_linear_lut(0, r)
g = make_linear_lut(0, g)
b = make_linear_lut(0, b)
return ImagePalette("RGB", r + g + b)
bands = [make_linear_lut(0, band) for band in ImageColor.getrgb(white)]
return ImagePalette("RGB", [bands[i % 3][i // 3] for i in range(256 * 3)])
def wedge(mode="RGB"):
return ImagePalette(mode, list(range(256)) * len(mode))
palette = list(range(256 * len(mode)))
return ImagePalette(mode, [i // len(mode) for i in palette])
def load(filename):

View File

@ -1577,6 +1577,9 @@ def _save(im, fp, filename):
# aim for 64 KB strips when using libtiff writer
if libtiff:
rows_per_strip = min((2 ** 16 + stride - 1) // stride, im.size[1])
# JPEG encoder expects multiple of 8 rows
if compression == "jpeg":
rows_per_strip = min(((rows_per_strip + 7) // 8) * 8, im.size[1])
else:
rows_per_strip = im.size[1]
strip_byte_counts = stride * rows_per_strip

View File

@ -1,2 +1,2 @@
# Master version for Pillow
__version__ = "8.3.0"
__version__ = "8.3.2"

View File

@ -223,8 +223,15 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t byt
break;
case 16:
/* COPY chunk */
if (state->xsize > bytes / state->ysize) {
if (INT32_MAX / state->xsize < state->ysize) {
/* Integer overflow, bail */
state->errcode = IMAGING_CODEC_OVERRUN;
return -1;
}
/* Note, have to check Data + size, not just ptr + size) */
if (data + (state->xsize * state->ysize) > ptr + bytes) {
/* not enough data for frame */
/* UNDONE Unclear that we're actually going to leave the buffer at the right place. */
return ptr - buf; /* bytes consumed */
}
for (y = 0; y < state->ysize; y++) {

View File

@ -12,7 +12,7 @@
/* FriBiDi>=1.0.0 adds bracket_types param, ignore and call legacy function */
FriBidiLevel fribidi_get_par_embedding_levels_ex_compat(
static FriBidiLevel fribidi_get_par_embedding_levels_ex_compat(
const FriBidiCharType *bidi_types,
const FriBidiBracketType *bracket_types,
const FriBidiStrIndex len,
@ -24,7 +24,7 @@ FriBidiLevel fribidi_get_par_embedding_levels_ex_compat(
}
/* FriBiDi>=1.0.0 gets bracket types here, ignore */
void fribidi_get_bracket_types_compat(
static void fribidi_get_bracket_types_compat(
const FriBidiChar *str,
const FriBidiStrIndex len,
const FriBidiCharType *types,

View File

@ -63,8 +63,12 @@ typedef uint32_t FriBidiParType;
/* functions */
#ifdef FRIBIDI_SHIM_IMPLEMENTATION
#ifdef _MSC_VER
#define FRIBIDI_ENTRY
#else
#define FRIBIDI_ENTRY __attribute__((visibility ("hidden")))
#endif
#else
#define FRIBIDI_ENTRY extern
#endif

View File

@ -6,7 +6,7 @@
[tox]
envlist =
lint
py{36,37,38,39,py3}
py{36,37,38,39,310,py3}
minversion = 1.9
[testenv]