mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-24 17:06:16 +03:00
Merge branch 'main' into bytes_tests
This commit is contained in:
commit
60976c8dbe
|
@ -1,3 +1,10 @@
|
|||
skip_commits:
|
||||
files:
|
||||
- ".github/**"
|
||||
- ".gitmodules"
|
||||
- "docs/**"
|
||||
- "wheels/**"
|
||||
|
||||
version: '{build}'
|
||||
clone_folder: c:\pillow
|
||||
init:
|
||||
|
@ -27,7 +34,7 @@ install:
|
|||
- xcopy /S /Y c:\test-images-main\* c:\pillow\tests\images
|
||||
- curl -fsSL -o nasm-win64.zip https://raw.githubusercontent.com/python-pillow/pillow-depends/main/nasm-2.16.01-win64.zip
|
||||
- 7z x nasm-win64.zip -oc:\
|
||||
- choco install ghostscript --version=10.0.0.20230317
|
||||
- choco install ghostscript --version=10.3.0
|
||||
- path c:\nasm-2.16.01;C:\Program Files\gs\gs10.00.0\bin;%PATH%
|
||||
- cd c:\pillow\winbuild\
|
||||
- ps: |
|
||||
|
|
|
@ -1 +1 @@
|
|||
cibuildwheel==2.16.5
|
||||
cibuildwheel==2.17.0
|
||||
|
|
20
.github/workflows/test-cygwin.yml
vendored
20
.github/workflows/test-cygwin.yml
vendored
|
@ -50,7 +50,7 @@ jobs:
|
|||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Cygwin
|
||||
uses: egor-tensin/setup-cygwin@v4
|
||||
uses: cygwin/cygwin-install-action@v4
|
||||
with:
|
||||
packages: >
|
||||
gcc-g++
|
||||
|
@ -71,7 +71,6 @@ jobs:
|
|||
make
|
||||
netpbm
|
||||
perl
|
||||
python39=3.9.16-1
|
||||
python3${{ matrix.python-minor-version }}-cffi
|
||||
python3${{ matrix.python-minor-version }}-cython
|
||||
python3${{ matrix.python-minor-version }}-devel
|
||||
|
@ -89,21 +88,15 @@ jobs:
|
|||
|
||||
- name: Select Python version
|
||||
run: |
|
||||
ln -sf c:/tools/cygwin/bin/python3.${{ matrix.python-minor-version }} c:/tools/cygwin/bin/python3
|
||||
|
||||
- name: Get latest NumPy version
|
||||
id: latest-numpy
|
||||
shell: bash.exe -eo pipefail -o igncr "{0}"
|
||||
run: |
|
||||
python3 -m pip list --outdated | grep numpy | sed -r 's/ +/ /g' | cut -d ' ' -f 3 | sed 's/^/version=/' >> $GITHUB_OUTPUT
|
||||
ln -sf c:/cygwin/bin/python3.${{ matrix.python-minor-version }} c:/cygwin/bin/python3
|
||||
|
||||
- name: pip cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: 'C:\cygwin\home\runneradmin\.cache\pip'
|
||||
key: ${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-numpy${{ steps.latest-numpy.outputs.version }}-${{ hashFiles('.ci/install.sh') }}
|
||||
key: ${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-${{ hashFiles('.ci/install.sh') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-numpy${{ steps.latest-numpy.outputs.version }}-
|
||||
${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-
|
||||
|
||||
- name: Build system information
|
||||
run: |
|
||||
|
@ -113,11 +106,6 @@ jobs:
|
|||
run: |
|
||||
bash.exe .ci/install.sh
|
||||
|
||||
- name: Upgrade NumPy
|
||||
shell: dash.exe -l "{0}"
|
||||
run: |
|
||||
python3 -m pip install -U "numpy<1.26"
|
||||
|
||||
- name: Build
|
||||
shell: bash.exe -eo pipefail -o igncr "{0}"
|
||||
run: |
|
||||
|
|
4
.github/workflows/test-windows.yml
vendored
4
.github/workflows/test-windows.yml
vendored
|
@ -35,7 +35,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["pypy3.10", "pypy3.9", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13.0-alpha.3"]
|
||||
python-version: ["pypy3.10", "pypy3.9", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||
|
||||
timeout-minutes: 30
|
||||
|
||||
|
@ -86,7 +86,7 @@ jobs:
|
|||
choco install nasm --no-progress
|
||||
echo "C:\Program Files\NASM" >> $env:GITHUB_PATH
|
||||
|
||||
choco install ghostscript --version=10.0.0.20230317 --no-progress
|
||||
choco install ghostscript --version=10.3.0 --no-progress
|
||||
echo "C:\Program Files\gs\gs10.00.0\bin" >> $env:GITHUB_PATH
|
||||
|
||||
# Install extra test images
|
||||
|
|
4
.github/workflows/wheels-dependencies.sh
vendored
4
.github/workflows/wheels-dependencies.sh
vendored
|
@ -16,7 +16,7 @@ ARCHIVE_SDIR=pillow-depends-main
|
|||
|
||||
# Package versions for fresh source builds
|
||||
FREETYPE_VERSION=2.13.2
|
||||
HARFBUZZ_VERSION=8.3.0
|
||||
HARFBUZZ_VERSION=8.3.1
|
||||
LIBPNG_VERSION=1.6.43
|
||||
JPEGTURBO_VERSION=3.0.2
|
||||
OPENJPEG_VERSION=2.5.2
|
||||
|
@ -72,7 +72,7 @@ function build {
|
|||
|
||||
build_simple xcb-proto 1.16.0 https://xorg.freedesktop.org/archive/individual/proto
|
||||
if [ -n "$IS_MACOS" ]; then
|
||||
build_simple xorgproto 2023.2 https://www.x.org/pub/individual/proto
|
||||
build_simple xorgproto 2024.1 https://www.x.org/pub/individual/proto
|
||||
build_simple libXau 1.0.11 https://www.x.org/pub/individual/lib
|
||||
build_simple libpthread-stubs 0.5 https://xcb.freedesktop.org/dist
|
||||
if [[ "$CIBW_ARCHS" == "arm64" ]]; then
|
||||
|
|
54
CHANGES.rst
54
CHANGES.rst
|
@ -5,6 +5,60 @@ Changelog (Pillow)
|
|||
10.3.0 (unreleased)
|
||||
-------------------
|
||||
|
||||
- Use I;16 mode for 9-bit JPEG 2000 images #7900
|
||||
[scaramallion, radarhere]
|
||||
|
||||
- Raise ValueError if kmeans is negative #7891
|
||||
[radarhere]
|
||||
|
||||
- Remove TIFF tag OSUBFILETYPE when saving using libtiff #7893
|
||||
[radarhere]
|
||||
|
||||
- Raise ValueError for negative values when loading P1-P3 PPM images #7882
|
||||
[radarhere]
|
||||
|
||||
- Added reading of JPEG2000 palettes #7870
|
||||
[radarhere]
|
||||
|
||||
- Added alpha_quality argument when saving WebP images #7872
|
||||
[radarhere]
|
||||
|
||||
- Fixed joined corners for ImageDraw rounded_rectangle() non-integer dimensions #7881
|
||||
[radarhere]
|
||||
|
||||
- Stop reading EPS image at EOF marker #7753
|
||||
[radarhere]
|
||||
|
||||
- PSD layer co-ordinates may be negative #7706
|
||||
[radarhere]
|
||||
|
||||
- Use subprocess with CREATE_NO_WINDOW flag in ImageShow WindowsViewer #7791
|
||||
[radarhere]
|
||||
|
||||
- When saving GIF frame that restores to background color, do not fill identical pixels #7788
|
||||
[radarhere]
|
||||
|
||||
- Fixed reading PNG iCCP compression method #7823
|
||||
[radarhere]
|
||||
|
||||
- Allow writing IFDRational to UNDEFINED tag #7840
|
||||
[radarhere]
|
||||
|
||||
- Fix logged tag name when loading Exif data #7842
|
||||
[radarhere]
|
||||
|
||||
- Use maximum frame size in IHDR chunk when saving APNG images #7821
|
||||
[radarhere]
|
||||
|
||||
- Prevent opening P TGA images without a palette #7797
|
||||
[radarhere]
|
||||
|
||||
- Use palette when loading ICO images #7798
|
||||
[radarhere]
|
||||
|
||||
- Use consistent arguments for load_read and load_seek #7713
|
||||
[radarhere]
|
||||
|
||||
- Turn off nullability warnings for macOS SDK #7827
|
||||
[radarhere]
|
||||
|
||||
|
|
4
LICENSE
4
LICENSE
|
@ -1,11 +1,11 @@
|
|||
The Python Imaging Library (PIL) is
|
||||
|
||||
Copyright © 1997-2011 by Secret Labs AB
|
||||
Copyright © 1995-2011 by Fredrik Lundh
|
||||
Copyright © 1995-2011 by Fredrik Lundh and contributors
|
||||
|
||||
Pillow is the friendly PIL fork. It is
|
||||
|
||||
Copyright © 2010-2024 by Jeffrey A. Clark (Alex) and contributors.
|
||||
Copyright © 2010-2024 by Jeffrey A. Clark and contributors
|
||||
|
||||
Like PIL, Pillow is licensed under the open source HPND License:
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
## Python Imaging Library (Fork)
|
||||
|
||||
Pillow is the friendly PIL fork by [Jeffrey A. Clark (Alex) and
|
||||
Pillow is the friendly PIL fork by [Jeffrey A. Clark and
|
||||
contributors](https://github.com/python-pillow/Pillow/graphs/contributors).
|
||||
PIL is the Python Imaging Library by Fredrik Lundh and Contributors.
|
||||
PIL is the Python Imaging Library by Fredrik Lundh and contributors.
|
||||
As of 2019, Pillow development is
|
||||
[supported by Tidelift](https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=readme&utm_campaign=enterprise).
|
||||
|
||||
|
|
BIN
Tests/images/9bit.j2k
Normal file
BIN
Tests/images/9bit.j2k
Normal file
Binary file not shown.
BIN
Tests/images/m13.fits
Normal file
BIN
Tests/images/m13.fits
Normal file
Binary file not shown.
366
Tests/images/m13_gzip.fits
Normal file
366
Tests/images/m13_gzip.fits
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |
|
@ -7,7 +7,7 @@ import fuzzers
|
|||
import packaging
|
||||
import pytest
|
||||
|
||||
from PIL import Image, features
|
||||
from PIL import Image, UnidentifiedImageError, features
|
||||
from Tests.helper import skip_unless_feature
|
||||
|
||||
if sys.platform.startswith("win32"):
|
||||
|
@ -43,7 +43,7 @@ def test_fuzz_images(path: str) -> None:
|
|||
except (
|
||||
Image.DecompressionBombError,
|
||||
Image.DecompressionBombWarning,
|
||||
Image.UnidentifiedImageError,
|
||||
UnidentifiedImageError,
|
||||
):
|
||||
# Known Image.* exceptions
|
||||
assert True
|
||||
|
|
|
@ -5,7 +5,7 @@ from pathlib import Path
|
|||
|
||||
import pytest
|
||||
|
||||
from PIL import EpsImagePlugin, Image, features
|
||||
from PIL import EpsImagePlugin, Image, UnidentifiedImageError, features
|
||||
|
||||
from .helper import (
|
||||
assert_image_similar,
|
||||
|
@ -419,7 +419,7 @@ def test_emptyline() -> None:
|
|||
)
|
||||
def test_timeout(test_file: str) -> None:
|
||||
with open(test_file, "rb") as f:
|
||||
with pytest.raises(Image.UnidentifiedImageError):
|
||||
with pytest.raises(UnidentifiedImageError):
|
||||
with Image.open(f):
|
||||
pass
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import pytest
|
|||
|
||||
from PIL import FitsImagePlugin, Image
|
||||
|
||||
from .helper import assert_image_equal, hopper
|
||||
from .helper import assert_image_equal, assert_image_equal_tofile, hopper
|
||||
|
||||
TEST_FILE = "Tests/images/hopper.fits"
|
||||
|
||||
|
@ -22,6 +22,11 @@ def test_open() -> None:
|
|||
assert_image_equal(im, hopper("L"))
|
||||
|
||||
|
||||
def test_gzip1() -> None:
|
||||
with Image.open("Tests/images/m13_gzip.fits") as im:
|
||||
assert_image_equal_tofile(im, "Tests/images/m13.fits")
|
||||
|
||||
|
||||
def test_invalid_file() -> None:
|
||||
# Arrange
|
||||
invalid_file = "Tests/images/flower.jpg"
|
||||
|
|
|
@ -364,6 +364,16 @@ def test_subsampling_decode(name: str) -> None:
|
|||
assert_image_similar(im, expected, epsilon)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not os.path.exists(EXTRA_DIR), reason="Extra image files not installed"
|
||||
)
|
||||
def test_pclr() -> None:
|
||||
with Image.open(f"{EXTRA_DIR}/issue104_jpxstream.jp2") as im:
|
||||
assert im.mode == "P"
|
||||
assert len(im.palette.colors) == 256
|
||||
assert im.palette.colors[(255, 255, 255)] == 0
|
||||
|
||||
|
||||
def test_comment() -> None:
|
||||
with Image.open("Tests/images/comment.jp2") as im:
|
||||
assert im.info["comment"] == b"Created by OpenJPEG version 2.5.0"
|
||||
|
@ -436,3 +446,9 @@ def test_plt_marker() -> None:
|
|||
hdr = out.read(2)
|
||||
length = _binary.i16be(hdr)
|
||||
out.seek(length - 2, os.SEEK_CUR)
|
||||
|
||||
|
||||
def test_9bit():
|
||||
with Image.open("Tests/images/9bit.j2k") as im:
|
||||
assert im.mode == "I;16"
|
||||
assert im.size == (128, 128)
|
||||
|
|
|
@ -6,13 +6,13 @@ import itertools
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
from pathlib import Path
|
||||
from typing import Any, NamedTuple
|
||||
|
||||
import pytest
|
||||
|
||||
from PIL import Image, ImageFilter, ImageOps, TiffImagePlugin, TiffTags, features
|
||||
from PIL.TiffImagePlugin import SAMPLEFORMAT, STRIPOFFSETS, SUBIFD
|
||||
from PIL.TiffImagePlugin import OSUBFILETYPE, SAMPLEFORMAT, STRIPOFFSETS, SUBIFD
|
||||
|
||||
from .helper import (
|
||||
assert_image_equal,
|
||||
|
@ -243,36 +243,40 @@ class TestFileLibTiff(LibTiffTestCase):
|
|||
TiffImagePlugin.WRITE_LIBTIFF = False
|
||||
|
||||
def test_custom_metadata(self, tmp_path: Path) -> None:
|
||||
tc = namedtuple("tc", "value,type,supported_by_default")
|
||||
class Tc(NamedTuple):
|
||||
value: Any
|
||||
type: int
|
||||
supported_by_default: bool
|
||||
|
||||
custom = {
|
||||
37000 + k: v
|
||||
for k, v in enumerate(
|
||||
[
|
||||
tc(4, TiffTags.SHORT, True),
|
||||
tc(123456789, TiffTags.LONG, True),
|
||||
tc(-4, TiffTags.SIGNED_BYTE, False),
|
||||
tc(-4, TiffTags.SIGNED_SHORT, False),
|
||||
tc(-123456789, TiffTags.SIGNED_LONG, False),
|
||||
tc(TiffImagePlugin.IFDRational(4, 7), TiffTags.RATIONAL, True),
|
||||
tc(4.25, TiffTags.FLOAT, True),
|
||||
tc(4.25, TiffTags.DOUBLE, True),
|
||||
tc("custom tag value", TiffTags.ASCII, True),
|
||||
tc(b"custom tag value", TiffTags.BYTE, True),
|
||||
tc((4, 5, 6), TiffTags.SHORT, True),
|
||||
tc((123456789, 9, 34, 234, 219387, 92432323), TiffTags.LONG, True),
|
||||
tc((-4, 9, 10), TiffTags.SIGNED_BYTE, False),
|
||||
tc((-4, 5, 6), TiffTags.SIGNED_SHORT, False),
|
||||
tc(
|
||||
Tc(4, TiffTags.SHORT, True),
|
||||
Tc(123456789, TiffTags.LONG, True),
|
||||
Tc(-4, TiffTags.SIGNED_BYTE, False),
|
||||
Tc(-4, TiffTags.SIGNED_SHORT, False),
|
||||
Tc(-123456789, TiffTags.SIGNED_LONG, False),
|
||||
Tc(TiffImagePlugin.IFDRational(4, 7), TiffTags.RATIONAL, True),
|
||||
Tc(4.25, TiffTags.FLOAT, True),
|
||||
Tc(4.25, TiffTags.DOUBLE, True),
|
||||
Tc("custom tag value", TiffTags.ASCII, True),
|
||||
Tc(b"custom tag value", TiffTags.BYTE, True),
|
||||
Tc((4, 5, 6), TiffTags.SHORT, True),
|
||||
Tc((123456789, 9, 34, 234, 219387, 92432323), TiffTags.LONG, True),
|
||||
Tc((-4, 9, 10), TiffTags.SIGNED_BYTE, False),
|
||||
Tc((-4, 5, 6), TiffTags.SIGNED_SHORT, False),
|
||||
Tc(
|
||||
(-123456789, 9, 34, 234, 219387, -92432323),
|
||||
TiffTags.SIGNED_LONG,
|
||||
False,
|
||||
),
|
||||
tc((4.25, 5.25), TiffTags.FLOAT, True),
|
||||
tc((4.25, 5.25), TiffTags.DOUBLE, True),
|
||||
Tc((4.25, 5.25), TiffTags.FLOAT, True),
|
||||
Tc((4.25, 5.25), TiffTags.DOUBLE, True),
|
||||
# array of TIFF_BYTE requires bytes instead of tuple for backwards
|
||||
# compatibility
|
||||
tc(bytes([4]), TiffTags.BYTE, True),
|
||||
tc(bytes((4, 9, 10)), TiffTags.BYTE, True),
|
||||
Tc(bytes([4]), TiffTags.BYTE, True),
|
||||
Tc(bytes((4, 9, 10)), TiffTags.BYTE, True),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
@ -325,6 +329,12 @@ class TestFileLibTiff(LibTiffTestCase):
|
|||
)
|
||||
TiffImagePlugin.WRITE_LIBTIFF = False
|
||||
|
||||
def test_osubfiletype(self, tmp_path: Path) -> None:
|
||||
outfile = str(tmp_path / "temp.tif")
|
||||
with Image.open("Tests/images/g4_orientation_6.tif") as im:
|
||||
im.tag_v2[OSUBFILETYPE] = 1
|
||||
im.save(outfile)
|
||||
|
||||
def test_subifd(self, tmp_path: Path) -> None:
|
||||
outfile = str(tmp_path / "temp.tif")
|
||||
with Image.open("Tests/images/g4_orientation_6.tif") as im:
|
||||
|
|
|
@ -93,7 +93,7 @@ def test_exif(test_file: str) -> None:
|
|||
|
||||
def test_frame_size() -> None:
|
||||
# This image has been hexedited to contain a different size
|
||||
# in the EXIF data of the second frame
|
||||
# in the SOF marker of the second frame
|
||||
with Image.open("Tests/images/sugarshack_frame_size.mpo") as im:
|
||||
assert im.size == (640, 480)
|
||||
|
||||
|
|
|
@ -241,13 +241,23 @@ def test_plain_ppm_token_too_long(tmp_path: Path, data: bytes) -> None:
|
|||
im.load()
|
||||
|
||||
|
||||
def test_plain_ppm_value_negative(tmp_path: Path) -> None:
|
||||
path = str(tmp_path / "temp.ppm")
|
||||
with open(path, "wb") as f:
|
||||
f.write(b"P3\n128 128\n255\n-1")
|
||||
|
||||
with Image.open(path) as im:
|
||||
with pytest.raises(ValueError, match="Channel value is negative"):
|
||||
im.load()
|
||||
|
||||
|
||||
def test_plain_ppm_value_too_large(tmp_path: Path) -> None:
|
||||
path = str(tmp_path / "temp.ppm")
|
||||
with open(path, "wb") as f:
|
||||
f.write(b"P3\n128 128\n255\n256")
|
||||
|
||||
with Image.open(path) as im:
|
||||
with pytest.raises(ValueError):
|
||||
with pytest.raises(ValueError, match="Channel value too large"):
|
||||
im.load()
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import warnings
|
|||
|
||||
import pytest
|
||||
|
||||
from PIL import Image, PsdImagePlugin
|
||||
from PIL import Image, PsdImagePlugin, UnidentifiedImageError
|
||||
|
||||
from .helper import assert_image_equal_tofile, assert_image_similar, hopper, is_pypy
|
||||
|
||||
|
@ -152,11 +152,11 @@ def test_combined_larger_than_size() -> None:
|
|||
[
|
||||
(
|
||||
"Tests/images/timeout-1ee28a249896e05b83840ae8140622de8e648ba9.psd",
|
||||
Image.UnidentifiedImageError,
|
||||
UnidentifiedImageError,
|
||||
),
|
||||
(
|
||||
"Tests/images/timeout-598843abc37fc080ec36a2699ebbd44f795d3a6f.psd",
|
||||
Image.UnidentifiedImageError,
|
||||
UnidentifiedImageError,
|
||||
),
|
||||
("Tests/images/timeout-c8efc3fded6426986ba867a399791bae544f59bc.psd", OSError),
|
||||
("Tests/images/timeout-dedc7a4ebd856d79b4359bbcc79e8ef231ce38f6.psd", OSError),
|
||||
|
|
|
@ -151,3 +151,15 @@ def test_write_unsupported_mode_PA(tmp_path: Path) -> None:
|
|||
target = im.convert("RGBA")
|
||||
|
||||
assert_image_similar(image, target, 25.0)
|
||||
|
||||
|
||||
def test_alpha_quality(tmp_path: Path) -> None:
|
||||
with Image.open("Tests/images/transparent.png") as im:
|
||||
out = str(tmp_path / "temp.webp")
|
||||
im.save(out)
|
||||
|
||||
out_quality = str(tmp_path / "quality.webp")
|
||||
im.save(out_quality, alpha_quality=50)
|
||||
with Image.open(out) as reloaded:
|
||||
with Image.open(out_quality) as reloaded_quality:
|
||||
assert reloaded.tobytes() != reloaded_quality.tobytes()
|
||||
|
|
|
@ -188,3 +188,21 @@ def test_seek_errors() -> None:
|
|||
|
||||
with pytest.raises(EOFError):
|
||||
im.seek(42)
|
||||
|
||||
|
||||
def test_alpha_quality(tmp_path: Path) -> None:
|
||||
with Image.open("Tests/images/transparent.png") as im:
|
||||
first_frame = Image.new("L", im.size)
|
||||
|
||||
out = str(tmp_path / "temp.webp")
|
||||
first_frame.save(out, save_all=True, append_images=[im])
|
||||
|
||||
out_quality = str(tmp_path / "quality.webp")
|
||||
first_frame.save(
|
||||
out_quality, save_all=True, append_images=[im], alpha_quality=50
|
||||
)
|
||||
with Image.open(out) as reloaded:
|
||||
reloaded.seek(1)
|
||||
with Image.open(out_quality) as reloaded_quality:
|
||||
reloaded_quality.seek(1)
|
||||
assert reloaded.tobytes() != reloaded_quality.tobytes()
|
||||
|
|
|
@ -183,6 +183,14 @@ def test_trns_RGB(tmp_path: Path) -> None:
|
|||
assert im_l.info["transparency"] == im_l.getpixel((0, 0)) # undone
|
||||
im_l.save(f)
|
||||
|
||||
im_la = im.convert("LA")
|
||||
assert "transparency" not in im_la.info
|
||||
im_la.save(f)
|
||||
|
||||
im_la = im.convert("La")
|
||||
assert "transparency" not in im_la.info
|
||||
assert im_la.getpixel((0, 0)) == (0, 0)
|
||||
|
||||
im_p = im.convert("P")
|
||||
assert "transparency" in im_p.info
|
||||
im_p.save(f)
|
||||
|
@ -191,6 +199,10 @@ def test_trns_RGB(tmp_path: Path) -> None:
|
|||
assert "transparency" not in im_rgba.info
|
||||
im_rgba.save(f)
|
||||
|
||||
im_rgba = im.convert("RGBa")
|
||||
assert "transparency" not in im_rgba.info
|
||||
assert im_rgba.getpixel((0, 0)) == (0, 0, 0, 0)
|
||||
|
||||
im_p = pytest.warns(UserWarning, im.convert, "P", palette=Image.Palette.ADAPTIVE)
|
||||
assert "transparency" not in im_p.info
|
||||
im_p.save(f)
|
||||
|
|
|
@ -16,11 +16,13 @@ pytestmark = pytest.mark.skipif(
|
|||
not ImageQt.qt_is_installed, reason="Qt bindings are not installed"
|
||||
)
|
||||
|
||||
ims = [
|
||||
hopper(),
|
||||
Image.open("Tests/images/transparent.png"),
|
||||
Image.open("Tests/images/7x13.png"),
|
||||
]
|
||||
ims: list[Image.Image] = []
|
||||
|
||||
|
||||
def setup_module() -> None:
|
||||
ims.append(hopper())
|
||||
ims.append(Image.open("Tests/images/transparent.png"))
|
||||
ims.append(Image.open("Tests/images/7x13.png"))
|
||||
|
||||
|
||||
def teardown_module() -> None:
|
||||
|
|
|
@ -94,6 +94,19 @@ def test_quantize_dither_diff() -> None:
|
|||
assert dither.tobytes() != nodither.tobytes()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"method", (Image.Quantize.MEDIANCUT, Image.Quantize.MAXCOVERAGE)
|
||||
)
|
||||
def test_quantize_kmeans(method) -> None:
|
||||
im = hopper()
|
||||
no_kmeans = im.quantize(kmeans=0, method=method)
|
||||
kmeans = im.quantize(kmeans=1, method=method)
|
||||
assert kmeans.tobytes() != no_kmeans.tobytes()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
im.quantize(kmeans=-1, method=method)
|
||||
|
||||
|
||||
def test_colors() -> None:
|
||||
im = hopper()
|
||||
colors = 2
|
||||
|
|
|
@ -868,8 +868,10 @@ def test_rounded_rectangle_zero_radius(bbox: Coords) -> None:
|
|||
[
|
||||
((20, 10, 80, 90), "x"),
|
||||
((20, 10, 81, 90), "x_odd"),
|
||||
((20, 10, 81.1, 90), "x_odd"),
|
||||
((10, 20, 90, 80), "y"),
|
||||
((10, 20, 90, 81), "y_odd"),
|
||||
((10, 20, 90, 81.1), "y_odd"),
|
||||
((20, 20, 80, 80), "both"),
|
||||
],
|
||||
)
|
||||
|
|
|
@ -15,7 +15,7 @@ class TestLibPack:
|
|||
mode: str,
|
||||
rawmode: str,
|
||||
data: int | bytes,
|
||||
*pixels: int | float | tuple[int, ...],
|
||||
*pixels: float | tuple[int, ...],
|
||||
) -> None:
|
||||
"""
|
||||
data - either raw bytes with data or just number of bytes in rawmode.
|
||||
|
@ -239,7 +239,7 @@ class TestLibUnpack:
|
|||
mode: str,
|
||||
rawmode: str,
|
||||
data: int | bytes,
|
||||
*pixels: int | float | tuple[int, ...],
|
||||
*pixels: float | tuple[int, ...],
|
||||
) -> None:
|
||||
"""
|
||||
data - either raw bytes with data or just number of bytes in rawmode.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
The Python Imaging Library (PIL) is
|
||||
|
||||
Copyright © 1997-2011 by Secret Labs AB
|
||||
Copyright © 1995-2011 by Fredrik Lundh
|
||||
Copyright © 1995-2011 by Fredrik Lundh and contributors
|
||||
|
||||
Pillow is the friendly PIL fork. It is
|
||||
|
||||
Copyright © 2010-2024 by Jeffrey A. Clark (Alex) and contributors
|
||||
Copyright © 2010-2024 by Jeffrey A. Clark and contributors
|
||||
|
||||
Like PIL, Pillow is licensed under the open source PIL
|
||||
Software License:
|
||||
|
|
|
@ -54,9 +54,10 @@ master_doc = "index"
|
|||
# General information about the project.
|
||||
project = "Pillow (PIL Fork)"
|
||||
copyright = (
|
||||
"1995-2011 Fredrik Lundh, 2010-2024 Jeffrey A. Clark (Alex) and contributors"
|
||||
"1995-2011 Fredrik Lundh and contributors, "
|
||||
"2010-2024 Jeffrey A. Clark and contributors."
|
||||
)
|
||||
author = "Fredrik Lundh, Jeffrey A. Clark (Alex), contributors"
|
||||
author = "Fredrik Lundh (PIL), Jeffrey A. Clark (Pillow)"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
|
@ -252,7 +253,7 @@ latex_documents = [
|
|||
master_doc,
|
||||
"PillowPILFork.tex",
|
||||
"Pillow (PIL Fork) Documentation",
|
||||
"Jeffrey A. Clark (Alex)",
|
||||
"Jeffrey A. Clark",
|
||||
"manual",
|
||||
)
|
||||
]
|
||||
|
@ -302,7 +303,7 @@ texinfo_documents = [
|
|||
"Pillow (PIL Fork) Documentation",
|
||||
author,
|
||||
"PillowPILFork",
|
||||
"Pillow is the friendly PIL fork by Jeffrey A. Clark (Alex) and contributors.",
|
||||
"Pillow is the friendly PIL fork by Jeffrey A. Clark and contributors.",
|
||||
"Miscellaneous",
|
||||
)
|
||||
]
|
||||
|
|
|
@ -1234,11 +1234,15 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options:
|
|||
If present and true, instructs the WebP writer to use lossless compression.
|
||||
|
||||
**quality**
|
||||
Integer, 0-100, Defaults to 80. For lossy, 0 gives the smallest
|
||||
Integer, 0-100, defaults to 80. For lossy, 0 gives the smallest
|
||||
size and 100 the largest. For lossless, this parameter is the amount
|
||||
of effort put into the compression: 0 is the fastest, but gives larger
|
||||
files compared to the slowest, but best, 100.
|
||||
|
||||
**alpha_quality**
|
||||
Integer, 0-100, defaults to 100. For lossy compression only. 0 gives the
|
||||
smallest size and 100 is lossless.
|
||||
|
||||
**method**
|
||||
Quality/speed trade-off (0=fast, 6=slower-better). Defaults to 4.
|
||||
|
||||
|
@ -1335,7 +1339,8 @@ FITS
|
|||
|
||||
.. versionadded:: 9.1.0
|
||||
|
||||
Pillow identifies and reads FITS files, commonly used for astronomy.
|
||||
Pillow identifies and reads FITS files, commonly used for astronomy. Uncompressed and
|
||||
GZIP_1 compressed images can be read.
|
||||
|
||||
FLI, FLC
|
||||
^^^^^^^^
|
||||
|
@ -1351,9 +1356,8 @@ The :py:meth:`~PIL.Image.open` method sets the following
|
|||
FPX
|
||||
^^^
|
||||
|
||||
Pillow reads Kodak FlashPix files. In the current version, only the highest
|
||||
resolution image is read from the file, and the viewing transform is not taken
|
||||
into account.
|
||||
Pillow reads Kodak FlashPix files. Only the highest resolution image is read from the
|
||||
file, and the viewing transform is not taken into account.
|
||||
|
||||
To enable FPX support, you must install :pypi:`olefile`.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Pillow
|
||||
======
|
||||
|
||||
Pillow is the friendly PIL fork by `Jeffrey A. Clark (Alex) and contributors <https://github.com/python-pillow/Pillow/graphs/contributors>`_. PIL is the Python Imaging Library by Fredrik Lundh and contributors.
|
||||
Pillow is the friendly PIL fork by `Jeffrey A. Clark and contributors <https://github.com/python-pillow/Pillow/graphs/contributors>`_. PIL is the Python Imaging Library by Fredrik Lundh and contributors.
|
||||
|
||||
Pillow for enterprise is available via the Tidelift Subscription. `Learn more <https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=docs&utm_campaign=enterprise>`_.
|
||||
|
||||
|
|
|
@ -23,8 +23,7 @@ Example: Filter an image
|
|||
Filters
|
||||
-------
|
||||
|
||||
The current version of the library provides the following set of predefined
|
||||
image enhancement filters:
|
||||
Pillow provides the following set of predefined image enhancement filters:
|
||||
|
||||
* **BLUR**
|
||||
* **CONTOUR**
|
||||
|
|
|
@ -21,8 +21,8 @@ vector data. Path objects can be passed to the methods on the
|
|||
|
||||
The path object implements most parts of the Python sequence interface, and
|
||||
behaves like a list of (x, y) pairs. You can use len(), item access, and
|
||||
slicing as usual. However, the current version does not support slice
|
||||
assignment, or item and slice deletion.
|
||||
slicing as usual. However, this does not support slice assignment, or item
|
||||
and slice deletion.
|
||||
|
||||
:param xy: A sequence. The sequence can contain 2-tuples [(x, y), ...]
|
||||
or a flat list of numbers [x, y, ...].
|
||||
|
|
|
@ -1,6 +1,33 @@
|
|||
10.0.0
|
||||
------
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Limit size even if one dimension is zero
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When performing decompression bomb checks, Pillow did not reject images with
|
||||
excessive width and zero height, or zero width and excessive height. That has
|
||||
now been fixed.
|
||||
|
||||
This effectively dates to the PIL fork, since problem images would still have
|
||||
been processed before Pillow started checking for decompression bombs.
|
||||
|
||||
.. _Added ImageFont.MAX_STRING_LENGTH:
|
||||
|
||||
:cve:`2023-44271`: Added ImageFont.MAX_STRING_LENGTH
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To protect against potential DOS attacks when using arbitrary strings as text
|
||||
input, Pillow will now raise a :py:exc:`ValueError` if the number of characters
|
||||
passed into ImageFont methods is over a certain limit,
|
||||
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`.
|
||||
|
||||
This threshold can be changed by setting
|
||||
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`. It can be disabled by setting
|
||||
``ImageFont.MAX_STRING_LENGTH = None``.
|
||||
|
||||
Backwards Incompatible Changes
|
||||
==============================
|
||||
|
||||
|
@ -157,31 +184,6 @@ Added ``alpha_only`` argument to ``getbbox()``
|
|||
and the image has an alpha channel, trim transparent pixels. Otherwise, trim
|
||||
pixels when all channels are zero.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Limit size even if one dimension is zero
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When performing decompression bomb checks, Pillow did not reject images with
|
||||
excessive width and zero height, or zero width and excessive height. That has
|
||||
now been fixed.
|
||||
|
||||
This effectively dates to the PIL fork, since problem images would still have
|
||||
been processed before Pillow started checking for decompression bombs.
|
||||
|
||||
Added ImageFont.MAX_STRING_LENGTH
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:cve:`2023-44271`: To protect against potential DOS attacks when using arbitrary strings as text
|
||||
input, Pillow will now raise a :py:exc:`ValueError` if the number of characters
|
||||
passed into ImageFont methods is over a certain limit,
|
||||
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`.
|
||||
|
||||
This threshold can be changed by setting
|
||||
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`. It can be disabled by setting
|
||||
``ImageFont.MAX_STRING_LENGTH = None``.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -4,11 +4,17 @@
|
|||
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.
|
||||
:cve:`2023-4863`: Updated install script and updated wheels
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This release provides an updated install script and updated wheels to
|
||||
include libwebp 1.3.2, preventing a potential heap buffer overflow in
|
||||
WebP.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
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.
|
||||
|
|
|
@ -1,6 +1,38 @@
|
|||
10.2.0
|
||||
------
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
ImageFont.getmask: Applied ImageFont.MAX_STRING_LENGTH
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To protect against potential DOS attacks when using arbitrary strings as text input,
|
||||
Pillow will now raise a :py:exc:`ValueError` if the number of characters passed into
|
||||
:py:meth:`PIL.ImageFont.ImageFont.getmask` is over a certain limit,
|
||||
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`.
|
||||
|
||||
This threshold can be changed by setting :py:data:`PIL.ImageFont.MAX_STRING_LENGTH`. It
|
||||
can be disabled by setting ``ImageFont.MAX_STRING_LENGTH = None``.
|
||||
|
||||
A decompression bomb check has also been added to
|
||||
:py:meth:`PIL.ImageFont.ImageFont.getmask`.
|
||||
|
||||
ImageFont.getmask: Trim glyph size
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To protect against potential DOS attacks when using PIL fonts,
|
||||
:py:class:`PIL.ImageFont.ImageFont` now trims the size of individual glyphs so that
|
||||
they do not extend beyond the bitmap image.
|
||||
|
||||
:cve:`2023-50447`: ImageMath.eval: Restricted environment keys
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If an attacker has control over the keys passed to the
|
||||
``environment`` argument of :py:meth:`PIL.ImageMath.eval`, they may be able to execute
|
||||
arbitrary code. To prevent this, keys matching the names of builtins and keys
|
||||
containing double underscores will now raise a :py:exc:`ValueError`.
|
||||
|
||||
Deprecations
|
||||
============
|
||||
|
||||
|
@ -63,38 +95,6 @@ JPEG tables-only streamtype
|
|||
When saving JPEG files, ``streamtype`` can now be set to 1, for tables-only. This will
|
||||
output only the quantization and Huffman tables for the image.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
ImageFont.getmask: Applied ImageFont.MAX_STRING_LENGTH
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To protect against potential DOS attacks when using arbitrary strings as text input,
|
||||
Pillow will now raise a :py:exc:`ValueError` if the number of characters passed into
|
||||
:py:meth:`PIL.ImageFont.ImageFont.getmask` is over a certain limit,
|
||||
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`.
|
||||
|
||||
This threshold can be changed by setting :py:data:`PIL.ImageFont.MAX_STRING_LENGTH`. It
|
||||
can be disabled by setting ``ImageFont.MAX_STRING_LENGTH = None``.
|
||||
|
||||
A decompression bomb check has also been added to
|
||||
:py:meth:`PIL.ImageFont.ImageFont.getmask`.
|
||||
|
||||
ImageFont.getmask: Trim glyph size
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To protect against potential DOS attacks when using PIL fonts,
|
||||
:py:class:`PIL.ImageFont.ImageFont` now trims the size of individual glyphs so that
|
||||
they do not extend beyond the bitmap image.
|
||||
|
||||
ImageMath.eval: Restricted environment keys
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:cve:`2023-50447`: If an attacker has control over the keys passed to the
|
||||
``environment`` argument of :py:meth:`PIL.ImageMath.eval`, they may be able to execute
|
||||
arbitrary code. To prevent this, keys matching the names of builtins and keys
|
||||
containing double underscores will now raise a :py:exc:`ValueError`.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
10.3.0
|
||||
------
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
|
||||
TODO
|
||||
|
||||
:cve:`YYYY-XXXXX`: TODO
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
TODO
|
||||
|
||||
Backwards Incompatible Changes
|
||||
==============================
|
||||
|
||||
|
@ -48,10 +61,24 @@ Deprecated Use instead
|
|||
API Changes
|
||||
===========
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
Added alpha_quality argument when saving WebP images
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
TODO
|
||||
When saving WebP images, an ``alpha_quality`` argument can be passed to the encoder. It
|
||||
is an integer value between 0 to 100, where values other than 100 will provide lossy
|
||||
compression.
|
||||
|
||||
Negative kmeans error
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When calling :py:meth:`~PIL.Image.Image.quantize`, a negative ``kmeans`` will now
|
||||
raise a :py:exc:`ValueError`, unless a palette is supplied to make the value redundant.
|
||||
|
||||
Negative P1-P3 PPM value error
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If a P1-P3 PPM image contains a negative value, a :py:exc:`ValueError` will now be
|
||||
raised.
|
||||
|
||||
API Additions
|
||||
=============
|
||||
|
@ -63,14 +90,6 @@ Added PerspectiveTransform
|
|||
that all of the :py:data:`~PIL.Image.Transform` values now have a corresponding
|
||||
subclass of :py:class:`~PIL.ImageTransform.Transform`.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
|
||||
TODO
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
26
docs/releasenotes/2.3.1.rst
Normal file
26
docs/releasenotes/2.3.1.rst
Normal file
|
@ -0,0 +1,26 @@
|
|||
2.3.1
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
These issues were reported in
|
||||
`Debian bug #737059 <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=737059>`_.
|
||||
|
||||
:cve:`2014-1932`: Fix insecure use of :py:func:`tempfile.mktemp`
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The (1) ``load_djpeg`` function in ``JpegImagePlugin.py``, (2) Ghostscript function
|
||||
in ``EpsImagePlugin.py``, (3) ``load`` function in ``IptcImagePlugin.py``, and (4)
|
||||
``_copy`` function in ``Image.py`` in
|
||||
Pillow before 2.3.1 do not properly create temporary files, which allow
|
||||
local users to overwrite arbitrary files and obtain sensitive information via a
|
||||
symlink attack on the temporary file.
|
||||
|
||||
:cve:`2014-1933`: Fix insecure use of :py:func:`tempfile.mktemp`
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The (1) ``JpegImagePlugin.py`` and (2) ``EpsImagePlugin.py`` scripts in
|
||||
Pillow before 2.3.1 uses the names of
|
||||
temporary files on the command line, which makes it easier for local users to
|
||||
conduct symlink attacks by listing the processes.
|
14
docs/releasenotes/2.3.2.rst
Normal file
14
docs/releasenotes/2.3.2.rst
Normal file
|
@ -0,0 +1,14 @@
|
|||
2.3.2
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
:cve:`2014-3589`: Fix DOS attack
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``PIL/IcnsImagePlugin.py`` in Pillow before 2.3.2 and
|
||||
2.5.x before 2.5.2 allows remote attackers to cause a denial of service via a crafted
|
||||
block size.
|
||||
|
||||
Found and reported by Andrew Drake of `Dropbox <https://www.dropbox.com/>`__.
|
14
docs/releasenotes/2.5.2.rst
Normal file
14
docs/releasenotes/2.5.2.rst
Normal file
|
@ -0,0 +1,14 @@
|
|||
2.5.2
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
:cve:`2014-3589`: Fix DOS attack
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``PIL/IcnsImagePlugin.py`` in Pillow before 2.3.2 and
|
||||
2.5.x before 2.5.2 allows remote attackers to cause a denial of service via a crafted
|
||||
block size.
|
||||
|
||||
Found and reported by Andrew Drake of `Dropbox <https://www.dropbox.com/>`__.
|
14
docs/releasenotes/2.6.0.rst
Normal file
14
docs/releasenotes/2.6.0.rst
Normal file
|
@ -0,0 +1,14 @@
|
|||
2.6.0
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
:cve:`2014-3589`: Fix DOS attack
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``PIL/IcnsImagePlugin.py`` in Pillow before 2.3.2 and
|
||||
2.5.x before 2.5.2 allows remote attackers to cause a denial of service via a crafted
|
||||
block size.
|
||||
|
||||
Found and reported by Andrew Drake of `Dropbox <https://www.dropbox.com/>`__.
|
|
@ -1,15 +1,14 @@
|
|||
2.7.0
|
||||
=====
|
||||
-----
|
||||
|
||||
Sane Plugin
|
||||
-----------
|
||||
^^^^^^^^^^^
|
||||
|
||||
The Sane plugin has now been split into its own repo:
|
||||
https://github.com/python-pillow/Sane .
|
||||
|
||||
|
||||
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
|
||||
|
@ -24,7 +23,7 @@ default. The total decompressed size of all text chunks is limited to
|
|||
know that there are large text blocks that are desired.
|
||||
|
||||
Image resizing filters
|
||||
----------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Image resizing methods :py:meth:`~PIL.Image.Image.resize` and
|
||||
:py:meth:`~PIL.Image.Image.thumbnail` take a ``resample`` argument, which tells
|
||||
|
@ -33,7 +32,7 @@ which filter should be used for resampling. Possible values are:
|
|||
were changed in this version.
|
||||
|
||||
Bicubic and bilinear downscaling
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
++++++++++++++++++++++++++++++++
|
||||
|
||||
From the beginning ``BILINEAR`` and ``BICUBIC`` filters were based on affine
|
||||
transformations and used a fixed number of pixels from the source image for
|
||||
|
@ -50,7 +49,7 @@ If you have previously used any tricks to maintain quality when downscaling with
|
|||
steps), they are unnecessary now.
|
||||
|
||||
Antialias renamed to Lanczos
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
++++++++++++++++++++++++++++
|
||||
|
||||
A new ``LANCZOS`` constant was added instead of ``ANTIALIAS``.
|
||||
|
||||
|
@ -64,19 +63,19 @@ The ``ANTIALIAS`` constant is left for backward compatibility and is an alias
|
|||
for ``LANCZOS``.
|
||||
|
||||
Lanczos upscaling quality
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
The image upscaling quality with ``LANCZOS`` filter was almost the same as
|
||||
``BILINEAR`` due to a bug. This has been fixed.
|
||||
|
||||
Bicubic upscaling quality
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
The ``BICUBIC`` filter for affine transformations produced sharp, slightly
|
||||
pixelated image for upscaling. Bicubic for convolutions is more soft.
|
||||
|
||||
Resize performance
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
++++++++++++++++++
|
||||
|
||||
In most cases, convolution is more a expensive algorithm for downscaling
|
||||
because it takes into account all the pixels of source image. Therefore
|
||||
|
@ -93,7 +92,7 @@ The upscaling performance of the ``LANCZOS`` filter has remained the same. For
|
|||
times.
|
||||
|
||||
Default filter for thumbnails
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
+++++++++++++++++++++++++++++
|
||||
|
||||
In Pillow 2.5 the default filter for :py:meth:`~PIL.Image.Image.thumbnail` was
|
||||
changed from ``NEAREST`` to ``ANTIALIAS``. Antialias was chosen because all the
|
||||
|
@ -103,7 +102,7 @@ other filters gave poor quality for reduction. Starting from Pillow 2.7.0,
|
|||
uses supersampling internally, not convolutions.
|
||||
|
||||
Image transposition
|
||||
-------------------
|
||||
+++++++++++++++++++
|
||||
|
||||
A new method ``TRANSPOSE`` has been added for the
|
||||
:py:meth:`~PIL.Image.Image.transpose` operation in addition to
|
||||
|
@ -115,7 +114,7 @@ The speed of ``ROTATE_90``, ``ROTATE_270`` and ``TRANSPOSE`` has been significan
|
|||
improved for large images which don't fit in the processor cache.
|
||||
|
||||
Gaussian blur and unsharp mask
|
||||
------------------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The :py:meth:`~PIL.ImageFilter.GaussianBlur` implementation has been replaced
|
||||
with a sequential application of box filters. The new implementation is based on
|
||||
|
@ -125,7 +124,7 @@ implementations use Gaussian blur internally, all changes from this chapter
|
|||
are also applicable to it.
|
||||
|
||||
Blur radius
|
||||
^^^^^^^^^^^
|
||||
+++++++++++
|
||||
|
||||
There was an error in the previous version of Pillow, where blur radius (the
|
||||
standard deviation of Gaussian) actually meant blur diameter. For example, to
|
||||
|
@ -136,7 +135,7 @@ If you used a Gaussian blur with some radius value, you need to divide this
|
|||
value by two.
|
||||
|
||||
Blur performance
|
||||
^^^^^^^^^^^^^^^^
|
||||
++++++++++++++++
|
||||
|
||||
Box filter computation time is constant relative to the radius and depends
|
||||
on source image size only. Because the new Gaussian blur implementation
|
||||
|
@ -148,7 +147,7 @@ second for radius 1, 3.6 seconds for radius 10 and 17 seconds for 50, now blur
|
|||
with any radius on same image is executed for 0.2 seconds.
|
||||
|
||||
Blur quality
|
||||
^^^^^^^^^^^^
|
||||
++++++++++++
|
||||
|
||||
The previous implementation takes into account only source pixels within
|
||||
2 * standard deviation radius for every destination pixel. This was not enough,
|
||||
|
@ -157,7 +156,7 @@ so the quality was worse compared to other Gaussian blur software.
|
|||
The new implementation does not have this drawback.
|
||||
|
||||
TIFF Parameter Changes
|
||||
----------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Several kwarg parameters for saving TIFF images were previously
|
||||
specified as strings with included spaces (e.g. 'x resolution'). This
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
2.8.0
|
||||
=====
|
||||
-----
|
||||
|
||||
Open HTTP response objects with Image.open
|
||||
------------------------------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
HTTP response objects returned from ``urllib2.urlopen(url)`` or
|
||||
``requests.get(url, stream=True).raw`` are 'file-like' but do not support ``.seek()``
|
||||
|
|
|
@ -1,9 +1,28 @@
|
|||
|
||||
3.0.0
|
||||
=====
|
||||
-----
|
||||
|
||||
Backwards Incompatible Changes
|
||||
==============================
|
||||
|
||||
Several methods that have been marked as deprecated for many releases
|
||||
have been removed in this release:
|
||||
|
||||
* ``Image.tostring()``
|
||||
* ``Image.fromstring()``
|
||||
* ``Image.offset()``
|
||||
* ``ImageDraw.setink()``
|
||||
* ``ImageDraw.setfill()``
|
||||
* The ``ImageFileIO`` module
|
||||
* The ``ImageFont.FreeTypeFont`` and ``ImageFont.truetype`` ``file`` keyword arg
|
||||
* The ``ImagePalette`` private ``_make`` functions
|
||||
* ``ImageWin.fromstring()``
|
||||
* ``ImageWin.tostring()``
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
Saving Multipage Images
|
||||
-----------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There is now support for saving multipage images in the ``GIF`` and
|
||||
``PDF`` formats. To enable this functionality, pass in ``save_all=True``
|
||||
|
@ -12,7 +31,7 @@ as a keyword argument to the save::
|
|||
im.save('test.pdf', save_all=True)
|
||||
|
||||
Tiff ImageFileDirectory Rewrite
|
||||
-------------------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The Tiff ImageFileDirectory metadata code has been rewritten. Where
|
||||
previously it returned a somewhat arbitrary set of values and tuples,
|
||||
|
@ -25,25 +44,8 @@ structures will be deprecated at some point in the future. When
|
|||
saving Tiff metadata, new code should use the
|
||||
TiffImagePlugin.ImageFileDirectory_v2 class.
|
||||
|
||||
Deprecated Methods
|
||||
------------------
|
||||
|
||||
Several methods that have been marked as deprecated for many releases
|
||||
have been removed in this release::
|
||||
|
||||
Image.tostring()
|
||||
Image.fromstring()
|
||||
Image.offset()
|
||||
ImageDraw.setink()
|
||||
ImageDraw.setfill()
|
||||
The ImageFileIO module
|
||||
The ImageFont.FreeTypeFont and ImageFont.truetype ``file`` keyword arg
|
||||
The ImagePalette private _make functions
|
||||
ImageWin.fromstring()
|
||||
ImageWin.tostring()
|
||||
|
||||
LibJpeg and Zlib are Required by Default
|
||||
----------------------------------------
|
||||
LibJpeg and Zlib are required by default
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The external dependencies on libjpeg and zlib are now required by default.
|
||||
If the headers or libraries are not found, then installation will abort
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
|
||||
3.1.0
|
||||
=====
|
||||
-----
|
||||
|
||||
ImageDraw arc, chord and pieslice can now use floats
|
||||
----------------------------------------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There is no longer a need to ensure that the start and end arguments for ``arc``,
|
||||
``chord`` and ``pieslice`` are integers.
|
||||
|
@ -12,7 +11,7 @@ Note that these numbers are not simply rounded internally, but are actually
|
|||
utilised in the drawing process.
|
||||
|
||||
Consistent multiline text spacing
|
||||
---------------------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When using the ``ImageDraw`` multiline methods, the spacing between
|
||||
lines was inconsistent, based on the combination on ascenders and
|
||||
|
@ -24,7 +23,7 @@ not the absolute height of each line.
|
|||
There is also now a default spacing of 4px between lines.
|
||||
|
||||
Exif, Jpeg and Tiff Metadata
|
||||
----------------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There were major changes in the TIFF ImageFileDirectory support in
|
||||
Pillow 3.0 that led to a number of regressions. Some of them have been
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
|
||||
3.1.1
|
||||
=====
|
||||
-----
|
||||
|
||||
CVE-2016-0740 -- Buffer overflow in TiffDecode.c
|
||||
------------------------------------------------
|
||||
Security
|
||||
========
|
||||
|
||||
:cve:`2016-0740`: Buffer overflow in ``TiffDecode.c``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow 3.1.0 and earlier when linked against libtiff >= 4.0.0 on x64
|
||||
may overflow a buffer when reading a specially crafted tiff file (:cve:`2016-0740`).
|
||||
may overflow a buffer when reading a specially crafted tiff file.
|
||||
|
||||
Specifically, libtiff >= 4.0.0 changed the return type of
|
||||
``TIFFScanlineSize`` from ``int32`` to machine dependent
|
||||
|
@ -19,9 +21,8 @@ image data over 64k is written over the heap, causing a segfault.
|
|||
|
||||
This issue was found by security researcher FourOne.
|
||||
|
||||
|
||||
CVE-2016-0775 -- Buffer overflow in FliDecode.c
|
||||
-----------------------------------------------
|
||||
:cve:`2016-0775`: Buffer overflow in ``FliDecode.c``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In all versions of Pillow, dating back at least to the last PIL 1.1.7
|
||||
release, FliDecode.c has a buffer overflow error (:cve:`2016-0775`).
|
||||
|
@ -49,8 +50,8 @@ off the end of the memory buffer, causing a segfault.
|
|||
|
||||
This issue was found by Alyssa Besseling at Atlassian.
|
||||
|
||||
CVE-2016-2533 -- Buffer overflow in PcdDecode.c
|
||||
-----------------------------------------------
|
||||
:cve:`2016-2533`: Buffer overflow in ``PcdDecode.c``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In all versions of Pillow, dating back at least to the last PIL 1.1.7
|
||||
release, ``PcdDecode.c`` has a buffer overflow error (:cve:`2016-2533`).
|
||||
|
@ -61,8 +62,8 @@ assuming 4 bytes per pixel. This writes 768 bytes beyond the end of
|
|||
the buffer into other Python object storage. In some cases, this
|
||||
causes a segfault, in others an internal Python malloc error.
|
||||
|
||||
Integer overflow in Resample.c
|
||||
------------------------------
|
||||
Integer overflow in ``Resample.c``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If a large value was passed into the new size for an image, it is
|
||||
possible to overflow an ``int32`` value passed into malloc.
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
|
||||
3.1.2
|
||||
=====
|
||||
-----
|
||||
|
||||
CVE-2016-3076 -- Buffer overflow in Jpeg2KEncode.c
|
||||
--------------------------------------------------
|
||||
Security
|
||||
========
|
||||
|
||||
Pillow between 2.5.0 and 3.1.1 may overflow a buffer when writing
|
||||
large Jpeg2000 files, allowing for code execution or other memory
|
||||
corruption (:cve:`2016-3076`).
|
||||
:cve:`2016-3076`: Buffer overflow in Jpeg2KEncode.c
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow between 2.5.0 and 3.1.1 may overflow a buffer
|
||||
when writing large Jpeg2000 files, allowing for code execution or other
|
||||
memory corruption.
|
||||
|
||||
This occurs specifically in the function ``j2k_encode_entry``, at the line:
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
|
||||
3.2.0
|
||||
-----
|
||||
|
||||
New DDS and FTEX Image Plugins
|
||||
==============================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``DdsImagePlugin`` reading DXT1 and DXT5 encoded ``.dds`` images was
|
||||
added. DXT3 images are not currently supported.
|
||||
|
@ -14,13 +13,13 @@ per file, in the ``.ftc`` (compressed) and ``.ftu`` (uncompressed)
|
|||
formats.
|
||||
|
||||
Updates to the GbrImagePlugin
|
||||
=============================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``GbrImagePlugin`` (GIMP brush format) has been updated to fix
|
||||
support for version 1 files and add support for version 2 files.
|
||||
|
||||
Passthrough Parameters for ImageDraw.text
|
||||
=========================================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``ImageDraw.multiline_text`` and ``ImageDraw.multiline_size`` take extra
|
||||
spacing parameters above what are used in ``ImageDraw.text`` and
|
||||
|
@ -29,7 +28,7 @@ spacing parameters above what are used in ``ImageDraw.text`` and
|
|||
to the corresponding multiline functions.
|
||||
|
||||
ImageSequence.Iterator changes
|
||||
==============================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``ImageSequence.Iterator`` is now an actual iterator implementing the
|
||||
Iterator protocol. It is also now possible to seek to the first image
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
-----
|
||||
|
||||
Libimagequant support
|
||||
=====================
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There is now support for using libimagequant as a higher quality
|
||||
quantization option in ``Image.quantize()`` on Unix-like
|
||||
|
@ -12,21 +12,20 @@ differences.
|
|||
|
||||
|
||||
New Setup.py options
|
||||
====================
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There are two new options to control the ``build_ext`` task in ``setup.py``:
|
||||
|
||||
* ``--debug`` dumps all of the directories and files that are
|
||||
checked when searching for libraries or headers when building the
|
||||
extensions.
|
||||
* ``--disable-platform-guessing`` removes many of the directories
|
||||
that are checked for libraries and headers for build systems or
|
||||
cross compilers that specify that information in via environment
|
||||
variables.
|
||||
|
||||
* ``--debug`` dumps all of the directories and files that are
|
||||
checked when searching for libraries or headers when building the
|
||||
extensions.
|
||||
* ``--disable-platform-guessing`` removes many of the directories
|
||||
that are checked for libraries and headers for build systems or
|
||||
cross compilers that specify that information in via environment
|
||||
variables.
|
||||
|
||||
Resizing
|
||||
========
|
||||
^^^^^^^^
|
||||
|
||||
Image resampling for 8-bit per channel images was rewritten using only integer
|
||||
computings. This is faster on most platforms and doesn't introduce precision
|
||||
|
@ -36,19 +35,17 @@ makes resampling 60% faster on average.
|
|||
Color calculation for images in the ``LA`` mode on semitransparent pixels
|
||||
was fixed.
|
||||
|
||||
|
||||
Rotation
|
||||
========
|
||||
^^^^^^^^
|
||||
|
||||
Rotation for angles divisible by 90 degrees now always uses transposition.
|
||||
This greatly improves both quality and performance in this case.
|
||||
Also, the bug with wrong image size calculation when rotating by 90 degrees
|
||||
was fixed.
|
||||
|
||||
|
||||
Image Metadata
|
||||
==============
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
The return type for binary data in version 2 Exif and Tiff metadata
|
||||
has been changed from a tuple of integers to bytes. This is a change
|
||||
from the behavior since ``3.0.0``.
|
||||
from the behavior since 3.0.0.
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
|
||||
3.3.2
|
||||
=====
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Integer overflow in Map.c
|
||||
-------------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow prior to 3.3.2 may experience integer overflow errors in map.c
|
||||
when reading specially crafted image files. This may lead to memory
|
||||
|
@ -26,7 +28,7 @@ memory without duplicating the image first.
|
|||
This issue was found by Cris Neckar at Divergent Security.
|
||||
|
||||
Sign Extension in Storage.c
|
||||
---------------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow prior to 3.3.2 and PIL 1.1.7 (at least) do not check for
|
||||
negative image sizes in ``ImagingNew`` in ``Storage.c``. A negative
|
||||
|
|
|
@ -1,9 +1,32 @@
|
|||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
Backwards Incompatible Changes
|
||||
==============================
|
||||
|
||||
Image.core.open_ppm removed
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The nominally private/debugging function ``Image.core.open_ppm`` has
|
||||
been removed. If you were using this function, please use
|
||||
``Image.open`` instead.
|
||||
|
||||
Deprecations
|
||||
============
|
||||
|
||||
Deprecation Warning when Saving JPEGs
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
JPEG images cannot contain an alpha channel. Pillow prior to 3.4.0
|
||||
silently drops the alpha channel. With this release Pillow will now
|
||||
issue a :py:exc:`DeprecationWarning` when attempting to save a ``RGBA`` mode
|
||||
image as a JPEG. This will become an error in Pillow 4.2.
|
||||
|
||||
API Additions
|
||||
=============
|
||||
|
||||
New resizing filters
|
||||
====================
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Two new filters available for ``Image.resize()`` and ``Image.thumbnail()``
|
||||
functions: ``BOX`` and ``HAMMING``. ``BOX`` is the high-performance filter with
|
||||
|
@ -14,23 +37,15 @@ two times shorter window than ``BILINEAR``. It can be used for image reduction
|
|||
providing the image downscaling quality comparable to ``BICUBIC``.
|
||||
Both new filters don't show good quality for the image upscaling.
|
||||
|
||||
Deprecation Warning when Saving JPEGs
|
||||
=====================================
|
||||
|
||||
JPEG images cannot contain an alpha channel. Pillow prior to 3.4.0
|
||||
silently drops the alpha channel. With this release Pillow will now
|
||||
issue a :py:exc:`DeprecationWarning` when attempting to save a ``RGBA`` mode
|
||||
image as a JPEG. This will become an error in Pillow 4.2.
|
||||
|
||||
New DDS Decoders
|
||||
================
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow can now decode DXT3 images, as well as the previously supported
|
||||
DXT1 and DXT5 formats. All three formats are now decoded in C code for
|
||||
better performance.
|
||||
|
||||
Append images to GIF
|
||||
====================
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Additional frames can now be appended when saving a GIF file, through the
|
||||
``append_images`` argument. The new frames are passed in as a list of images,
|
||||
|
@ -42,16 +57,9 @@ in effect, e.g.::
|
|||
im.save(out, save_all=True, append_images=[im1, im2, ...])
|
||||
|
||||
Save multiple frame TIFF
|
||||
========================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Multiple frames can now be saved in a TIFF file by using the ``save_all`` option.
|
||||
e.g.::
|
||||
|
||||
im.save("filename.tiff", format="TIFF", save_all=True)
|
||||
|
||||
Image.core.open_ppm removed
|
||||
===========================
|
||||
|
||||
The nominally private/debugging function ``Image.core.open_ppm`` has
|
||||
been removed. If you were using this function, please use
|
||||
``Image.open`` instead.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
-----
|
||||
|
||||
Python 2.6 and 3.2 Dropped
|
||||
==========================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow 4.0 no longer supports Python 2.6 and 3.2. We will not be
|
||||
creating binaries, testing, or retaining compatibility with these
|
||||
|
@ -10,12 +10,12 @@ releases. This release removes some workarounds for those Python
|
|||
releases, so the final working version of Pillow on 2.6 or 3.2 is 3.4.2.
|
||||
|
||||
Support added for Python 3.6
|
||||
============================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow 4.0 supports Python 3.6.
|
||||
|
||||
OleFileIO.py
|
||||
============
|
||||
^^^^^^^^^^^^
|
||||
|
||||
``OleFileIO.py`` has been removed as a vendored file and is now installed
|
||||
from the upstream :pypi:`olefile` PyPI package. All internal dependencies are
|
||||
|
@ -24,19 +24,19 @@ redirected to the olefile package. Direct accesses to
|
|||
upstream olefile into ``sys.modules`` in its place.
|
||||
|
||||
SGI image save
|
||||
==============
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
It is now possible to save images in modes ``L``, ``RGB``, and
|
||||
``RGBA`` to the uncompressed SGI image format.
|
||||
|
||||
Zero sized images
|
||||
=================
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow 3.4.0 removed support for creating images with (0,0) size. This
|
||||
has been reenabled, restoring pre 3.4 behavior.
|
||||
|
||||
Internal handles_eof flag
|
||||
=========================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``handles_eof flag`` for decoding images has been removed, as there
|
||||
were no internal users of the flag. Anyone maintaining image decoders
|
||||
|
@ -44,7 +44,7 @@ outside of the Pillow source tree should consider using the cleanup
|
|||
function pointers instead.
|
||||
|
||||
Image.core.stretch removed
|
||||
==========================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
4.1.0
|
||||
-----
|
||||
|
||||
Removed Deprecated Items
|
||||
========================
|
||||
Deprecations
|
||||
============
|
||||
|
||||
Several deprecated items have been removed.
|
||||
|
||||
|
@ -15,8 +15,11 @@ Several deprecated items have been removed.
|
|||
``PIL.ImageDraw.ImageDraw.setfont`` have been removed.
|
||||
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
Closing Files When Opening Images
|
||||
=================================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The file handling when opening images has been overhauled. Previously,
|
||||
Pillow would attempt to close some, but not all image formats
|
||||
|
@ -38,9 +41,8 @@ is specified:
|
|||
the underlying file until we are done with the image. The mapping
|
||||
will be closed in the ``close`` or ``__del__`` method.
|
||||
|
||||
|
||||
Changes to GIF Handling When Saving
|
||||
===================================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The :py:class:`PIL.GifImagePlugin` code has been refactored to fix the flow when
|
||||
saving images. There are two external changes that arise from this:
|
||||
|
@ -56,14 +58,14 @@ This refactor fixed some bugs with palette handling when saving
|
|||
multiple frame GIFs.
|
||||
|
||||
New Method: Image.remap_palette
|
||||
===============================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The method :py:meth:`PIL.Image.Image.remap_palette()` has been
|
||||
added. This method was hoisted from the GifImagePlugin code used to
|
||||
optimize the palette.
|
||||
|
||||
Added Decoder Registry and Support for Python Based Decoders
|
||||
============================================================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There is now a decoder registry similar to the image plugin
|
||||
registries. Image plugins can register a decoder, and it will be
|
||||
|
@ -73,7 +75,7 @@ their C based counterparts, they may be easier and quicker to develop
|
|||
or safer to run.
|
||||
|
||||
Tests
|
||||
=====
|
||||
^^^^^
|
||||
|
||||
Many tests have been added, including correctness tests for image
|
||||
formats that have been previously untested.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
-----
|
||||
|
||||
Fix Regression with reading DPI from EXIF data
|
||||
==============================================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Some JPEG images don't contain DPI information in the image metadata,
|
||||
but do contain it in the EXIF data. A patch was added in 4.1.0 to read
|
||||
|
@ -10,9 +10,8 @@ from the EXIF data, but it did not accept all possible types that
|
|||
could be included there. This fix adds the ability to read ints as
|
||||
well as rational values.
|
||||
|
||||
|
||||
Incompatibility between 3.6.0 and 3.6.1
|
||||
=======================================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
CPython 3.6.1 added a new symbol, PySlice_GetIndicesEx, which was not
|
||||
present in 3.6.0. This had the effect of causing binaries compiled on
|
||||
|
|
|
@ -1,37 +1,11 @@
|
|||
4.2.0
|
||||
-----
|
||||
|
||||
Added Complex Text Rendering
|
||||
============================
|
||||
Backwards Incompatible Changes
|
||||
==============================
|
||||
|
||||
Pillow now supports complex text rendering for scripts requiring glyph
|
||||
composition and bidirectional flow. This optional feature adds three
|
||||
dependencies: harfbuzz, fribidi, and raqm. See the :doc:`install documentation
|
||||
<../installation>` for further details. This feature is tested and works on
|
||||
Unix and Mac, but has not yet been built on Windows platforms.
|
||||
|
||||
New Optional Parameters
|
||||
=======================
|
||||
|
||||
* :py:meth:`PIL.ImageDraw.floodfill` has a new optional parameter:
|
||||
threshold. This specifies a tolerance for the color to replace with
|
||||
the flood fill.
|
||||
|
||||
* The TIFF and PDF image writers now support the ``append_images``
|
||||
optional parameter for specifying additional images to create
|
||||
multipage outputs.
|
||||
|
||||
New DecompressionBomb Warning
|
||||
=============================
|
||||
|
||||
:py:meth:`PIL.Image.Image.crop` now may raise a DecompressionBomb
|
||||
warning if the crop region enlarges the image over the threshold
|
||||
specified by :py:data:`PIL.Image.MAX_IMAGE_PIXELS`.
|
||||
|
||||
Removed Deprecated Items
|
||||
========================
|
||||
|
||||
Several deprecated items have been removed.
|
||||
Several deprecated items have been removed
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* The methods ``PIL.ImageWin.Dib.fromstring``,
|
||||
``PIL.ImageWin.Dib.tostring`` and
|
||||
|
@ -44,8 +18,38 @@ Several deprecated items have been removed.
|
|||
an :py:exc:`IOError` is raised.
|
||||
|
||||
Removed Core Image Function
|
||||
===========================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The unused function ``Image.core.new_array`` was removed. This is an
|
||||
internal function that should not have been used by user code, but it
|
||||
was accessible from the python layer.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
Added Complex Text Rendering
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow now supports complex text rendering for scripts requiring glyph
|
||||
composition and bidirectional flow. This optional feature adds three
|
||||
dependencies: harfbuzz, fribidi, and raqm. See the :doc:`install documentation
|
||||
<../installation>` for further details. This feature is tested and works on
|
||||
Unix and Mac, but has not yet been built on Windows platforms.
|
||||
|
||||
New Optional Parameters
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* :py:meth:`PIL.ImageDraw.floodfill` has a new optional parameter:
|
||||
threshold. This specifies a tolerance for the color to replace with
|
||||
the flood fill.
|
||||
|
||||
* The TIFF and PDF image writers now support the ``append_images``
|
||||
optional parameter for specifying additional images to create
|
||||
multipage outputs.
|
||||
|
||||
New DecompressionBomb Warning
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:py:meth:`PIL.Image.Image.crop` now may raise a DecompressionBomb
|
||||
warning if the crop region enlarges the image over the threshold
|
||||
specified by :py:data:`PIL.Image.MAX_IMAGE_PIXELS`.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
There are no functional changes in this release.
|
||||
|
||||
Fixed Windows PyPy Build
|
||||
========================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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.
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
5.1.0
|
||||
-----
|
||||
|
||||
New File Format
|
||||
===============
|
||||
|
||||
BLP File Format
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow now supports reading the BLP "Blizzard Mipmap" file format used
|
||||
for tiles in Blizzard's engine.
|
||||
|
||||
API Changes
|
||||
===========
|
||||
|
||||
|
@ -21,12 +12,21 @@ and ``CMYK`` with up to 6 8-bit channels, discarding any extra
|
|||
channels if the content is tagged as UNSPECIFIED. Pillow still does
|
||||
not store more than 4 8-bit channels of image data.
|
||||
|
||||
API Additions
|
||||
=============
|
||||
|
||||
Append to PDF Files
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Images can now be appended to PDF files in place by passing in
|
||||
``append=True`` when saving the image.
|
||||
|
||||
New BLP File Format
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow now supports reading the BLP "Blizzard Mipmap" file format used
|
||||
for tiles in Blizzard's engine.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -1,6 +1,53 @@
|
|||
6.2.0
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
This release catches several buffer overruns and fixes :cve:`2019-16865`.
|
||||
|
||||
Buffer overruns
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
In ``RawDecode.c``, an error is now thrown if skip is calculated to be less than
|
||||
zero. It is intended to skip padding between lines, not to go backwards.
|
||||
|
||||
In ``PsdImagePlugin``, if the combined sizes of the individual parts is larger than
|
||||
the declared size of the extra data field, then it looked for the next layer by
|
||||
seeking backwards. This is now corrected by seeking to (the start of the layer
|
||||
+ the size of the extra data field) instead of (the read parts of the layer +
|
||||
the rest of the layer).
|
||||
|
||||
Decompression bomb checks have been added to GIF and ICO formats.
|
||||
|
||||
An error is now raised if a TIFF dimension is a string, rather than trying to
|
||||
perform operations on it.
|
||||
|
||||
:cve:`2019-16865`: Fix DOS attack
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The CVE is regarding DOS problems, such as consuming large amounts of memory,
|
||||
or taking a large amount of time to process an image.
|
||||
|
||||
API Changes
|
||||
===========
|
||||
|
||||
Image.getexif
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
To allow for lazy loading of Exif data, ``Image.getexif()`` now returns a
|
||||
shared instance of ``Image.Exif``.
|
||||
|
||||
Deprecations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Image.frombuffer
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
There has been a longstanding warning that the defaults of ``Image.frombuffer``
|
||||
may change in the future for the "raw" decoder. The change will now take place
|
||||
in Pillow 7.0.
|
||||
|
||||
API Additions
|
||||
=============
|
||||
|
||||
|
@ -46,46 +93,6 @@ ImageGrab on multi-monitor Windows
|
|||
An ``all_screens`` argument has been added to ``ImageGrab.grab``. If ``True``,
|
||||
all monitors will be included in the created image.
|
||||
|
||||
API Changes
|
||||
===========
|
||||
|
||||
Image.getexif
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
To allow for lazy loading of Exif data, ``Image.getexif()`` now returns a
|
||||
shared instance of ``Image.Exif``.
|
||||
|
||||
Deprecations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Image.frombuffer
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
There has been a longstanding warning that the defaults of ``Image.frombuffer``
|
||||
may change in the future for the "raw" decoder. The change will now take place
|
||||
in Pillow 7.0.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
This release catches several buffer overruns, as well as addressing
|
||||
:cve:`2019-16865`. The CVE is regarding DOS problems, such as consuming large
|
||||
amounts of memory, or taking a large amount of time to process an image.
|
||||
|
||||
In RawDecode.c, an error is now thrown if skip is calculated to be less than
|
||||
zero. It is intended to skip padding between lines, not to go backwards.
|
||||
|
||||
In PsdImagePlugin, if the combined sizes of the individual parts is larger than
|
||||
the declared size of the extra data field, then it looked for the next layer by
|
||||
seeking backwards. This is now corrected by seeking to (the start of the layer
|
||||
+ the size of the extra data field) instead of (the read parts of the layer +
|
||||
the rest of the layer).
|
||||
|
||||
Decompression bomb checks have been added to GIF and ICO formats.
|
||||
|
||||
An error is now raised if a TIFF dimension is a string, rather than trying to
|
||||
perform operations on it.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ Pillow 7.0.0 will be released on 2020-01-01 and will drop support for Python
|
|||
Other Changes
|
||||
=============
|
||||
|
||||
|
||||
|
||||
Support added for Python 3.8
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -4,15 +4,17 @@
|
|||
Security
|
||||
========
|
||||
|
||||
This release addresses several security problems.
|
||||
This release fixes several buffer overflow issues and a DOS attack vulnerability.
|
||||
|
||||
:cve:`2019-19911` is regarding FPX images. If an image reports that it has a large
|
||||
number of bands, a large amount of resources will be used when trying to process the
|
||||
image. This is fixed by limiting the number of bands to those usable by Pillow.
|
||||
:cve:`2020-5310`, :cve:`2020-5311`, :cve:`2020-5312`, :cve:`2020-5313`: Overflow checks added
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Buffer overruns were found when processing an SGI (:cve:`2020-5311`),
|
||||
PCX (:cve:`2020-5312`) or FLI image (:cve:`2020-5313`). Checks have been added
|
||||
to prevent this.
|
||||
Overflow checks have been added when calculating the size of a memory block to be reallocated
|
||||
in the processing of TIFF, SGI, PCX and FLI images.
|
||||
|
||||
:cve:`2020-5310`: Overflow checks have been added when calculating the size of a
|
||||
memory block to be reallocated in the processing of a TIFF image.
|
||||
:cve:`2019-19911`: DOS attack vulnerability
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If an FPX image reports that it has a large number of bands, a large amount of
|
||||
resources will be used when trying to process the image. This is fixed by
|
||||
limiting the number of bands to those usable by Pillow.
|
||||
|
|
|
@ -1,6 +1,40 @@
|
|||
7.1.0
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
This release includes many security fixes.
|
||||
|
||||
:cve:`2020-10177`: Multiple out-of-bounds reads in FLI decoding
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow before 7.1.0 has multiple out-of-bounds reads in ``libImaging/FliDecode.c``.
|
||||
|
||||
:cve:`2020-10378`: Bounds overflow in PCX decoding
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In ``libImaging/PcxDecode.c`` in Pillow before 7.1.0, an out-of-bounds read can occur
|
||||
when reading PCX files where ``state->shuffle`` is instructed to read beyond
|
||||
``state->buffer``.
|
||||
|
||||
:cve:`2020-10379`: Two buffer overflows in TIFF decoding
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In Pillow before 7.1.0, there are two buffer overflows in ``libImaging/TiffDecode.c``.
|
||||
|
||||
:cve:`2020-10994`: Bounds overflow in JPEG 2000 decoding
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In ``libImaging/Jpeg2KDecode.c`` in Pillow before 7.1.0, there are multiple
|
||||
out-of-bounds reads via a crafted JP2 file.
|
||||
|
||||
:cve:`2020-11538`: Buffer overflow in SGI-RLE decoding
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In ``libImaging/SgiRleDecode.c`` in Pillow through 7.0.0, a number of out-of-bounds
|
||||
reads exist in the parsing of SGI image files, a different issue than :cve:`2020-5311`.
|
||||
|
||||
API Changes
|
||||
===========
|
||||
|
||||
|
@ -67,17 +101,6 @@ Passing a different value on Windows or macOS will force taking a snapshot
|
|||
using the selected X server; pass an empty string to use the default X server.
|
||||
XCB support is not included in pre-compiled wheels for Windows and macOS.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
This release includes security fixes.
|
||||
|
||||
* :cve:`2020-10177` Fix multiple out-of-bounds reads in FLI decoding
|
||||
* :cve:`2020-10378` Fix bounds overflow in PCX decoding
|
||||
* :cve:`2020-10379` Fix two buffer overflows in TIFF decoding
|
||||
* :cve:`2020-10994` Fix bounds overflow in JPEG 2000 decoding
|
||||
* :cve:`2020-11538` Fix buffer overflow in SGI-RLE decoding
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
-----
|
||||
|
||||
Fix regression seeking PNG files
|
||||
================================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This fixes a regression introduced in 7.1.0 when adding support for APNG files when calling
|
||||
``seek`` and ``tell``:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
-----
|
||||
|
||||
Fix another regression seeking PNG files
|
||||
========================================
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This fixes a regression introduced in 7.1.0 when adding support for APNG files.
|
||||
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
Security
|
||||
========
|
||||
|
||||
Update FreeType used in binary wheels to `2.10.4`_ to fix :cve:`2020-15999`:
|
||||
:cve:`2020-15999`: Update FreeType in wheels to `2.10.4`_
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- A heap buffer overflow has been found in the handling of embedded PNG bitmaps,
|
||||
introduced in FreeType version 2.6.
|
||||
* A heap buffer overflow has been found in the handling of embedded PNG bitmaps,
|
||||
introduced in FreeType version 2.6.
|
||||
|
||||
If you use option ``FT_CONFIG_OPTION_USE_PNG`` you should upgrade immediately.
|
||||
* If you use option ``FT_CONFIG_OPTION_USE_PNG`` you should upgrade immediately.
|
||||
|
||||
We strongly recommend updating to Pillow 8.0.1 if you are using Pillow 8.0.0, which improved support for bitmap fonts.
|
||||
|
||||
|
|
|
@ -1,6 +1,50 @@
|
|||
8.1.0
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
This release includes security fixes.
|
||||
|
||||
* An out-of-bounds read when saving TIFFs with custom metadata through LibTIFF
|
||||
* An out-of-bounds read when saving a GIF of 1px width
|
||||
|
||||
:cve:`2020-35653`: Buffer read overrun in PCX decoding
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The PCX image decoder used the reported image stride to calculate
|
||||
the row buffer, rather than calculating it from the image size. This issue dates back
|
||||
to the PIL fork. Thanks to Google's `OSS-Fuzz`_ project for finding this.
|
||||
|
||||
:cve:`2020-35654`: TIFF out-of-bounds write error
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Out-of-bounds write in ``TiffDecode.c`` when reading corrupt YCbCr
|
||||
files in some LibTIFF versions (4.1.0/Ubuntu 20.04, but not 4.0.9/Ubuntu 18.04).
|
||||
In some cases LibTIFF's interpretation of the file is different when reading in RGBA mode,
|
||||
leading to an out-of-bounds write in ``TiffDecode.c``. This potentially affects Pillow
|
||||
versions from 6.0.0 to 8.0.1, depending on the version of LibTIFF. This was reported through
|
||||
`Tidelift`_.
|
||||
|
||||
:cve:`2020-35655`: SGI Decode buffer overrun
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
4 byte read overflow in ``SgiRleDecode.c``, where the code was not correctly
|
||||
checking the offsets and length tables. Independently reported through `Tidelift`_ and Google's
|
||||
`OSS-Fuzz`_. This vulnerability covers Pillow versions 4.3.0->8.0.1.
|
||||
|
||||
.. _Tidelift: https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pillow&utm_medium=referral&utm_campaign=docs
|
||||
.. _OSS-Fuzz: https://github.com/google/oss-fuzz
|
||||
|
||||
Dependencies
|
||||
^^^^^^^^^^^^
|
||||
|
||||
OpenJPEG in the macOS and Linux wheels has been updated from 2.3.1 to 2.4.0, including
|
||||
security fixes.
|
||||
|
||||
LibTIFF in the macOS and Linux wheels has been updated from 4.1.0 to 4.2.0, including
|
||||
security fixes discovered by fuzzers.
|
||||
|
||||
Deprecations
|
||||
============
|
||||
|
||||
|
@ -33,46 +77,6 @@ With this release, a list of images can be provided to the ``append_images`` par
|
|||
when saving, to replace the scaled down versions. This is the same functionality that
|
||||
already exists for the ICNS format.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
This release includes security fixes.
|
||||
|
||||
* An out-of-bounds read when saving TIFFs with custom metadata through LibTIFF
|
||||
* An out-of-bounds read when saving a GIF of 1px width
|
||||
* :cve:`2020-35653` Buffer read overrun in PCX decoding
|
||||
|
||||
The PCX image decoder used the reported image stride to calculate the row buffer,
|
||||
rather than calculating it from the image size. This issue dates back to the PIL fork.
|
||||
Thanks to Google's `OSS-Fuzz`_ project for finding this.
|
||||
|
||||
* :cve:`2020-35654` Fix TIFF out-of-bounds write error
|
||||
|
||||
Out-of-bounds write in ``TiffDecode.c`` when reading corrupt YCbCr files in some
|
||||
LibTIFF versions (4.1.0/Ubuntu 20.04, but not 4.0.9/Ubuntu 18.04). In some cases
|
||||
LibTIFF's interpretation of the file is different when reading in RGBA mode, leading to
|
||||
an out-of-bounds write in ``TiffDecode.c``. This potentially affects Pillow versions
|
||||
from 6.0.0 to 8.0.1, depending on the version of LibTIFF. This was reported through
|
||||
`Tidelift`_.
|
||||
|
||||
* :cve:`2020-35655` Fix for SGI Decode buffer overrun
|
||||
|
||||
4 byte read overflow in ``SgiRleDecode.c``, where the code was not correctly checking the
|
||||
offsets and length tables. Independently reported through `Tidelift`_ and Google's
|
||||
`OSS-Fuzz`_. This vulnerability covers Pillow versions 4.3.0->8.0.1.
|
||||
|
||||
.. _Tidelift: https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pillow&utm_medium=referral&utm_campaign=docs
|
||||
.. _OSS-Fuzz: https://github.com/google/oss-fuzz
|
||||
|
||||
Dependencies
|
||||
^^^^^^^^^^^^
|
||||
|
||||
OpenJPEG in the macOS and Linux wheels has been updated from 2.3.1 to 2.4.0, including
|
||||
security fixes.
|
||||
|
||||
LibTIFF in the macOS and Linux wheels has been updated from 4.1.0 to 4.2.0, including
|
||||
security fixes discovered by fuzzers.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -4,21 +4,33 @@
|
|||
Security
|
||||
========
|
||||
|
||||
:cve:`2021-25289`: The previous fix for :cve:`2020-35654` was insufficient
|
||||
due to incorrect error checking in ``TiffDecode.c``.
|
||||
:cve:`2021-25289`: Correct the fix for :cve:`2020-35654`
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:cve:`2021-25290`: In ``TiffDecode.c``, there is a negative-offset ``memcpy``
|
||||
with an invalid size.
|
||||
The previous fix for :cve:`2020-35654` was insufficient due to incorrect
|
||||
error checking in ``TiffDecode.c``.
|
||||
|
||||
:cve:`2021-25291`: In ``TiffDecode.c``, invalid tile boundaries could lead to
|
||||
an out-of-bounds read in ``TIFFReadRGBATile``.
|
||||
:cve:`2021-25290`: Fix buffer overflow in ``TiffDecode.c``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:cve:`2021-25292`: The PDF parser has a catastrophic backtracking regex
|
||||
that could be used as a DOS attack.
|
||||
In ``TiffDecode.c``, there is a negative-offset ``memcpy`` with an invalid size.
|
||||
|
||||
:cve:`2021-25293`: There is an out-of-bounds read in ``SgiRleDecode.c``,
|
||||
since Pillow 4.3.0.
|
||||
:cve:`2021-25291`: Fix buffer overflow in ``TIFFReadRGBATile``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In ``TiffDecode.c``, invalid tile boundaries could lead to an out-of-bounds
|
||||
read in ``TIFFReadRGBATile``.
|
||||
|
||||
:cve:`2021-25292`: Fix DOS attack
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The PDF parser has a catastrophic backtracking regex that could be used as a
|
||||
DOS attack.
|
||||
|
||||
:cve:`2021-25293`: Fix buffer overflow in ``SgiRleDecode.c``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There is an out-of-bounds read in ``SgiRleDecode.c`` since Pillow 4.3.0.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
Security
|
||||
========
|
||||
|
||||
There is an exhaustion of memory DOS in the BLP (:cve:`2021-27921`),
|
||||
ICNS (:cve:`2021-27922`) and ICO (:cve:`2021-27923`) container formats
|
||||
:cve:`2021-27921`, :cve:`2021-27922`, :cve:`2021-27923`: Fix DOS attacks
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There is an exhaustion of memory DOS attack in BLP, ICNS, ICO images
|
||||
where Pillow did not properly check the reported size of the contained image.
|
||||
These images could cause arbitrarily large memory allocations. This was reported
|
||||
by Jiayi Lin, Luke Shaffer, Xinran Xie, and Akshay Ajayan of
|
||||
`Arizona State University <https://www.asu.edu/>`_.
|
||||
These images could cause arbitrarily large memory allocations.
|
||||
|
||||
These issues were reported by Jiayi Lin, Luke Shaffer, Xinran Xie and
|
||||
Akshay Ajayan of `Arizona State University <https://www.asu.edu/>`_.
|
||||
|
|
|
@ -1,6 +1,60 @@
|
|||
8.2.0
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
These issues were all found with `OSS-Fuzz`_.
|
||||
|
||||
:cve:`2021-25287`, :cve:`2021-25288`: OOB read in Jpeg2KDecode
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* For J2k images with multiple bands, it's legal to have different widths for each band,
|
||||
e.g. 1 byte for ``L``, 4 bytes for ``A``.
|
||||
* This dates to Pillow 2.4.0.
|
||||
|
||||
:cve:`2021-28675`: DOS attack in PsdImagePlugin
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* :py:class:`.PsdImagePlugin.PsdImageFile` did not sanity check the number of input
|
||||
layers with regard to the size of the data block, this could lead to a
|
||||
denial-of-service on :py:meth:`~PIL.Image.open` prior to
|
||||
:py:meth:`~PIL.Image.Image.load`.
|
||||
* This dates to the PIL fork.
|
||||
|
||||
:cve:`2021-28676`: FLI image DOS attack
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* ``FliDecode.c`` did not properly check that the block advance was non-zero,
|
||||
potentially leading to an infinite loop on load.
|
||||
* This dates to the PIL fork.
|
||||
|
||||
:cve:`2021-28677`: EPS DOS on _open
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* The readline used in EPS has to deal with any combination of ``\r`` and ``\n`` as line
|
||||
endings. It accidentally used a quadratic method of accumulating lines while looking
|
||||
for a line ending.
|
||||
* A malicious EPS file could use this to perform a denial-of-service of Pillow in the
|
||||
open phase, before an image was accepted for opening.
|
||||
* This dates to the PIL fork.
|
||||
|
||||
:cve:`2021-28678`: BLP DOS attack
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* ``BlpImagePlugin`` did not properly check that reads after jumping to file offsets
|
||||
returned data. This could lead to a denial-of-service where the decoder could be run a
|
||||
large number of times on empty data.
|
||||
* This dates to Pillow 5.1.0.
|
||||
|
||||
Fix memory DOS in ImageFont
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* A corrupt or specially crafted TTF font could have font metrics that lead to
|
||||
unreasonably large sizes when rendering text in font. ``ImageFont.py`` did not check
|
||||
the image size before allocating memory for it.
|
||||
* This dates to the PIL fork.
|
||||
|
||||
Deprecations
|
||||
============
|
||||
|
||||
|
@ -123,61 +177,6 @@ be specified through a keyword argument::
|
|||
|
||||
im.save("out.tif", icc_profile=...)
|
||||
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
These were all found with `OSS-Fuzz`_.
|
||||
|
||||
:cve:`2021-25287`, :cve:`2021-25288`: Fix OOB read in Jpeg2KDecode
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* For J2k images with multiple bands, it's legal to have different widths for each band,
|
||||
e.g. 1 byte for ``L``, 4 bytes for ``A``.
|
||||
* This dates to Pillow 2.4.0.
|
||||
|
||||
:cve:`2021-28675`: Fix DOS in PsdImagePlugin
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* :py:class:`.PsdImagePlugin.PsdImageFile` did not sanity check the number of input
|
||||
layers with regard to the size of the data block, this could lead to a
|
||||
denial-of-service on :py:meth:`~PIL.Image.open` prior to
|
||||
:py:meth:`~PIL.Image.Image.load`.
|
||||
* This dates to the PIL fork.
|
||||
|
||||
:cve:`2021-28676`: Fix FLI DOS
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* ``FliDecode.c`` did not properly check that the block advance was non-zero,
|
||||
potentially leading to an infinite loop on load.
|
||||
* This dates to the PIL fork.
|
||||
|
||||
:cve:`2021-28677`: Fix EPS DOS on _open
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* The readline used in EPS has to deal with any combination of ``\r`` and ``\n`` as line
|
||||
endings. It accidentally used a quadratic method of accumulating lines while looking
|
||||
for a line ending.
|
||||
* A malicious EPS file could use this to perform a denial-of-service of Pillow in the
|
||||
open phase, before an image was accepted for opening.
|
||||
* This dates to the PIL fork.
|
||||
|
||||
:cve:`2021-28678`: Fix BLP DOS
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* ``BlpImagePlugin`` did not properly check that reads after jumping to file offsets
|
||||
returned data. This could lead to a denial-of-service where the decoder could be run a
|
||||
large number of times on empty data.
|
||||
* This dates to Pillow 5.1.0.
|
||||
|
||||
Fix memory DOS in ImageFont
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* A corrupt or specially crafted TTF font could have font metrics that lead to
|
||||
unreasonably large sizes when rendering text in font. ``ImageFont.py`` did not check
|
||||
the image size before allocating memory for it.
|
||||
* This dates to the PIL fork.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -1,6 +1,27 @@
|
|||
8.3.0
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
:cve:`2021-34552`: Fix buffer overflow
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
PIL since 1.1.4 and Pillow since 1.0 allowed parameters passed into a convert
|
||||
function to trigger buffer overflow in ``Convert.c``.
|
||||
|
||||
Parsing XML
|
||||
^^^^^^^^^^^
|
||||
|
||||
Pillow previously parsed XMP data using Python's ``xml`` module. However, this module
|
||||
is not secure.
|
||||
|
||||
- :py:meth:`~PIL.Image.Image.getexif` has used ``xml`` to potentially retrieve
|
||||
orientation data since Pillow 7.2.0. It has been refactored to use ``re`` instead.
|
||||
- :py:meth:`~PIL.JpegImagePlugin.JpegImageFile.getxmp` was added in Pillow 8.2.0. It
|
||||
will now use ``defusedxml`` instead. If the dependency is not present, an empty
|
||||
dictionary will be returned and a warning raised.
|
||||
|
||||
Deprecations
|
||||
============
|
||||
|
||||
|
@ -79,28 +100,6 @@ format, through the new ``bitmap_format`` argument::
|
|||
|
||||
im.save("out.ico", bitmap_format="bmp")
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Buffer overflow
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
This release addresses :cve:`2021-34552`. PIL since 1.1.4 and Pillow since 1.0
|
||||
allowed parameters passed into a convert function to trigger buffer overflow in
|
||||
Convert.c.
|
||||
|
||||
Parsing XML
|
||||
^^^^^^^^^^^
|
||||
|
||||
Pillow previously parsed XMP data using Python's ``xml`` module. However, this module
|
||||
is not secure.
|
||||
|
||||
- :py:meth:`~PIL.Image.Image.getexif` has used ``xml`` to potentially retrieve
|
||||
orientation data since Pillow 7.2.0. It has been refactored to use ``re`` instead.
|
||||
- :py:meth:`~PIL.JpegImagePlugin.JpegImageFile.getxmp` was added in Pillow 8.2.0. It
|
||||
will now use ``defusedxml`` instead. If the dependency is not present, an empty
|
||||
dictionary will be returned and a warning raised.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
-----
|
||||
|
||||
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.
|
||||
|
@ -19,7 +19,7 @@ with a ``dtype`` argument.
|
|||
>>>
|
||||
|
||||
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 :py:exc:`OSError` being raised if the environment restricted
|
||||
|
@ -28,7 +28,7 @@ access.
|
|||
The :py:exc:`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
|
||||
|
|
|
@ -4,14 +4,21 @@
|
|||
Security
|
||||
========
|
||||
|
||||
* :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.
|
||||
:cve:`2021-23437`: Avoid potential ReDoS (regular expression denial of service)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* 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.
|
||||
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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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
|
||||
=============
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
8.4.0
|
||||
-----
|
||||
|
||||
API Changes
|
||||
===========
|
||||
|
||||
Deprecations
|
||||
^^^^^^^^^^^^
|
||||
============
|
||||
|
||||
ImagePalette size parameter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``size`` parameter will be removed in Pillow 10.0.0 (2023-07-01).
|
||||
|
||||
|
|
|
@ -24,6 +24,41 @@ success of Python.
|
|||
|
||||
Thank you, Fredrik.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Ensure JpegImagePlugin stops at the end of a truncated file
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``JpegImagePlugin`` may append an EOF marker to the end of a truncated file, so that
|
||||
the last segment of the data will still be processed by the decoder.
|
||||
|
||||
If the EOF marker is not detected as such however, this could lead to an infinite
|
||||
loop where ``JpegImagePlugin`` keeps trying to end the file.
|
||||
|
||||
Remove consecutive duplicate tiles that only differ by their offset
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To prevent attempts to slow down loading times for images, if an image has consecutive
|
||||
duplicate tiles that only differ by their offset, only load the last tile. Credit to
|
||||
Google's `OSS-Fuzz`_ project for finding this issue.
|
||||
|
||||
:cve:`2022-22817`: Restrict builtins available to ImageMath.eval
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To limit :py:class:`PIL.ImageMath` to working with images, Pillow
|
||||
will now restrict the builtins available to :py:meth:`PIL.ImageMath.eval`. This will
|
||||
help prevent problems arising if users evaluate arbitrary expressions, such as
|
||||
``ImageMath.eval("exec(exit())")``.
|
||||
|
||||
:cve:`2022-22815`, :cve:`2022-22816`: ImagePath.Path array handling
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:cve:`2022-22815` (:cwe:`126`) and :cve:`2022-22816` (:cwe:`665`) were found when
|
||||
initializing ``ImagePath.Path``.
|
||||
|
||||
.. _OSS-Fuzz: https://github.com/google/oss-fuzz
|
||||
|
||||
Backwards Incompatible Changes
|
||||
==============================
|
||||
|
||||
|
@ -97,41 +132,6 @@ Support has been added for the "title" argument in
|
|||
argument will also now be supported, e.g. ``im.show(title="My Image")`` and
|
||||
``ImageShow.show(im, title="My Image")``.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Ensure JpegImagePlugin stops at the end of a truncated file
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``JpegImagePlugin`` may append an EOF marker to the end of a truncated file, so that
|
||||
the last segment of the data will still be processed by the decoder.
|
||||
|
||||
If the EOF marker is not detected as such however, this could lead to an infinite
|
||||
loop where ``JpegImagePlugin`` keeps trying to end the file.
|
||||
|
||||
Remove consecutive duplicate tiles that only differ by their offset
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To prevent attempts to slow down loading times for images, if an image has consecutive
|
||||
duplicate tiles that only differ by their offset, only load the last tile. Credit to
|
||||
Google's `OSS-Fuzz`_ project for finding this issue.
|
||||
|
||||
Restrict builtins available to ImageMath.eval
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:cve:`2022-22817`: To limit :py:class:`PIL.ImageMath` to working with images, Pillow
|
||||
will now restrict the builtins available to :py:meth:`PIL.ImageMath.eval`. This will
|
||||
help prevent problems arising if users evaluate arbitrary expressions, such as
|
||||
``ImageMath.eval("exec(exit())")``.
|
||||
|
||||
Fixed ImagePath.Path array handling
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:cve:`2022-22815` (:cwe:`126`) and :cve:`2022-22816` (:cwe:`665`) were
|
||||
found when initializing ``ImagePath.Path``.
|
||||
|
||||
.. _OSS-Fuzz: https://github.com/google/oss-fuzz
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -6,14 +6,20 @@ Security
|
|||
|
||||
This release addresses several security problems.
|
||||
|
||||
:cve:`2022-24303`: If the path to the temporary directory on Linux or macOS
|
||||
:cve:`2022-24303`: Temp image removal
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If the path to the temporary directory on Linux or macOS
|
||||
contained a space, this would break removal of the temporary image file after
|
||||
``im.show()`` (and related actions), and potentially remove an unrelated file. This
|
||||
has been present since PIL.
|
||||
|
||||
:cve:`2022-22817`: While Pillow 9.0 restricted top-level builtins available to
|
||||
:py:meth:`PIL.ImageMath.eval`, it did not prevent builtins available to lambda
|
||||
expressions. These are now also restricted.
|
||||
:cve:`2022-22817`: Restrict lambda expressions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
While Pillow 9.0 restricted top-level builtins available to
|
||||
:py:meth:`PIL.ImageMath.eval`, it did not prevent builtins
|
||||
available to lambda expressions. These are now also restricted.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
|
|
@ -1,49 +1,6 @@
|
|||
9.1.0
|
||||
-----
|
||||
|
||||
API Changes
|
||||
===========
|
||||
|
||||
Raise an error when performing a negative crop
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Performing a negative crop on an image previously just returned a ``(0, 0)`` image. Now
|
||||
it will raise a :py:exc:`ValueError`, to help reduce confusion if a user has unintentionally
|
||||
provided the wrong arguments.
|
||||
|
||||
Added specific error if path coordinate type is incorrect
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Rather than returning a :py:exc:`SystemError`, passing the incorrect types of coordinates into
|
||||
a path will now raise a more specific :py:exc:`ValueError`, with the message "incorrect
|
||||
coordinate type".
|
||||
|
||||
Replace requirements.txt with extras
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Rather than installing all dependencies for docs and tests via ``requirements.txt``,
|
||||
``extras_require`` is used instead. This installs only those needed and at the same
|
||||
time as installing Pillow.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Install with dependencies for tests:
|
||||
python3 -m pip install .[tests]
|
||||
|
||||
# Or for building docs:
|
||||
python3 -m pip install .[docs]
|
||||
|
||||
# Or for all:
|
||||
python3 -m pip install .[docs,tests]
|
||||
|
||||
On macOS, the last argument may need to be wrapped in quotes, e.g.
|
||||
``python3 -m pip install ".[tests]"``
|
||||
|
||||
Therefore ``requirements.txt`` has been removed along with the ``make install-req``
|
||||
command for installing its contents.
|
||||
|
||||
Deprecations
|
||||
============
|
||||
|
||||
|
@ -137,6 +94,49 @@ The stub image plugin ``FitsStubImagePlugin`` has been deprecated and will be re
|
|||
Pillow 10.0.0 (2023-07-01). FITS images can be read without a handler through
|
||||
:mod:`~PIL.FitsImagePlugin` instead.
|
||||
|
||||
API Changes
|
||||
===========
|
||||
|
||||
Raise an error when performing a negative crop
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Performing a negative crop on an image previously just returned a ``(0, 0)`` image. Now
|
||||
it will raise a :py:exc:`ValueError`, to help reduce confusion if a user has unintentionally
|
||||
provided the wrong arguments.
|
||||
|
||||
Added specific error if path coordinate type is incorrect
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Rather than returning a :py:exc:`SystemError`, passing the incorrect types of coordinates into
|
||||
a path will now raise a more specific :py:exc:`ValueError`, with the message "incorrect
|
||||
coordinate type".
|
||||
|
||||
Replace requirements.txt with extras
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Rather than installing all dependencies for docs and tests via ``requirements.txt``,
|
||||
``extras_require`` is used instead. This installs only those needed and at the same
|
||||
time as installing Pillow.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Install with dependencies for tests:
|
||||
python3 -m pip install .[tests]
|
||||
|
||||
# Or for building docs:
|
||||
python3 -m pip install .[docs]
|
||||
|
||||
# Or for all:
|
||||
python3 -m pip install .[docs,tests]
|
||||
|
||||
On macOS, the last argument may need to be wrapped in quotes, e.g.
|
||||
``python3 -m pip install ".[tests]"``
|
||||
|
||||
Therefore ``requirements.txt`` has been removed along with the ``make install-req``
|
||||
command for installing its contents.
|
||||
|
||||
API Additions
|
||||
=============
|
||||
|
||||
|
|
|
@ -4,13 +4,19 @@
|
|||
Security
|
||||
========
|
||||
|
||||
This release addresses several security problems.
|
||||
This release addresses several security issues.
|
||||
|
||||
:cve:`2022-30595`: When reading a TGA file with RLE packets that cross scan lines,
|
||||
:cve:`2022-30595`: Heap buffer overflow
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When reading a TGA file with RLE packets that cross scan lines,
|
||||
Pillow reads the information past the end of the first line without deducting that
|
||||
from the length of the remaining file data. This vulnerability was introduced in Pillow
|
||||
9.1.0, and can cause a heap buffer overflow.
|
||||
|
||||
Decompression bomb check fix
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Opening an image with a zero or negative height has been found to bypass a
|
||||
decompression bomb check. This will now raise a :py:exc:`SyntaxError` instead, in turn
|
||||
raising a ``PIL.UnidentifiedImageError``.
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
9.2.0
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
An additional decompression bomb check has been added for the GIF format.
|
||||
|
||||
Deprecations
|
||||
============
|
||||
|
||||
|
@ -132,11 +137,6 @@ with "transparency" in ``im.info``, and apply the transparency to the palette in
|
|||
The image's palette mode will become "RGBA", and "transparency" will be removed from
|
||||
``im.info``.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
An additional decompression bomb check has been added for the GIF format.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -1,6 +1,33 @@
|
|||
9.3.0
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Initialize libtiff buffer when saving
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When saving a TIFF image to a file object using libtiff, the buffer was not
|
||||
initialized. This behaviour introduced in Pillow 2.0.0, and has now been fixed.
|
||||
|
||||
Decode JPEG compressed BLP1 data in original mode
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Within the BLP image format, BLP1 data may use JPEG compression. Instead of
|
||||
telling the JPEG library that this data is in BGRX mode, Pillow will now
|
||||
decode the data in its natural CMYK mode, then convert it to RGB and rearrange
|
||||
the channels afterwards. Trying to load the data in an incorrect mode could
|
||||
result in a segmentation fault. This issue was introduced in Pillow 9.1.0.
|
||||
|
||||
Limit SAMPLESPERPIXEL to avoid runtime DOS
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A large value in the ``SAMPLESPERPIXEL`` tag could lead to a memory and runtime DOS in
|
||||
``TiffImagePlugin.py`` when setting up the context for image decoding.
|
||||
This was introduced in Pillow 9.2.0, found with `OSS-Fuzz`_ and fixed by limiting
|
||||
``SAMPLESPERPIXEL`` to the number of planes that we can decode.
|
||||
|
||||
|
||||
API Additions
|
||||
=============
|
||||
|
||||
|
@ -38,33 +65,6 @@ The data from :py:data:`~PIL.ExifTags.TAGS` and
|
|||
:py:data:`~PIL.ExifTags.GPS`.
|
||||
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Initialize libtiff buffer when saving
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When saving a TIFF image to a file object using libtiff, the buffer was not
|
||||
initialized. This behaviour introduced in Pillow 2.0.0, and has now been fixed.
|
||||
|
||||
Decode JPEG compressed BLP1 data in original mode
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Within the BLP image format, BLP1 data may use JPEG compression. Instead of
|
||||
telling the JPEG library that this data is in BGRX mode, Pillow will now
|
||||
decode the data in its natural CMYK mode, then convert it to RGB and rearrange
|
||||
the channels afterwards. Trying to load the data in an incorrect mode could
|
||||
result in a segmentation fault. This issue was introduced in Pillow 9.1.0.
|
||||
|
||||
Limit SAMPLESPERPIXEL to avoid runtime DOS
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A large value in the ``SAMPLESPERPIXEL`` tag could lead to a memory and runtime DOS in
|
||||
``TiffImagePlugin.py`` when setting up the context for image decoding.
|
||||
This was introduced in Pillow 9.2.0, found with `OSS-Fuzz`_ and fixed by limiting
|
||||
``SAMPLESPERPIXEL`` to the number of planes that we can decode.
|
||||
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
9.4.0
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Fix memory DOS in ImageFont
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A corrupt or specially crafted TTF font could have font metrics that lead to
|
||||
unreasonably large sizes when rendering text in font. ``ImageFont.py`` did not
|
||||
check the image size before allocating memory for it. This dates to the PIL
|
||||
fork. Pillow 8.2.0 added a check for large sizes, but did not consider the
|
||||
case where one dimension is zero.
|
||||
|
||||
Null pointer dereference crash in ImageFont
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow attempted to dereference a null pointer in ``ImageFont``, leading to a
|
||||
crash. An error is now raised instead. This has been present since
|
||||
Pillow 8.0.0.
|
||||
|
||||
API Additions
|
||||
=============
|
||||
|
||||
|
@ -69,25 +88,6 @@ When saving a JPEG image, a comment can now be written from
|
|||
|
||||
im.save(out, comment="Test comment")
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Fix memory DOS in ImageFont
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A corrupt or specially crafted TTF font could have font metrics that lead to
|
||||
unreasonably large sizes when rendering text in font. ``ImageFont.py`` did not
|
||||
check the image size before allocating memory for it. This dates to the PIL
|
||||
fork. Pillow 8.2.0 added a check for large sizes, but did not consider the
|
||||
case where one dimension is zero.
|
||||
|
||||
Null pointer dereference crash in ImageFont
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow attempted to dereference a null pointer in ``ImageFont``, leading to a
|
||||
crash. An error is now raised instead. This has been present since
|
||||
Pillow 8.0.0.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -1,6 +1,31 @@
|
|||
9.5.0
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Clear PPM half token after use
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Image files that are small on disk are often prevented from expanding to be
|
||||
big images consuming a large amount of resources simply because they lack the
|
||||
data to populate those resources.
|
||||
|
||||
PpmImagePlugin might hold onto the last data read for a pixel value in case the
|
||||
pixel value has not been finished yet. However, that data was not being cleared
|
||||
afterwards, meaning that infinite data could be available to fill any image
|
||||
size. This has been present since Pillow 9.2.0.
|
||||
|
||||
That data is now cleared after use.
|
||||
|
||||
Saving TIFF tag ImageSourceData
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If Pillow incorrectly saved the TIFF tag ImageSourceData as ASCII instead of
|
||||
UNDEFINED, a segmentation fault was triggered.
|
||||
|
||||
The correct tag type will now be used by default instead.
|
||||
|
||||
Deprecations
|
||||
============
|
||||
|
||||
|
@ -46,31 +71,6 @@ If OpenJPEG 2.4.0 or later is available and the ``plt`` keyword argument
|
|||
is present and true when saving JPEG2000 images, tell the encoder to generate
|
||||
PLT markers.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Clear PPM half token after use
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Image files that are small on disk are often prevented from expanding to be
|
||||
big images consuming a large amount of resources simply because they lack the
|
||||
data to populate those resources.
|
||||
|
||||
PpmImagePlugin might hold onto the last data read for a pixel value in case the
|
||||
pixel value has not been finished yet. However, that data was not being cleared
|
||||
afterwards, meaning that infinite data could be available to fill any image
|
||||
size. This has been present since Pillow 9.2.0.
|
||||
|
||||
That data is now cleared after use.
|
||||
|
||||
Saving TIFF tag ImageSourceData
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If Pillow incorrectly saved the TIFF tag ImageSourceData as ASCII instead of
|
||||
UNDEFINED, a segmentation fault was triggered.
|
||||
|
||||
The correct tag type will now be used by default instead.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -69,4 +69,8 @@ expected to be backported to earlier versions.
|
|||
3.0.0
|
||||
2.8.0
|
||||
2.7.0
|
||||
2.6.0
|
||||
2.5.2
|
||||
2.3.2
|
||||
2.3.1
|
||||
versioning
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
xx.y.z
|
||||
------
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
|
||||
TODO
|
||||
|
||||
:cve:`YYYY-XXXXX`: TODO
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
TODO
|
||||
|
||||
Backwards Incompatible Changes
|
||||
==============================
|
||||
|
||||
|
@ -31,14 +44,6 @@ TODO
|
|||
|
||||
TODO
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
|
||||
TODO
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ keywords = [
|
|||
"Imaging",
|
||||
]
|
||||
license = {text = "HPND"}
|
||||
authors = [{name = "Jeffrey A. Clark (Alex)", email = "aclark@aclark.net"}]
|
||||
authors = [{name = "Jeffrey A. Clark", email = "aclark@aclark.net"}]
|
||||
requires-python = ">=3.8"
|
||||
classifiers = [
|
||||
"Development Status :: 6 - Mature",
|
||||
|
@ -106,6 +106,7 @@ select = [
|
|||
"ISC", # flake8-implicit-str-concat
|
||||
"LOG", # flake8-logging
|
||||
"PGH", # pygrep-hooks
|
||||
"PYI", # flake8-pyi
|
||||
"RUF100", # unused noqa (yesqa)
|
||||
"UP", # pyupgrade
|
||||
"W", # pycodestyle warnings
|
||||
|
@ -116,6 +117,7 @@ ignore = [
|
|||
"E221", # Multiple spaces before operator
|
||||
"E226", # Missing whitespace around arithmetic operator
|
||||
"E241", # Multiple spaces after ','
|
||||
"PYI034", # flake8-pyi: typing.Self added in Python 3.11
|
||||
]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#
|
||||
from __future__ import annotations
|
||||
|
||||
import gzip
|
||||
import math
|
||||
|
||||
from . import Image, ImageFile
|
||||
|
@ -27,14 +28,32 @@ class FitsImageFile(ImageFile.ImageFile):
|
|||
assert self.fp is not None
|
||||
|
||||
headers: dict[bytes, bytes] = {}
|
||||
header_in_progress = False
|
||||
decoder_name = ""
|
||||
while True:
|
||||
header = self.fp.read(80)
|
||||
if not header:
|
||||
msg = "Truncated FITS file"
|
||||
raise OSError(msg)
|
||||
keyword = header[:8].strip()
|
||||
if keyword == b"END":
|
||||
if keyword in (b"SIMPLE", b"XTENSION"):
|
||||
header_in_progress = True
|
||||
elif headers and not header_in_progress:
|
||||
# This is now a data unit
|
||||
break
|
||||
elif keyword == b"END":
|
||||
# Seek to the end of the header unit
|
||||
self.fp.seek(math.ceil(self.fp.tell() / 2880) * 2880)
|
||||
if not decoder_name:
|
||||
decoder_name, offset, args = self._parse_headers(headers)
|
||||
|
||||
header_in_progress = False
|
||||
continue
|
||||
|
||||
if decoder_name:
|
||||
# Keep going to read past the headers
|
||||
continue
|
||||
|
||||
value = header[8:].split(b"/")[0].strip()
|
||||
if value.startswith(b"="):
|
||||
value = value[1:].strip()
|
||||
|
@ -43,32 +62,87 @@ class FitsImageFile(ImageFile.ImageFile):
|
|||
raise SyntaxError(msg)
|
||||
headers[keyword] = value
|
||||
|
||||
naxis = int(headers[b"NAXIS"])
|
||||
if naxis == 0:
|
||||
if not decoder_name:
|
||||
msg = "No image data"
|
||||
raise ValueError(msg)
|
||||
elif naxis == 1:
|
||||
self._size = 1, int(headers[b"NAXIS1"])
|
||||
else:
|
||||
self._size = int(headers[b"NAXIS1"]), int(headers[b"NAXIS2"])
|
||||
|
||||
number_of_bits = int(headers[b"BITPIX"])
|
||||
offset += self.fp.tell() - 80
|
||||
self.tile = [(decoder_name, (0, 0) + self.size, offset, args)]
|
||||
|
||||
def _get_size(
|
||||
self, headers: dict[bytes, bytes], prefix: bytes
|
||||
) -> tuple[int, int] | None:
|
||||
naxis = int(headers[prefix + b"NAXIS"])
|
||||
if naxis == 0:
|
||||
return None
|
||||
|
||||
if naxis == 1:
|
||||
return 1, int(headers[prefix + b"NAXIS1"])
|
||||
else:
|
||||
return int(headers[prefix + b"NAXIS1"]), int(headers[prefix + b"NAXIS2"])
|
||||
|
||||
def _parse_headers(
|
||||
self, headers: dict[bytes, bytes]
|
||||
) -> tuple[str, int, tuple[str | int, ...]]:
|
||||
prefix = b""
|
||||
decoder_name = "raw"
|
||||
offset = 0
|
||||
if (
|
||||
headers.get(b"XTENSION") == b"'BINTABLE'"
|
||||
and headers.get(b"ZIMAGE") == b"T"
|
||||
and headers[b"ZCMPTYPE"] == b"'GZIP_1 '"
|
||||
):
|
||||
no_prefix_size = self._get_size(headers, prefix) or (0, 0)
|
||||
number_of_bits = int(headers[b"BITPIX"])
|
||||
offset = no_prefix_size[0] * no_prefix_size[1] * (number_of_bits // 8)
|
||||
|
||||
prefix = b"Z"
|
||||
decoder_name = "fits_gzip"
|
||||
|
||||
size = self._get_size(headers, prefix)
|
||||
if not size:
|
||||
return "", 0, ()
|
||||
|
||||
self._size = size
|
||||
|
||||
number_of_bits = int(headers[prefix + b"BITPIX"])
|
||||
if number_of_bits == 8:
|
||||
self._mode = "L"
|
||||
elif number_of_bits == 16:
|
||||
self._mode = "I"
|
||||
self._mode = "I;16"
|
||||
elif number_of_bits == 32:
|
||||
self._mode = "I"
|
||||
elif number_of_bits in (-32, -64):
|
||||
self._mode = "F"
|
||||
|
||||
offset = math.ceil(self.fp.tell() / 2880) * 2880
|
||||
self.tile = [("raw", (0, 0) + self.size, offset, (self.mode, 0, -1))]
|
||||
args = (self.mode, 0, -1) if decoder_name == "raw" else (number_of_bits,)
|
||||
return decoder_name, offset, args
|
||||
|
||||
|
||||
class FitsGzipDecoder(ImageFile.PyDecoder):
|
||||
_pulls_fd = True
|
||||
|
||||
def decode(self, buffer):
|
||||
assert self.fd is not None
|
||||
value = gzip.decompress(self.fd.read())
|
||||
|
||||
rows = []
|
||||
offset = 0
|
||||
number_of_bits = min(self.args[0] // 8, 4)
|
||||
for y in range(self.state.ysize):
|
||||
row = bytearray()
|
||||
for x in range(self.state.xsize):
|
||||
row += value[offset + (4 - number_of_bits) : offset + 4]
|
||||
offset += 4
|
||||
rows.append(row)
|
||||
self.set_as_raw(bytes([pixel for row in rows[::-1] for pixel in row]))
|
||||
return -1, 0
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Registry
|
||||
|
||||
Image.register_open(FitsImageFile.format, FitsImageFile, _accept)
|
||||
Image.register_decoder("fits_gzip", FitsGzipDecoder)
|
||||
|
||||
Image.register_extensions(FitsImageFile.format, [".fit", ".fits"])
|
||||
|
|
|
@ -702,7 +702,7 @@ class Image:
|
|||
pass
|
||||
else:
|
||||
if parse_version(numpy.__version__) < parse_version("1.23"):
|
||||
warnings.warn(e)
|
||||
warnings.warn(str(e))
|
||||
raise
|
||||
new["shape"], new["typestr"] = _conv_type_shape(self)
|
||||
return new
|
||||
|
@ -894,9 +894,8 @@ class Image:
|
|||
omitted, a mode is chosen so that all information in the image
|
||||
and the palette can be represented without a palette.
|
||||
|
||||
The current version supports all possible conversions between
|
||||
"L", "RGB" and "CMYK". The ``matrix`` argument only supports "L"
|
||||
and "RGB".
|
||||
This supports all possible conversions between "L", "RGB" and "CMYK". The
|
||||
``matrix`` argument only supports "L" and "RGB".
|
||||
|
||||
When translating a color image to grayscale (mode "L"),
|
||||
the library uses the ITU-R 601-2 luma transform::
|
||||
|
@ -979,7 +978,7 @@ class Image:
|
|||
# transparency handling
|
||||
if has_transparency:
|
||||
if (self.mode in ("1", "L", "I", "I;16") and mode in ("LA", "RGBA")) or (
|
||||
self.mode == "RGB" and mode == "RGBA"
|
||||
self.mode == "RGB" and mode in ("La", "LA", "RGBa", "RGBA")
|
||||
):
|
||||
# Use transparent conversion to promote from transparent
|
||||
# color to an alpha channel.
|
||||
|
@ -1141,7 +1140,7 @@ class Image:
|
|||
The exception to this is RGBA images. :data:`Quantize.MEDIANCUT`
|
||||
and :data:`Quantize.MAXCOVERAGE` do not support RGBA images, so
|
||||
:data:`Quantize.FASTOCTREE` is used by default instead.
|
||||
:param kmeans: Integer
|
||||
:param kmeans: Integer greater than or equal to zero.
|
||||
:param palette: Quantize to the palette of given
|
||||
:py:class:`PIL.Image.Image`.
|
||||
:param dither: Dithering method, used when converting from
|
||||
|
@ -1184,6 +1183,10 @@ class Image:
|
|||
new_im.palette = palette.palette.copy()
|
||||
return new_im
|
||||
|
||||
if kmeans < 0:
|
||||
msg = "kmeans must not be negative"
|
||||
raise ValueError(msg)
|
||||
|
||||
im = self._new(self.im.quantize(colors, method, kmeans))
|
||||
|
||||
from . import ImagePalette
|
||||
|
@ -1820,9 +1823,8 @@ class Image:
|
|||
class Example(Image.ImagePointHandler):
|
||||
def point(self, data):
|
||||
# Return result
|
||||
:param mode: Output mode (default is same as input). In the
|
||||
current version, this can only be used if the source image
|
||||
has mode "L" or "P", and the output has mode "1" or the
|
||||
:param mode: Output mode (default is same as input). This can only be used if
|
||||
the source image has mode "L" or "P", and the output has mode "1" or the
|
||||
source image mode is "I" and the output mode is "L".
|
||||
:returns: An :py:class:`~PIL.Image.Image` object.
|
||||
"""
|
||||
|
@ -3016,11 +3018,10 @@ def frombuffer(mode, size, data, decoder_name="raw", *args):
|
|||
If you have an entire image file in a string, wrap it in a
|
||||
:py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load it.
|
||||
|
||||
In the current version, the default parameters used for the "raw" decoder
|
||||
differs from that used for :py:func:`~PIL.Image.frombytes`. This is a
|
||||
bug, and will probably be fixed in a future release. The current release
|
||||
issues a warning if you do this; to disable the warning, you should provide
|
||||
the full set of parameters. See below for details.
|
||||
The default parameters used for the "raw" decoder differs from that used for
|
||||
:py:func:`~PIL.Image.frombytes`. This is a bug, and will probably be fixed in a
|
||||
future release. The current release issues a warning if you do this; to disable
|
||||
the warning, you should provide the full set of parameters. See below for details.
|
||||
|
||||
:param mode: The image mode. See: :ref:`concept-modes`.
|
||||
:param size: The image size.
|
||||
|
|
|
@ -25,7 +25,7 @@ from enum import IntEnum, IntFlag
|
|||
from functools import reduce
|
||||
from typing import Any
|
||||
|
||||
from . import Image
|
||||
from . import Image, __version__
|
||||
from ._deprecate import deprecate
|
||||
|
||||
try:
|
||||
|
@ -1087,4 +1087,4 @@ def versions():
|
|||
12,
|
||||
'(PIL.features.version("littlecms2"), sys.version, PIL.__version__)',
|
||||
)
|
||||
return _VERSION, core.littlecms_version, sys.version.split()[0], Image.__version__
|
||||
return _VERSION, core.littlecms_version, sys.version.split()[0], __version__
|
||||
|
|
|
@ -336,6 +336,10 @@ class ImageDraw:
|
|||
|
||||
d = radius * 2
|
||||
|
||||
x0 = round(x0)
|
||||
y0 = round(y0)
|
||||
x1 = round(x1)
|
||||
y1 = round(y1)
|
||||
full_x, full_y = False, False
|
||||
if all(corners):
|
||||
full_x = d >= x1 - x0 - 1
|
||||
|
|
|
@ -37,21 +37,18 @@ class BuiltinFilter(MultibandFilter):
|
|||
|
||||
class Kernel(BuiltinFilter):
|
||||
"""
|
||||
Create a convolution kernel. The current version only
|
||||
supports 3x3 and 5x5 integer and floating point kernels.
|
||||
Create a convolution kernel. This only supports 3x3 and 5x5 integer and floating
|
||||
point kernels.
|
||||
|
||||
In the current version, kernels can only be applied to
|
||||
"L" and "RGB" images.
|
||||
Kernels can only be applied to "L" and "RGB" images.
|
||||
|
||||
:param size: Kernel size, given as (width, height). In the current
|
||||
version, this must be (3,3) or (5,5).
|
||||
:param kernel: A sequence containing kernel weights. The kernel will
|
||||
be flipped vertically before being applied to the image.
|
||||
:param scale: Scale factor. If given, the result for each pixel is
|
||||
divided by this value. The default is the sum of the
|
||||
kernel weights.
|
||||
:param offset: Offset. If given, this value is added to the result,
|
||||
after it has been divided by the scale factor.
|
||||
:param size: Kernel size, given as (width, height). This must be (3,3) or (5,5).
|
||||
:param kernel: A sequence containing kernel weights. The kernel will be flipped
|
||||
vertically before being applied to the image.
|
||||
:param scale: Scale factor. If given, the result for each pixel is divided by this
|
||||
value. The default is the sum of the kernel weights.
|
||||
:param offset: Offset. If given, this value is added to the result, after it has
|
||||
been divided by the scale factor.
|
||||
"""
|
||||
|
||||
name = "Kernel"
|
||||
|
|
|
@ -19,7 +19,7 @@ import io
|
|||
import os
|
||||
import struct
|
||||
|
||||
from . import Image, ImageFile, _binary
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
|
||||
class BoxReader:
|
||||
|
@ -106,15 +106,11 @@ def _parse_codestream(fp):
|
|||
lsiz, rsiz, xsiz, ysiz, xosiz, yosiz, _, _, _, _, csiz = struct.unpack_from(
|
||||
">HHIIIIIIIIH", siz
|
||||
)
|
||||
ssiz = [None] * csiz
|
||||
xrsiz = [None] * csiz
|
||||
yrsiz = [None] * csiz
|
||||
for i in range(csiz):
|
||||
ssiz[i], xrsiz[i], yrsiz[i] = struct.unpack_from(">BBB", siz, 36 + 3 * i)
|
||||
|
||||
size = (xsiz - xosiz, ysiz - yosiz)
|
||||
if csiz == 1:
|
||||
if (yrsiz[0] & 0x7F) > 8:
|
||||
ssiz = struct.unpack_from(">B", siz, 38)
|
||||
if (ssiz[0] & 0x7F) + 1 > 8:
|
||||
mode = "I;16"
|
||||
else:
|
||||
mode = "L"
|
||||
|
@ -162,6 +158,7 @@ def _parse_jp2_header(fp):
|
|||
bpc = None
|
||||
nc = None
|
||||
dpi = None # 2-tuple of DPI info, or None
|
||||
palette = None
|
||||
|
||||
while header.has_next_box():
|
||||
tbox = header.next_box_type()
|
||||
|
@ -179,6 +176,14 @@ def _parse_jp2_header(fp):
|
|||
mode = "RGB"
|
||||
elif nc == 4:
|
||||
mode = "RGBA"
|
||||
elif tbox == b"pclr" and mode in ("L", "LA"):
|
||||
ne, npc = header.read_fields(">HB")
|
||||
bitdepths = header.read_fields(">" + ("B" * npc))
|
||||
if max(bitdepths) <= 8:
|
||||
palette = ImagePalette.ImagePalette()
|
||||
for i in range(ne):
|
||||
palette.getcolor(header.read_fields(">" + ("B" * npc)))
|
||||
mode = "P" if mode == "L" else "PA"
|
||||
elif tbox == b"res ":
|
||||
res = header.read_boxes()
|
||||
while res.has_next_box():
|
||||
|
@ -195,7 +200,7 @@ def _parse_jp2_header(fp):
|
|||
msg = "Malformed JP2 header"
|
||||
raise SyntaxError(msg)
|
||||
|
||||
return size, mode, mimetype, dpi
|
||||
return size, mode, mimetype, dpi, palette
|
||||
|
||||
|
||||
##
|
||||
|
@ -217,7 +222,7 @@ class Jpeg2KImageFile(ImageFile.ImageFile):
|
|||
if sig == b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a":
|
||||
self.codec = "jp2"
|
||||
header = _parse_jp2_header(self.fp)
|
||||
self._size, self._mode, self.custom_mimetype, dpi = header
|
||||
self._size, self._mode, self.custom_mimetype, dpi, self.palette = header
|
||||
if dpi is not None:
|
||||
self.info["dpi"] = dpi
|
||||
if self.fp.read(12).endswith(b"jp2c\xff\x4f\xff\x51"):
|
||||
|
|
|
@ -24,14 +24,11 @@ import os
|
|||
import struct
|
||||
|
||||
from . import (
|
||||
ExifTags,
|
||||
Image,
|
||||
ImageFile,
|
||||
ImageSequence,
|
||||
JpegImagePlugin,
|
||||
TiffImagePlugin,
|
||||
)
|
||||
from ._binary import i16be as i16
|
||||
from ._binary import o32le
|
||||
|
||||
|
||||
|
@ -109,7 +106,6 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
|
|||
self._after_jpeg_open()
|
||||
|
||||
def _after_jpeg_open(self, mpheader=None):
|
||||
self._initial_size = self.size
|
||||
self.mpinfo = mpheader if mpheader is not None else self._getmp()
|
||||
self.n_frames = self.mpinfo[0xB001]
|
||||
self.__mpoffsets = [
|
||||
|
@ -137,27 +133,20 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
|
|||
self.fp = self._fp
|
||||
self.offset = self.__mpoffsets[frame]
|
||||
|
||||
original_exif = self.info.get("exif")
|
||||
if "exif" in self.info:
|
||||
del self.info["exif"]
|
||||
|
||||
self.fp.seek(self.offset + 2) # skip SOI marker
|
||||
segment = self.fp.read(2)
|
||||
if not segment:
|
||||
if not self.fp.read(2):
|
||||
msg = "No data found for frame"
|
||||
raise ValueError(msg)
|
||||
self._size = self._initial_size
|
||||
if i16(segment) == 0xFFE1: # APP1
|
||||
n = i16(self.fp.read(2)) - 2
|
||||
self.info["exif"] = ImageFile._safe_read(self.fp, n)
|
||||
self.fp.seek(self.offset)
|
||||
JpegImagePlugin.JpegImageFile._open(self)
|
||||
if self.info.get("exif") != original_exif:
|
||||
self._reload_exif()
|
||||
|
||||
mptype = self.mpinfo[0xB002][frame]["Attribute"]["MPType"]
|
||||
if mptype.startswith("Large Thumbnail"):
|
||||
exif = self.getexif().get_ifd(ExifTags.IFD.Exif)
|
||||
if 40962 in exif and 40963 in exif:
|
||||
self._size = (exif[40962], exif[40963])
|
||||
elif "exif" in self.info:
|
||||
del self.info["exif"]
|
||||
self._reload_exif()
|
||||
|
||||
self.tile = [("jpeg", (0, 0) + self.size, self.offset, (self.mode, ""))]
|
||||
self.tile = [("jpeg", (0, 0) + self.size, self.offset, self.tile[0][-1])]
|
||||
self.__frame = frame
|
||||
|
||||
def tell(self):
|
||||
|
|
|
@ -8,7 +8,7 @@ import os
|
|||
import re
|
||||
import time
|
||||
import zlib
|
||||
from typing import TYPE_CHECKING, Any, List, Union
|
||||
from typing import TYPE_CHECKING, Any, List, NamedTuple, Union
|
||||
|
||||
|
||||
# see 7.9.2.2 Text String Type on page 86 and D.3 PDFDocEncoding Character Set
|
||||
|
@ -81,9 +81,12 @@ def check_format_condition(condition, error_message):
|
|||
raise PdfFormatError(error_message)
|
||||
|
||||
|
||||
class IndirectReference(
|
||||
collections.namedtuple("IndirectReferenceTuple", ["object_id", "generation"])
|
||||
):
|
||||
class IndirectReferenceTuple(NamedTuple):
|
||||
object_id: int
|
||||
generation: int
|
||||
|
||||
|
||||
class IndirectReference(IndirectReferenceTuple):
|
||||
def __str__(self):
|
||||
return f"{self.object_id} {self.generation} R"
|
||||
|
||||
|
|
|
@ -270,6 +270,9 @@ class PpmPlainDecoder(ImageFile.PyDecoder):
|
|||
msg = b"Token too long found in data: %s" % token[: max_len + 1]
|
||||
raise ValueError(msg)
|
||||
value = int(token)
|
||||
if value < 0:
|
||||
msg_str = f"Channel value is negative: {value}"
|
||||
raise ValueError(msg_str)
|
||||
if value > maxval:
|
||||
msg_str = f"Channel value too large for this mode: {value}"
|
||||
raise ValueError(msg_str)
|
||||
|
|
|
@ -74,6 +74,7 @@ MM = b"MM" # big-endian (Motorola style)
|
|||
# Read TIFF files
|
||||
|
||||
# a few tag names, just to make the code below a bit more readable
|
||||
OSUBFILETYPE = 255
|
||||
IMAGEWIDTH = 256
|
||||
IMAGELENGTH = 257
|
||||
BITSPERSAMPLE = 258
|
||||
|
@ -1784,11 +1785,13 @@ def _save(im, fp, filename):
|
|||
types = {}
|
||||
# STRIPOFFSETS and STRIPBYTECOUNTS are added by the library
|
||||
# based on the data in the strip.
|
||||
# OSUBFILETYPE is deprecated.
|
||||
# The other tags expect arrays with a certain length (fixed or depending on
|
||||
# BITSPERSAMPLE, etc), passing arrays with a different length will result in
|
||||
# segfaults. Block these tags until we add extra validation.
|
||||
# SUBIFD may also cause a segfault.
|
||||
blocklist += [
|
||||
OSUBFILETYPE,
|
||||
REFERENCEBLACKWHITE,
|
||||
STRIPBYTECOUNTS,
|
||||
STRIPOFFSETS,
|
||||
|
|
|
@ -18,10 +18,18 @@
|
|||
##
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import namedtuple
|
||||
from typing import NamedTuple
|
||||
|
||||
|
||||
class TagInfo(namedtuple("_TagInfo", "value name type length enum")):
|
||||
class _TagInfo(NamedTuple):
|
||||
value: int | None
|
||||
name: str
|
||||
type: int | None
|
||||
length: int | None
|
||||
enum: dict[str, int]
|
||||
|
||||
|
||||
class TagInfo(_TagInfo):
|
||||
__slots__: list[str] = []
|
||||
|
||||
def __new__(cls, value=None, name="unknown", type=None, length=None, enum=None):
|
||||
|
|
|
@ -217,6 +217,7 @@ def _save_all(im, fp, filename):
|
|||
verbose = False
|
||||
lossless = im.encoderinfo.get("lossless", False)
|
||||
quality = im.encoderinfo.get("quality", 80)
|
||||
alpha_quality = im.encoderinfo.get("alpha_quality", 100)
|
||||
method = im.encoderinfo.get("method", 0)
|
||||
icc_profile = im.encoderinfo.get("icc_profile") or ""
|
||||
exif = im.encoderinfo.get("exif", "")
|
||||
|
@ -296,6 +297,7 @@ def _save_all(im, fp, filename):
|
|||
rawmode,
|
||||
lossless,
|
||||
quality,
|
||||
alpha_quality,
|
||||
method,
|
||||
)
|
||||
|
||||
|
@ -310,7 +312,7 @@ def _save_all(im, fp, filename):
|
|||
im.seek(cur_idx)
|
||||
|
||||
# Force encoder to flush frames
|
||||
enc.add(None, round(timestamp), 0, 0, "", lossless, quality, 0)
|
||||
enc.add(None, round(timestamp), 0, 0, "", lossless, quality, alpha_quality, 0)
|
||||
|
||||
# Get the final output from the encoder
|
||||
data = enc.assemble(icc_profile, exif, xmp)
|
||||
|
@ -324,6 +326,7 @@ def _save_all(im, fp, filename):
|
|||
def _save(im, fp, filename):
|
||||
lossless = im.encoderinfo.get("lossless", False)
|
||||
quality = im.encoderinfo.get("quality", 80)
|
||||
alpha_quality = im.encoderinfo.get("alpha_quality", 100)
|
||||
icc_profile = im.encoderinfo.get("icc_profile") or ""
|
||||
exif = im.encoderinfo.get("exif", b"")
|
||||
if isinstance(exif, Image.Exif):
|
||||
|
@ -343,6 +346,7 @@ def _save(im, fp, filename):
|
|||
im.size[1],
|
||||
lossless,
|
||||
float(quality),
|
||||
float(alpha_quality),
|
||||
im.mode,
|
||||
icc_profile,
|
||||
method,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""Pillow (Fork of the Python Imaging Library)
|
||||
|
||||
Pillow is the friendly PIL fork by Jeffrey A. Clark (Alex) and contributors.
|
||||
Pillow is the friendly PIL fork by Jeffrey A. Clark and contributors.
|
||||
https://github.com/python-pillow/Pillow/
|
||||
|
||||
Pillow is forked from PIL 1.1.7.
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
def __getattr__(name: str) -> Any: ...
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
def __getattr__(name: str) -> Any: ...
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
def __getattr__(name: str) -> Any: ...
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
def __getattr__(name: str) -> Any: ...
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user