Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions recipes/pillow/meta.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package:
name: Pillow
version: "12.2.0"
version: "12.3.0"

requirements:
# PNG support is internal: libpng is not used.
#
# All three are linked STATICALLY into the extensions on iOS and dynamically on
# All four are linked STATICALLY into the extensions on iOS and dynamically on
# Android, so where they belong differs by platform. Under `host` they become a
# runtime Requires-Dist and every consuming app installs the wheel; on iOS that
# is ~16 MB of .a already folded into _imaging.so / _webp.so and unloadable at
Expand All @@ -17,11 +17,13 @@ requirements:
- flet-libjpeg 3.0.90
- flet-libfreetype 2.13.3
- flet-libwebp 1.6.0
- flet-libtiff 4.7.0
# {% else %}
host_build:
- flet-libjpeg 3.0.90
- flet-libfreetype 2.13.3
- flet-libwebp 1.6.0
- flet-libtiff 4.7.0
# {% endif %}

# {% if not version or version >= (12,0,0) %}
Expand All @@ -41,7 +43,7 @@ patches:
# {% endif %}

build:
number: 2
number: 1
script_env:
# {% if sdk == 'android' %}
# pillow's setup.py manually probes `self.compiler.{include,library}_dirs`
Expand Down
40 changes: 40 additions & 0 deletions recipes/pillow/tests/test_pillow.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,43 @@ def test_webp_animation_encode():
for i, want in enumerate([(255, 0, 0), (0, 255, 0), (0, 0, 255)]):
rt.seek(i)
assert rt.convert("RGB").getpixel((4, 4)) == want


def test_libtiff_available():
"""libtiff is linked: Pillow lists it as a codec."""
from PIL import features

assert features.check("libtiff") is True
assert "libtiff" in features.get_supported_codecs()


def test_tiff_jpeg_roundtrip():
"""Write and decode JPEG-compressed TIFFs (compression 7), RGB and RGBA."""
from PIL import Image

for mode, colour in (("RGB", (200, 40, 40)), ("RGBA", (40, 200, 40, 128))):
src = Image.new(mode, (64, 48), colour)
out = io.BytesIO()
src.save(out, "TIFF", compression="jpeg")

rt = Image.open(io.BytesIO(out.getvalue()))
assert rt.tag_v2[259] == 7, f"{mode}: compression tag {rt.tag_v2[259]}"
rt.load() # where a build without libtiff raises "decoder libtiff not available"
assert rt.mode == mode
got = rt.getpixel((32, 24))
assert all(abs(g - w) <= 8 for g, w in zip(got, colour)), f"{mode}: {got}"


def test_tiff_lossless_compressions_roundtrip():
"""LZW, deflate and PackBits TIFFs round-trip exactly."""
from PIL import Image

src = Image.new("RGB", (16, 16))
src.putdata([(x * 16, y * 16, 0) for y in range(16) for x in range(16)])

for compression in ("tiff_lzw", "tiff_adobe_deflate", "packbits"):
out = io.BytesIO()
src.save(out, "TIFF", compression=compression)
rt = Image.open(io.BytesIO(out.getvalue()))
assert rt.info["compression"] == compression
assert rt.tobytes() == src.tobytes(), compression
Loading