Merge branch 'main' into parse-eps-trailer

This commit is contained in:
Andrew Murray 2023-09-22 16:16:26 +10:00
commit 4c9c7636be
17 changed files with 85 additions and 46 deletions

View File

@ -23,7 +23,7 @@ if [[ $(uname) != CYGWIN* ]]; then
sudo apt-get -qq install libfreetype6-dev liblcms2-dev python3-tk\ sudo apt-get -qq install libfreetype6-dev liblcms2-dev python3-tk\
ghostscript libffi-dev libjpeg-turbo-progs libopenjp2-7-dev\ ghostscript libffi-dev libjpeg-turbo-progs libopenjp2-7-dev\
cmake meson imagemagick libharfbuzz-dev libfribidi-dev\ cmake meson imagemagick libharfbuzz-dev libfribidi-dev\
sway wl-clipboard sway wl-clipboard libopenblas-dev
fi fi
python3 -m pip install --upgrade pip python3 -m pip install --upgrade pip
@ -38,8 +38,7 @@ python3 -m pip install -U pytest-timeout
python3 -m pip install pyroma python3 -m pip install pyroma
if [[ $(uname) != CYGWIN* ]]; then if [[ $(uname) != CYGWIN* ]]; then
# TODO Remove condition when NumPy supports 3.12 python3 -m pip install numpy
if ! [ "$GHA_PYTHON_VERSION" == "3.12-dev" ]; then python3 -m pip install numpy ; fi
# PyQt6 doesn't support PyPy3 # PyQt6 doesn't support PyPy3
if [[ $GHA_PYTHON_VERSION == 3.* ]]; then if [[ $GHA_PYTHON_VERSION == 3.* ]]; then

View File

@ -3,6 +3,7 @@
set -e set -e
brew install libtiff libjpeg openjpeg libimagequant webp little-cms2 freetype libraqm brew install libtiff libjpeg openjpeg libimagequant webp little-cms2 freetype libraqm
export PKG_CONFIG_PATH="/usr/local/opt/openblas/lib/pkgconfig"
PYTHONOPTIMIZE=0 python3 -m pip install cffi PYTHONOPTIMIZE=0 python3 -m pip install cffi
python3 -m pip install coverage python3 -m pip install coverage
@ -13,8 +14,7 @@ python3 -m pip install -U pytest-cov
python3 -m pip install -U pytest-timeout python3 -m pip install -U pytest-timeout
python3 -m pip install pyroma python3 -m pip install pyroma
# TODO Remove condition when NumPy supports 3.12 python3 -m pip install numpy
if ! [ "$GHA_PYTHON_VERSION" == "3.12-dev" ]; then python3 -m pip install numpy ; fi
# extra test images # extra test images
pushd depends && ./install_extra_test_images.sh && popd pushd depends && ./install_extra_test_images.sh && popd

View File

@ -102,10 +102,10 @@ jobs:
run: | run: |
bash.exe .ci/install.sh bash.exe .ci/install.sh
- name: Install latest NumPy - name: Upgrade NumPy
shell: dash.exe -l "{0}" shell: dash.exe -l "{0}"
run: | run: |
python3 -m pip install -U numpy python3 -m pip install -U "numpy<1.26"
- name: Build - name: Build
shell: bash.exe -eo pipefail -o igncr "{0}" shell: bash.exe -eo pipefail -o igncr "{0}"

View File

@ -5,6 +5,12 @@ Changelog (Pillow)
10.1.0 (unreleased) 10.1.0 (unreleased)
------------------- -------------------
- Fixed bug when reading BC5S DDS images #7401
[radarhere]
- Prevent TIFF orientation from being applied more than once #7383
[radarhere]
- Use previous pixel alpha for QOI_OP_RGB #7357 - Use previous pixel alpha for QOI_OP_RGB #7357
[radarhere] [radarhere]
@ -50,6 +56,15 @@ Changelog (Pillow)
- Fix missing symbols when libtiff depends on libjpeg #7270 - Fix missing symbols when libtiff depends on libjpeg #7270
[heitbaum] [heitbaum]
10.0.1 (2023-09-15)
-------------------
- Updated libwebp to 1.3.2 #7395
[radarhere]
- Updated zlib to 1.3 #7344
[radarhere]
10.0.0 (2023-07-01) 10.0.0 (2023-07-01)
------------------- -------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 95 KiB

View File

@ -8,7 +8,7 @@ from collections import namedtuple
import pytest import pytest
from PIL import Image, ImageFilter, TiffImagePlugin, TiffTags, features from PIL import Image, ImageFilter, ImageOps, TiffImagePlugin, TiffTags, features
from PIL.TiffImagePlugin import SAMPLEFORMAT, STRIPOFFSETS, SUBIFD from PIL.TiffImagePlugin import SAMPLEFORMAT, STRIPOFFSETS, SUBIFD
from .helper import ( from .helper import (
@ -1035,7 +1035,18 @@ class TestFileLibTiff(LibTiffTestCase):
with Image.open("Tests/images/g4_orientation_1.tif") as base_im: with Image.open("Tests/images/g4_orientation_1.tif") as base_im:
for i in range(2, 9): for i in range(2, 9):
with Image.open("Tests/images/g4_orientation_" + str(i) + ".tif") as im: with Image.open("Tests/images/g4_orientation_" + str(i) + ".tif") as im:
assert 274 in im.tag_v2
im.load() im.load()
assert 274 not in im.tag_v2
assert_image_similar(base_im, im, 0.7)
def test_exif_transpose(self):
with Image.open("Tests/images/g4_orientation_1.tif") as base_im:
for i in range(2, 9):
with Image.open("Tests/images/g4_orientation_" + str(i) + ".tif") as im:
im = ImageOps.exif_transpose(im)
assert_image_similar(base_im, im, 0.7) assert_image_similar(base_im, im, 0.7)

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# install libimagequant # install libimagequant
archive=libimagequant-4.2.0 archive=libimagequant-4.2.1
./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/main/$archive.tar.gz ./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/main/$archive.tar.gz

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# install webp # install webp
archive=libwebp-1.3.1 archive=libwebp-1.3.2
./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/main/$archive.tar.gz ./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/main/$archive.tar.gz

View File

@ -180,7 +180,7 @@ Many of Pillow's features require external libraries:
* **libimagequant** provides improved color quantization * **libimagequant** provides improved color quantization
* Pillow has been tested with libimagequant **2.6-4.2** * Pillow has been tested with libimagequant **2.6-4.2.1**
* Libimagequant is licensed GPLv3, which is more restrictive than * Libimagequant is licensed GPLv3, which is more restrictive than
the Pillow license, therefore we will not be distributing binaries the Pillow license, therefore we will not be distributing binaries
with libimagequant support enabled. with libimagequant support enabled.
@ -498,7 +498,7 @@ These platforms have been reported to work at the versions mentioned.
| Operating system | | Tested Python | | Latest tested | | Tested | | Operating system | | Tested Python | | Latest tested | | Tested |
| | | versions | | Pillow version | | processors | | | | versions | | Pillow version | | processors |
+==================================+===========================+==================+==============+ +==================================+===========================+==================+==============+
| macOS 13 Ventura | 3.8, 3.9, 3.10, 3.11 | 10.0.0 |arm | | macOS 13 Ventura | 3.8, 3.9, 3.10, 3.11 | 10.0.1 |arm |
| +---------------------------+------------------+ | | +---------------------------+------------------+ |
| | 3.7 | 9.5.0 | | | | 3.7 | 9.5.0 | |
+----------------------------------+---------------------------+------------------+--------------+ +----------------------------------+---------------------------+------------------+--------------+

View File

@ -93,10 +93,14 @@ Generating images
Registering plugins Registering plugins
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
.. autofunction:: preinit
.. autofunction:: init
.. note:: .. note::
These functions are for use by plugin authors. Application authors can These functions are for use by plugin authors. They are called when a
ignore them. plugin is loaded as part of :py:meth:`~preinit()` or :py:meth:`~init()`.
Application authors can ignore them.
.. autofunction:: register_open .. autofunction:: register_open
.. autofunction:: register_mime .. autofunction:: register_mime

View File

@ -0,0 +1,14 @@
10.0.1
------
Security
========
This release addresses :cve:`2023-4863`, by providing an updated install script and
updated wheels to include libwebp 1.3.2, preventing a potential heap buffer overflow
in WebP.
Updated tests to pass with latest zlib version
==============================================
The release of zlib 1.3 caused one of the tests in the Pillow test suite to fail.

View File

@ -15,6 +15,7 @@ expected to be backported to earlier versions.
:maxdepth: 2 :maxdepth: 2
10.1.0 10.1.0
10.0.1
10.0.0 10.0.0
9.5.0 9.5.0
9.4.0 9.4.0

View File

@ -298,7 +298,11 @@ _initialized = 0
def preinit(): def preinit():
"""Explicitly load standard file format drivers.""" """
Explicitly loads BMP, GIF, JPEG, PPM and PPM file format drivers.
It is called when opening or saving images.
"""
global _initialized global _initialized
if _initialized >= 1: if _initialized >= 1:
@ -334,11 +338,6 @@ def preinit():
assert PngImagePlugin assert PngImagePlugin
except ImportError: except ImportError:
pass pass
# try:
# import TiffImagePlugin
# assert TiffImagePlugin
# except ImportError:
# pass
_initialized = 1 _initialized = 1
@ -347,6 +346,9 @@ def init():
""" """
Explicitly initializes the Python Imaging Library. This function Explicitly initializes the Python Imaging Library. This function
loads all available file format drivers. loads all available file format drivers.
It is called when opening or saving images if :py:meth:`~preinit()` is
insufficient, and by :py:meth:`~PIL.features.pilinfo`.
""" """
global _initialized global _initialized
@ -3407,8 +3409,12 @@ def register_open(id, factory, accept=None):
def register_mime(id, mimetype): def register_mime(id, mimetype):
""" """
Registers an image MIME type. This function should not be used Registers an image MIME type by populating ``Image.MIME``. This function
in application code. should not be used in application code.
``Image.MIME`` provides a mapping from image format identifiers to mime
formats, but :py:meth:`~PIL.ImageFile.ImageFile.get_format_mimetype` can
provide a different result for specific images.
:param id: An image format identifier. :param id: An image format identifier.
:param mimetype: The image MIME type for this format. :param mimetype: The image MIME type for this format.

View File

@ -588,6 +588,7 @@ def exif_transpose(image, *, in_place=False):
with the transposition applied. If there is no transposition, a copy of the with the transposition applied. If there is no transposition, a copy of the
image will be returned. image will be returned.
""" """
image.load()
image_exif = image.getexif() image_exif = image.getexif()
orientation = image_exif.get(ExifTags.Base.Orientation) orientation = image_exif.get(ExifTags.Base.Orientation)
method = { method = {

View File

@ -1203,20 +1203,6 @@ class TiffImageFile(ImageFile.ImageFile):
return super().load() return super().load()
def load_end(self): def load_end(self):
if self._tile_orientation:
method = {
2: Image.Transpose.FLIP_LEFT_RIGHT,
3: Image.Transpose.ROTATE_180,
4: Image.Transpose.FLIP_TOP_BOTTOM,
5: Image.Transpose.TRANSPOSE,
6: Image.Transpose.ROTATE_270,
7: Image.Transpose.TRANSVERSE,
8: Image.Transpose.ROTATE_90,
}.get(self._tile_orientation)
if method is not None:
self.im = self.im.transpose(method)
self._size = self.im.size
# allow closing if we're on the first frame, there's no next # allow closing if we're on the first frame, there's no next
# This is the ImageFile.load path only, libtiff specific below. # This is the ImageFile.load path only, libtiff specific below.
if not self.is_animated: if not self.is_animated:
@ -1233,6 +1219,10 @@ class TiffImageFile(ImageFile.ImageFile):
continue continue
exif.get_ifd(key) exif.get_ifd(key)
ImageOps.exif_transpose(self, in_place=True)
if ExifTags.Base.Orientation in self.tag_v2:
del self.tag_v2[ExifTags.Base.Orientation]
def _load_libtiff(self): def _load_libtiff(self):
"""Overload method triggered when we detect a compressed tiff """Overload method triggered when we detect a compressed tiff
Calls out to libtiff""" Calls out to libtiff"""
@ -1542,8 +1532,6 @@ class TiffImageFile(ImageFile.ImageFile):
palette = [o8(b // 256) for b in self.tag_v2[COLORMAP]] palette = [o8(b // 256) for b in self.tag_v2[COLORMAP]]
self.palette = ImagePalette.raw("RGB;L", b"".join(palette)) self.palette = ImagePalette.raw("RGB;L", b"".join(palette))
self._tile_orientation = self.tag_v2.get(ExifTags.Base.Orientation)
# #
# -------------------------------------------------------------------- # --------------------------------------------------------------------

View File

@ -118,8 +118,8 @@ decode_bc3_alpha(char *dst, const UINT8 *src, int stride, int o, int sign) {
if (sign == 1) { if (sign == 1) {
bc5s_alpha b; bc5s_alpha b;
memcpy(&b, src, sizeof(bc5s_alpha)); memcpy(&b, src, sizeof(bc5s_alpha));
a0 = (b.a0 + 255) / 2; a0 = b.a0 + 128;
a1 = (b.a1 + 255) / 2; a1 = b.a1 + 128;
lut1 = b.lut[0] | (b.lut[1] << 8) | (b.lut[2] << 16); lut1 = b.lut[0] | (b.lut[1] << 8) | (b.lut[2] << 16);
lut2 = b.lut[3] | (b.lut[4] << 8) | (b.lut[5] << 16); lut2 = b.lut[3] | (b.lut[4] << 8) | (b.lut[5] << 16);
} else { } else {

View File

@ -157,9 +157,9 @@ deps = {
"libs": [r"liblzma.lib"], "libs": [r"liblzma.lib"],
}, },
"libwebp": { "libwebp": {
"url": "http://downloads.webmproject.org/releases/webp/libwebp-1.3.1.tar.gz", "url": "http://downloads.webmproject.org/releases/webp/libwebp-1.3.2.tar.gz",
"filename": "libwebp-1.3.1.tar.gz", "filename": "libwebp-1.3.2.tar.gz",
"dir": "libwebp-1.3.1", "dir": "libwebp-1.3.2",
"license": "COPYING", "license": "COPYING",
"build": [ "build": [
cmd_rmdir(r"output\release-static"), # clean cmd_rmdir(r"output\release-static"), # clean
@ -335,9 +335,9 @@ deps = {
"libs": [r"imagequant.lib"], "libs": [r"imagequant.lib"],
}, },
"harfbuzz": { "harfbuzz": {
"url": "https://github.com/harfbuzz/harfbuzz/archive/8.1.1.zip", "url": "https://github.com/harfbuzz/harfbuzz/archive/8.2.0.zip",
"filename": "harfbuzz-8.1.1.zip", "filename": "harfbuzz-8.2.0.zip",
"dir": "harfbuzz-8.1.1", "dir": "harfbuzz-8.2.0",
"license": "COPYING", "license": "COPYING",
"build": [ "build": [
*cmds_cmake( *cmds_cmake(