Skip to content

Commit ee5c134

Browse files
authored
Merge branch 'master' into dpi_fix
2 parents d46f81a + 310d2c9 commit ee5c134

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1080
-263
lines changed

.appveyor.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ environment:
3030
PIP_DIR: bin
3131
TEST_OPTIONS: --processes=0
3232
DEPLOY: NO
33+
- PYTHON: C:/vp/pypy3
34+
EXECUTABLE: bin/pypy.exe
35+
PIP_DIR: bin
36+
VENV: YES
3337

3438

3539
install:
@@ -43,7 +47,12 @@ install:
4347
- ps: |
4448
if ($env:PYTHON -eq "c:/vp/pypy2")
4549
{
46-
c:\pillow\winbuild\appveyor_install_pypy.cmd
50+
c:\pillow\winbuild\appveyor_install_pypy2.cmd
51+
}
52+
- ps: |
53+
if ($env:PYTHON -eq "c:/vp/pypy3")
54+
{
55+
c:\pillow\winbuild\appveyor_install_pypy3.cmd
4756
}
4857
- ps: |
4958
if ($env:PYTHON -eq "c:/msys64/mingw32")

.github/workflows/lint.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Lint
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
8+
runs-on: ubuntu-latest
9+
strategy:
10+
matrix:
11+
python: [3.7]
12+
13+
name: Python ${{ matrix.python }}
14+
15+
steps:
16+
- uses: actions/checkout@v1
17+
18+
- name: Set up Python ${{ matrix.python }}
19+
uses: actions/setup-python@v1
20+
with:
21+
python-version: ${{ matrix.python }}
22+
23+
- name: Install dependencies
24+
run: |
25+
python -m pip install --upgrade pip
26+
python -m pip install --upgrade tox
27+
28+
- name: Lint
29+
run: tox -e lint

CHANGES.rst

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,54 @@ Changelog (Pillow)
77

88
- This is the last Pillow release to support Python 2.7 #3642
99

10-
- Depends: Update libwebp to 1.0.3 #3983
10+
- Changed WindowsViewer format to PNG #4080
11+
[radarhere]
12+
13+
- Use TIFF orientation #4063
14+
[radarhere]
15+
16+
- Raise the same error if a truncated image is loaded a second time #3965
17+
[radarhere]
18+
19+
- Lazily use ImageFileDirectory_v1 values from Exif #4031
20+
[radarhere]
21+
22+
- Improved HSV conversion #4004
23+
[radarhere]
24+
25+
- Added text stroking #3978
26+
[radarhere, hugovk]
27+
28+
- No more deprecated bdist_wininst .exe installers #4029
29+
[hugovk]
30+
31+
- Do not allow floodfill to extend into negative coordinates #4017
32+
[radarhere]
33+
34+
- Fixed arc drawing bug for a non-whole number of degrees #4014
35+
[radarhere]
36+
37+
- Fix bug when merging identical images to GIF with a list of durations #4003
38+
[djy0, radarhere]
39+
40+
- Fix bug in TIFF loading of BufferedReader #3998
41+
[chadawagner]
42+
43+
- Added fallback for finding ld on MinGW Cygwin #4019
44+
[radarhere]
45+
46+
- Remove indirect dependencies from requirements.txt #3976
47+
[hugovk]
48+
49+
- Depends: Update libwebp to 1.0.3 #3983, libimagequant to 2.12.5 #3993, freetype to 2.10.1 #3991
1150
[radarhere]
1251

1352
- Change overflow check to use PY_SSIZE_T_MAX #3964
1453
[radarhere]
1554

55+
- Report reason for pytest skips #3942
56+
[hugovk]
57+
1658
6.1.0 (2019-07-01)
1759
------------------
1860

@@ -55,7 +97,7 @@ Changelog (Pillow)
5597
- Updated TIFF tile descriptors to match current decoding functionality #3795
5698
[dmnisson]
5799

58-
- Added an `image.entropy()` method (second revision) #3608
100+
- Added an ``image.entropy()`` method (second revision) #3608
59101
[fish2000]
60102

61103
- Pass the correct types to PyArg_ParseTuple #3880
@@ -691,7 +733,7 @@ Changelog (Pillow)
691733
- Enable background colour parameter on rotate #3057
692734
[storesource]
693735

694-
- Remove unnecessary `#if 1` directive #3072
736+
- Remove unnecessary ``#if 1`` directive #3072
695737
[jdufresne]
696738

697739
- Remove unused Python class, Path #3070
@@ -1228,7 +1270,7 @@ Changelog (Pillow)
12281270
- Add decompression bomb check to Image.crop #2410
12291271
[wiredfool]
12301272

1231-
- ImageFile: Ensure that the `err_code` variable is initialized in case of exception. #2363
1273+
- ImageFile: Ensure that the ``err_code`` variable is initialized in case of exception. #2363
12321274
[alexkiro]
12331275

12341276
- Tiff: Support append_images for saving multipage TIFFs #2406
@@ -1465,7 +1507,7 @@ Changelog (Pillow)
14651507
- Removed PIL 1.0 era TK readme that concerns Windows 95/NT #2360
14661508
[wiredfool]
14671509

1468-
- Prevent `nose -v` printing docstrings #2369
1510+
- Prevent ``nose -v`` printing docstrings #2369
14691511
[hugovk]
14701512

14711513
- Replaced absolute PIL imports with relative imports #2349
@@ -1910,7 +1952,7 @@ Changelog (Pillow)
19101952
- Changed depends/install_*.sh urls to point to github pillow-depends repo #1983
19111953
[wiredfool]
19121954

1913-
- Allow ICC profile from `encoderinfo` while saving PNGs #1909
1955+
- Allow ICC profile from ``encoderinfo`` while saving PNGs #1909
19141956
[homm]
19151957

19161958
- Fix integer overflow on ILP32 systems (32-bit Linux). #1975
@@ -2353,7 +2395,7 @@ Changelog (Pillow)
23532395
- Added PDF multipage saving #1445
23542396
[radarhere]
23552397

2356-
- Removed deprecated code, Image.tostring, Image.fromstring, Image.offset, ImageDraw.setink, ImageDraw.setfill, ImageFileIO, ImageFont.FreeTypeFont and ImageFont.truetype `file` kwarg, ImagePalette private _make functions, ImageWin.fromstring and ImageWin.tostring #1343
2398+
- Removed deprecated code, Image.tostring, Image.fromstring, Image.offset, ImageDraw.setink, ImageDraw.setfill, ImageFileIO, ImageFont.FreeTypeFont and ImageFont.truetype ``file`` kwarg, ImagePalette private _make functions, ImageWin.fromstring and ImageWin.tostring #1343
23572399
[radarhere]
23582400

23592401
- Load more broken images #1428
@@ -2845,7 +2887,7 @@ Changelog (Pillow)
28452887
- Doc cleanup
28462888
[wiredfool]
28472889

2848-
- Fix `ImageStat` docs #796
2890+
- Fix ``ImageStat`` docs #796
28492891
[akx]
28502892

28512893
- Added docs for ExifTags #794
@@ -3282,7 +3324,7 @@ Changelog (Pillow)
32823324
- Add RGBA support to ImageColor #309
32833325
[yoavweiss]
32843326

3285-
- Test for `str`, not `"utf-8"` #306 (fixes #304)
3327+
- Test for ``str``, not ``"utf-8"`` #306 (fixes #304)
32863328
[mjpieters]
32873329

32883330
- Fix missing import os in _util.py #303
@@ -3388,7 +3430,7 @@ Changelog (Pillow)
33883430

33893431
- Partial work to add a wrapper for WebPGetFeatures to correctly support #220 (fixes #204)
33903432

3391-
- Significant performance improvement of `alpha_composite` function #156
3433+
- Significant performance improvement of ``alpha_composite`` function #156
33923434
[homm]
33933435

33943436
- Support explicitly disabling features via --disable-* options #240

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ To report a security vulnerability, please follow the procedure described in the
6767
.. |zenodo| image:: https://zenodo.org/badge/17549/python-pillow/Pillow.svg
6868
:target: https://zenodo.org/badge/latestdoi/17549/python-pillow/Pillow
6969

70-
.. |tidelift| image:: https://tidelift.com/badges/github/python-pillow/Pillow?style=flat
70+
.. |tidelift| image:: https://tidelift.com/badges/package/pypi/Pillow?style=flat
7171
:target: https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=referral&utm_campaign=readme
7272

7373
.. |version| image:: https://img.shields.io/pypi/v/pillow.svg

Tests/README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Pillow Tests
44
Test scripts are named ``test_xxx.py`` and use the ``unittest`` module. A base class and helper functions can be found in ``helper.py``.
55

66
Dependencies
7-
-----------
7+
------------
88

99
Install::
1010

Tests/helper.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,12 @@ def on_appveyor():
355355
return "APPVEYOR" in os.environ
356356

357357

358+
def on_ci():
359+
# Travis and AppVeyor have "CI"
360+
# Azure Pipelines has "TF_BUILD"
361+
return "CI" in os.environ or "TF_BUILD" in os.environ
362+
363+
358364
if sys.platform == "win32":
359365
IMCONVERT = os.environ.get("MAGICK_HOME", "")
360366
if IMCONVERT:

Tests/images/g4_orientation_1.tif

708 Bytes
Binary file not shown.

Tests/images/g4_orientation_2.tif

930 Bytes
Binary file not shown.

Tests/images/g4_orientation_3.tif

926 Bytes
Binary file not shown.

Tests/images/g4_orientation_4.tif

928 Bytes
Binary file not shown.

Tests/images/g4_orientation_5.tif

1 KB
Binary file not shown.

Tests/images/g4_orientation_6.tif

1 KB
Binary file not shown.

Tests/images/g4_orientation_7.tif

1022 Bytes
Binary file not shown.

Tests/images/g4_orientation_8.tif

1 KB
Binary file not shown.
Loading
214 Bytes
Loading
2.21 KB
Loading
3.97 KB
Loading
1.3 KB
Loading
3.66 KB
Loading

Tests/test_file_gif.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,26 @@ def test_identical_frames(self):
495495
# Assert that the new duration is the total of the identical frames
496496
self.assertEqual(reread.info["duration"], 4500)
497497

498+
def test_identical_frames_to_single_frame(self):
499+
for duration in ([1000, 1500, 2000, 4000], (1000, 1500, 2000, 4000), 8500):
500+
out = self.tempfile("temp.gif")
501+
im_list = [
502+
Image.new("L", (100, 100), "#000"),
503+
Image.new("L", (100, 100), "#000"),
504+
Image.new("L", (100, 100), "#000"),
505+
]
506+
507+
im_list[0].save(
508+
out, save_all=True, append_images=im_list[1:], duration=duration
509+
)
510+
reread = Image.open(out)
511+
512+
# Assert that all frames were combined
513+
self.assertEqual(reread.n_frames, 1)
514+
515+
# Assert that the new duration is the total of the identical frames
516+
self.assertEqual(reread.info["duration"], 8500)
517+
498518
def test_number_of_loops(self):
499519
number_of_loops = 2
500520

Tests/test_file_jpeg.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,10 @@ def test_truncated_jpeg_throws_IOError(self):
369369
with self.assertRaises(IOError):
370370
im.load()
371371

372+
# Test that the error is raised if loaded a second time
373+
with self.assertRaises(IOError):
374+
im.load()
375+
372376
def _n_qtables_helper(self, n, test_file):
373377
im = Image.open(test_file)
374378
f = self.tempfile("temp.jpg")

Tests/test_file_jpeg2k.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ def test_tiled_offset_rt(self):
9191
)
9292
self.assert_image_equal(im, test_card)
9393

94+
def test_tiled_offset_too_small(self):
95+
with self.assertRaises(ValueError):
96+
self.roundtrip(
97+
test_card, tile_size=(128, 128), tile_offset=(0, 0), offset=(128, 32)
98+
)
99+
94100
def test_irreversible_rt(self):
95101
im = self.roundtrip(test_card, irreversible=True, quality_layers=[20])
96102
self.assert_image_similar(im, test_card, 2.0)

Tests/test_file_libtiff.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,19 @@ def test_g4_tiff_bytesio(self):
8181
self.assertEqual(im.size, (500, 500))
8282
self._assert_noerr(im)
8383

84+
def test_g4_non_disk_file_object(self):
85+
"""Testing loading from non-disk non-BytesIO file object"""
86+
test_file = "Tests/images/hopper_g4_500.tif"
87+
s = io.BytesIO()
88+
with open(test_file, "rb") as f:
89+
s.write(f.read())
90+
s.seek(0)
91+
r = io.BufferedReader(s)
92+
im = Image.open(r)
93+
94+
self.assertEqual(im.size, (500, 500))
95+
self._assert_noerr(im)
96+
8497
def test_g4_eq_png(self):
8598
""" Checking that we're actually getting the data that we expect"""
8699
png = Image.open("Tests/images/hopper_bw_500.png")
@@ -818,3 +831,12 @@ def test_old_style_jpeg(self):
818831
self.assert_image_equal_tofile(
819832
im, "Tests/images/old-style-jpeg-compression.png"
820833
)
834+
835+
def test_orientation(self):
836+
base_im = Image.open("Tests/images/g4_orientation_1.tif")
837+
838+
for i in range(2, 9):
839+
im = Image.open("Tests/images/g4_orientation_" + str(i) + ".tif")
840+
im.load()
841+
842+
self.assert_image_similar(base_im, im, 0.7)

Tests/test_file_tiff_metadata.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def test_exif_div_zero(self):
222222
self.assertEqual(0, reloaded.tag_v2[41988].numerator)
223223
self.assertEqual(0, reloaded.tag_v2[41988].denominator)
224224

225-
def test_expty_values(self):
225+
def test_empty_values(self):
226226
data = io.BytesIO(
227227
b"II*\x00\x08\x00\x00\x00\x03\x00\x1a\x01\x05\x00\x00\x00\x00\x00"
228228
b"\x00\x00\x00\x00\x1b\x01\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00"
@@ -239,11 +239,13 @@ def test_expty_values(self):
239239
def test_PhotoshopInfo(self):
240240
im = Image.open("Tests/images/issue_2278.tif")
241241

242-
self.assertIsInstance(im.tag_v2[34377], bytes)
242+
self.assertEqual(len(im.tag_v2[34377]), 1)
243+
self.assertIsInstance(im.tag_v2[34377][0], bytes)
243244
out = self.tempfile("temp.tiff")
244245
im.save(out)
245246
reloaded = Image.open(out)
246-
self.assertIsInstance(reloaded.tag_v2[34377], bytes)
247+
self.assertEqual(len(reloaded.tag_v2[34377]), 1)
248+
self.assertIsInstance(reloaded.tag_v2[34377][0], bytes)
247249

248250
def test_too_many_entries(self):
249251
ifd = TiffImagePlugin.ImageFileDirectory_v2()

Tests/test_image_convert.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def convert(im, mode):
2323
"RGBX",
2424
"CMYK",
2525
"YCbCr",
26+
"HSV",
2627
)
2728

2829
for mode in modes:

0 commit comments

Comments
 (0)