Skip to content

Commit

Permalink
Merge branch 'main' into png_iccp
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Feb 29, 2024
2 parents 383ac4f + bebf038 commit b80b30d
Show file tree
Hide file tree
Showing 23 changed files with 121 additions and 45 deletions.
1 change: 1 addition & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ init:
# Uncomment previous line to get RDP access during the build.

environment:
COVERAGE_CORE: sysmon
EXECUTABLE: python.exe
TEST_OPTIONS:
DEPLOY: YES
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/test-cygwin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
COVERAGE_CORE: sysmon

jobs:
build:
runs-on: windows-latest
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/test-mingw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
COVERAGE_CORE: sysmon

jobs:
build:
runs-on: windows-latest
Expand Down
15 changes: 13 additions & 2 deletions .github/workflows/test-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
COVERAGE_CORE: sysmon

jobs:
build:
runs-on: windows-latest
Expand Down Expand Up @@ -66,8 +69,16 @@ jobs:
- name: Print build system information
run: python3 .github/workflows/system-info.py

- name: python3 -m pip install pytest pytest-cov pytest-timeout defusedxml olefile pyroma
run: python3 -m pip install pytest pytest-cov pytest-timeout defusedxml olefile pyroma
- name: Install Python dependencies
run: >
python3 -m pip install
coverage>=7.4.2
defusedxml
olefile
pyroma
pytest
pytest-cov
pytest-timeout
- name: Install dependencies
id: install
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ concurrency:
cancel-in-progress: true

env:
COVERAGE_CORE: sysmon
FORCE_COLOR: 1

jobs:
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/wheels-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ FREETYPE_VERSION=2.13.2
HARFBUZZ_VERSION=8.3.0
LIBPNG_VERSION=1.6.40
JPEGTURBO_VERSION=3.0.1
OPENJPEG_VERSION=2.5.0
OPENJPEG_VERSION=2.5.2
XZ_VERSION=5.4.5
TIFF_VERSION=4.6.0
LCMS2_VERSION=2.16
Expand All @@ -40,7 +40,7 @@ BROTLI_VERSION=1.1.0

if [[ -n "$IS_MACOS" ]] && [[ "$CIBW_ARCHS" == "x86_64" ]]; then
function build_openjpeg {
local out_dir=$(fetch_unpack https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz openjpeg-2.5.0.tar.gz)
local out_dir=$(fetch_unpack https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz openjpeg-${OPENJPEG_VERSION}.tar.gz)
(cd $out_dir \
&& cmake -DCMAKE_INSTALL_PREFIX=$BUILD_PREFIX -DCMAKE_INSTALL_NAME_DIR=$BUILD_PREFIX/lib . \
&& make install)
Expand Down Expand Up @@ -93,6 +93,9 @@ function build {
done
fi
build_openjpeg
if [ -f /usr/local/lib64/libopenjp2.so ]; then
cp /usr/local/lib64/libopenjp2.so /usr/local/lib
fi

ORIGINAL_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -O3 -DNDEBUG"
Expand Down
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ Changelog (Pillow)
10.3.0 (unreleased)
-------------------

- Release GIL while calling ``WebPAnimDecoderGetNext`` #7782
[evanmiller, radarhere]

- Fixed reading FLI/FLC images with a prefix chunk #7804
[twolife]

- Update wl-paste handling and return None for some errors in grabclipboard() on Linux #7745
[nik012003, radarhere]

Expand Down
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ As of 2019, Pillow development is
<a href="https://gitter.im/python-pillow/Pillow?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img
alt="Join the chat at https://gitter.im/python-pillow/Pillow"
src="https://badges.gitter.im/python-pillow/Pillow.svg"></a>
<a href="https://twitter.com/PythonPillow"><img
alt="Follow on https://twitter.com/PythonPillow"
src="https://img.shields.io/badge/tweet-on%20Twitter-00aced.svg"></a>
<a href="https://fosstodon.org/@pillow"><img
alt="Follow on https://fosstodon.org/@pillow"
src="https://img.shields.io/badge/publish-on%20Mastodon-595aff.svg"
Expand Down
2 changes: 1 addition & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Released as needed privately to individual vendors for critical security-related

## Publicize Release

* [ ] Announce release availability via [Twitter](https://twitter.com/pythonpillow) and [Mastodon](https://fosstodon.org/@pillow) e.g. https://twitter.com/PythonPillow/status/1013789184354603010
* [ ] Announce release availability via [Mastodon](https://fosstodon.org/@pillow) e.g. https://fosstodon.org/@pillow/110639450470725321

## Documentation

Expand Down
Binary file added Tests/images/2422.flc
Binary file not shown.
25 changes: 23 additions & 2 deletions Tests/test_file_fli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@

import pytest

from PIL import FliImagePlugin, Image
from PIL import FliImagePlugin, Image, ImageFile

from .helper import assert_image_equal, assert_image_equal_tofile, is_pypy

# created as an export of a palette image from Gimp2.6
# save as...-> hopper.fli, default options.
static_test_file = "Tests/images/hopper.fli"

# From https://samples.libav.org/fli-flc/
# From https://samples.ffmpeg.org/fli-flc/
animated_test_file = "Tests/images/a.fli"

# From https://samples.ffmpeg.org/fli-flc/
animated_test_file_with_prefix_chunk = "Tests/images/2422.flc"


def test_sanity() -> None:
with Image.open(static_test_file) as im:
Expand All @@ -32,6 +35,24 @@ def test_sanity() -> None:
assert im.is_animated


def test_prefix_chunk() -> None:
ImageFile.LOAD_TRUNCATED_IMAGES = True
try:
with Image.open(animated_test_file_with_prefix_chunk) as im:
assert im.mode == "P"
assert im.size == (320, 200)
assert im.format == "FLI"
assert im.info["duration"] == 171
assert im.is_animated

palette = im.getpalette()
assert palette[3:6] == [255, 255, 255]
assert palette[381:384] == [204, 204, 12]
assert palette[765:] == [252, 0, 0]
finally:
ImageFile.LOAD_TRUNCATED_IMAGES = False


@pytest.mark.skipif(is_pypy(), reason="Requires CPython")
def test_unclosed_file() -> None:
def open() -> None:
Expand Down
15 changes: 9 additions & 6 deletions Tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,15 +685,18 @@ def _make_new(
_make_new(im, blank_p, ImagePalette.ImagePalette())
_make_new(im, blank_pa, ImagePalette.ImagePalette())

def test_p_from_rgb_rgba(self) -> None:
for mode, color in [
@pytest.mark.parametrize(
"mode, color",
(
("RGB", "#DDEEFF"),
("RGB", (221, 238, 255)),
("RGBA", (221, 238, 255, 255)),
]:
im = Image.new("P", (100, 100), color)
expected = Image.new(mode, (100, 100), color)
assert_image_equal(im.convert(mode), expected)
),
)
def test_p_from_rgb_rgba(self, mode: str, color: str | tuple[int, ...]) -> None:
im = Image.new("P", (100, 100), color)
expected = Image.new(mode, (100, 100), color)
assert_image_equal(im.convert(mode), expected)

def test_no_resource_warning_on_save(self, tmp_path: Path) -> None:
# https://github.com/python-pillow/Pillow/issues/835
Expand Down
2 changes: 1 addition & 1 deletion depends/install_openjpeg.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash
# install openjpeg

archive=openjpeg-2.5.0
archive=openjpeg-2.5.2

./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/main/$archive.tar.gz

Expand Down
24 changes: 24 additions & 0 deletions docs/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,27 @@ PIL.OleFileIO
the upstream :pypi:`olefile` Python package, and replaced with an :py:exc:`ImportError` in 5.0.0
(2018-01). The deprecated file has now been removed from Pillow. If needed, install from
PyPI (eg. ``python3 -m pip install olefile``).

import _imaging
~~~~~~~~~~~~~~~

.. versionremoved:: 2.1.0

Pillow >= 2.1.0 no longer supports ``import _imaging``.
Please use ``from PIL.Image import core as _imaging`` instead.

Pillow and PIL
~~~~~~~~~~~~~~

.. versionremoved:: 1.0.0

Pillow and PIL cannot co-exist in the same environment.
Before installing Pillow, please uninstall PIL.

import Image
~~~~~~~~~~~~

.. versionremoved:: 1.0.0

Pillow >= 1.0 no longer supports ``import Image``.
Please use ``from PIL import Image`` instead.
4 changes: 0 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,6 @@ Pillow for enterprise is available via the Tidelift Subscription. `Learn more <h
:target: https://gitter.im/python-pillow/Pillow?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
:alt: Join the chat at https://gitter.im/python-pillow/Pillow

.. image:: https://img.shields.io/badge/tweet-on%20Twitter-00aced.svg
:target: https://twitter.com/PythonPillow
:alt: Follow on https://twitter.com/PythonPillow

.. image:: https://img.shields.io/badge/publish-on%20Mastodon-595aff.svg
:target: https://fosstodon.org/@pillow
:alt: Follow on https://fosstodon.org/@pillow
Expand Down
11 changes: 1 addition & 10 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@ Installation
});
</script>

Warnings
--------

.. warning:: Pillow and PIL cannot co-exist in the same environment. Before installing Pillow, please uninstall PIL.

.. warning:: Pillow >= 1.0 no longer supports ``import Image``. Please use ``from PIL import Image`` instead.

.. warning:: Pillow >= 2.1.0 no longer supports ``import _imaging``. Please use ``from PIL.Image import core as _imaging`` instead.

Python Support
--------------

Expand Down Expand Up @@ -186,7 +177,7 @@ Many of Pillow's features require external libraries:
* **openjpeg** provides JPEG 2000 functionality.

* Pillow has been tested with openjpeg **2.0.0**, **2.1.0**, **2.3.1**,
**2.4.0** and **2.5.0**.
**2.4.0**, **2.5.0** and **2.5.2**.
* Pillow does **not** support the earlier **1.5** series which ships
with Debian Jessie.

Expand Down
2 changes: 2 additions & 0 deletions docs/reference/ImageOps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ only work on L and RGB images.
.. autofunction:: colorize
.. autofunction:: crop
.. autofunction:: scale
.. autoclass:: SupportsGetMesh
:show-inheritance:
.. autofunction:: deform
.. autofunction:: equalize
.. autofunction:: expand
Expand Down
6 changes: 6 additions & 0 deletions docs/releasenotes/10.3.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,9 @@ Portable FloatMap (PFM) images

Support has been added for reading and writing grayscale (Pf format)
Portable FloatMap (PFM) files containing ``F`` data.

Release GIL when fetching WebP frames
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Python's Global Interpreter Lock is now released when fetching WebP frames from
the libwebp decoder.
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ Homepage = "https://python-pillow.org"
Mastodon = "https://fosstodon.org/@pillow"
"Release notes" = "https://pillow.readthedocs.io/en/stable/releasenotes/index.html"
Source = "https://github.com/python-pillow/Pillow"
Twitter = "https://twitter.com/PythonPillow"

[tool.setuptools]
packages = ["PIL"]
Expand Down
1 change: 1 addition & 0 deletions src/PIL/FliImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def _open(self):
if i16(s, 4) == 0xF100:
# prefix chunk; ignore it
self.__offset = self.__offset + i32(s)
self.fp.seek(self.__offset)
s = self.fp.read(16)

if i16(s, 4) == 0xF1FA:
Expand Down
12 changes: 10 additions & 2 deletions src/PIL/ImageOps.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,15 @@ def scale(
return image.resize(size, resample)


class _SupportsGetMesh(Protocol):
class SupportsGetMesh(Protocol):
"""
An object that supports the ``getmesh`` method, taking an image as an
argument, and returning a list of tuples. Each tuple contains two tuples,
the source box as a tuple of 4 integers, and a tuple of 8 integers for the
final quadrilateral, in order of top left, bottom left, bottom right, top
right.
"""

def getmesh(
self, image: Image.Image
) -> list[
Expand All @@ -421,7 +429,7 @@ def getmesh(

def deform(
image: Image.Image,
deformer: _SupportsGetMesh,
deformer: SupportsGetMesh,
resample: int = Image.Resampling.BILINEAR,
) -> Image.Image:
"""
Expand Down
7 changes: 6 additions & 1 deletion src/_webp.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,11 +448,16 @@ PyObject *
_anim_decoder_get_next(PyObject *self) {
uint8_t *buf;
int timestamp;
int ok;
PyObject *bytes;
PyObject *ret;
ImagingSectionCookie cookie;
WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;

if (!WebPAnimDecoderGetNext(decp->dec, &buf, &timestamp)) {
ImagingSectionEnter(&cookie);
ok = WebPAnimDecoderGetNext(decp->dec, &buf, &timestamp);
ImagingSectionLeave(&cookie);
if (!ok) {
PyErr_SetString(PyExc_OSError, "failed to read next frame");
return NULL;
}
Expand Down
15 changes: 5 additions & 10 deletions winbuild/build_prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,21 +308,16 @@ def cmd_msbuild(
"libs": [r"Lib\MS\*.lib"],
},
"openjpeg": {
"url": "https://github.com/uclouvain/openjpeg/archive/v2.5.0.tar.gz",
"filename": "openjpeg-2.5.0.tar.gz",
"dir": "openjpeg-2.5.0",
"url": "https://github.com/uclouvain/openjpeg/archive/v2.5.2.tar.gz",
"filename": "openjpeg-2.5.2.tar.gz",
"dir": "openjpeg-2.5.2",
"license": "LICENSE",
"patch": {
r"src\lib\openjp2\ht_dec.c": {
"#ifdef OPJ_COMPILER_MSVC\n return (OPJ_UINT32)__popcnt(val);": "#if defined(OPJ_COMPILER_MSVC) && (defined(_M_IX86) || defined(_M_AMD64))\n return (OPJ_UINT32)__popcnt(val);", # noqa: E501
}
},
"build": [
*cmds_cmake(
"openjp2", "-DBUILD_CODEC:BOOL=OFF", "-DBUILD_SHARED_LIBS:BOOL=OFF"
),
cmd_mkdir(r"{inc_dir}\openjpeg-2.5.0"),
cmd_copy(r"src\lib\openjp2\*.h", r"{inc_dir}\openjpeg-2.5.0"),
cmd_mkdir(r"{inc_dir}\openjpeg-2.5.2"),
cmd_copy(r"src\lib\openjp2\*.h", r"{inc_dir}\openjpeg-2.5.2"),
],
"libs": [r"bin\*.lib"],
},
Expand Down

0 comments on commit b80b30d

Please sign in to comment.