mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-27 09:44:31 +03:00
Merge remote-tracking branch 'upstream/master' into exif-writing-fixes
# Conflicts: # Tests/test_file_tiff_metadata.py
This commit is contained in:
commit
06e34db10b
17
CHANGES.rst
17
CHANGES.rst
|
@ -7,12 +7,27 @@ Changelog (Pillow)
|
||||||
|
|
||||||
- This is the last Pillow release to support Python 2.7 #3642
|
- This is the last Pillow release to support Python 2.7 #3642
|
||||||
|
|
||||||
- Depends: Update libwebp to 1.0.3 #3983
|
- Fix bug when merging identical images to GIF with a list of durations #4003
|
||||||
|
[djy0, radarhere]
|
||||||
|
|
||||||
|
- Fix bug in TIFF loading of BufferedReader #3998
|
||||||
|
[chadawagner]
|
||||||
|
|
||||||
|
- Added fallback for finding ld on MinGW Cygwin #4019
|
||||||
|
[radarhere]
|
||||||
|
|
||||||
|
- Remove indirect dependencies from requirements.txt #3976
|
||||||
|
[hugovk]
|
||||||
|
|
||||||
|
- Depends: Update libwebp to 1.0.3 #3983, libimagequant to 2.12.5 #3993, freetype to 2.10.1 #3991
|
||||||
[radarhere]
|
[radarhere]
|
||||||
|
|
||||||
- Change overflow check to use PY_SSIZE_T_MAX #3964
|
- Change overflow check to use PY_SSIZE_T_MAX #3964
|
||||||
[radarhere]
|
[radarhere]
|
||||||
|
|
||||||
|
- Report reason for pytest skips #3942
|
||||||
|
[hugovk]
|
||||||
|
|
||||||
6.1.0 (2019-07-01)
|
6.1.0 (2019-07-01)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
|
@ -495,6 +495,26 @@ class TestFileGif(PillowTestCase):
|
||||||
# Assert that the new duration is the total of the identical frames
|
# Assert that the new duration is the total of the identical frames
|
||||||
self.assertEqual(reread.info["duration"], 4500)
|
self.assertEqual(reread.info["duration"], 4500)
|
||||||
|
|
||||||
|
def test_identical_frames_to_single_frame(self):
|
||||||
|
for duration in ([1000, 1500, 2000, 4000], (1000, 1500, 2000, 4000), 8500):
|
||||||
|
out = self.tempfile("temp.gif")
|
||||||
|
im_list = [
|
||||||
|
Image.new("L", (100, 100), "#000"),
|
||||||
|
Image.new("L", (100, 100), "#000"),
|
||||||
|
Image.new("L", (100, 100), "#000"),
|
||||||
|
]
|
||||||
|
|
||||||
|
im_list[0].save(
|
||||||
|
out, save_all=True, append_images=im_list[1:], duration=duration
|
||||||
|
)
|
||||||
|
reread = Image.open(out)
|
||||||
|
|
||||||
|
# Assert that all frames were combined
|
||||||
|
self.assertEqual(reread.n_frames, 1)
|
||||||
|
|
||||||
|
# Assert that the new duration is the total of the identical frames
|
||||||
|
self.assertEqual(reread.info["duration"], 8500)
|
||||||
|
|
||||||
def test_number_of_loops(self):
|
def test_number_of_loops(self):
|
||||||
number_of_loops = 2
|
number_of_loops = 2
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,19 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
self.assertEqual(im.size, (500, 500))
|
self.assertEqual(im.size, (500, 500))
|
||||||
self._assert_noerr(im)
|
self._assert_noerr(im)
|
||||||
|
|
||||||
|
def test_g4_non_disk_file_object(self):
|
||||||
|
"""Testing loading from non-disk non-BytesIO file object"""
|
||||||
|
test_file = "Tests/images/hopper_g4_500.tif"
|
||||||
|
s = io.BytesIO()
|
||||||
|
with open(test_file, "rb") as f:
|
||||||
|
s.write(f.read())
|
||||||
|
s.seek(0)
|
||||||
|
r = io.BufferedReader(s)
|
||||||
|
im = Image.open(r)
|
||||||
|
|
||||||
|
self.assertEqual(im.size, (500, 500))
|
||||||
|
self._assert_noerr(im)
|
||||||
|
|
||||||
def test_g4_eq_png(self):
|
def test_g4_eq_png(self):
|
||||||
""" Checking that we're actually getting the data that we expect"""
|
""" Checking that we're actually getting the data that we expect"""
|
||||||
png = Image.open("Tests/images/hopper_bw_500.png")
|
png = Image.open("Tests/images/hopper_bw_500.png")
|
||||||
|
|
|
@ -286,7 +286,7 @@ class TestFileTiffMetadata(PillowTestCase):
|
||||||
reloaded = Image.open(out)
|
reloaded = Image.open(out)
|
||||||
self.assertEqual(reloaded.tag_v2[37000], -60000)
|
self.assertEqual(reloaded.tag_v2[37000], -60000)
|
||||||
|
|
||||||
def test_expty_values(self):
|
def test_empty_values(self):
|
||||||
data = io.BytesIO(
|
data = io.BytesIO(
|
||||||
b"II*\x00\x08\x00\x00\x00\x03\x00\x1a\x01\x05\x00\x00\x00\x00\x00"
|
b"II*\x00\x08\x00\x00\x00\x03\x00\x1a\x01\x05\x00\x00\x00\x00\x00"
|
||||||
b"\x00\x00\x00\x00\x1b\x01\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
b"\x00\x00\x00\x00\x1b\x01\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# install libimagequant
|
# install libimagequant
|
||||||
|
|
||||||
archive=libimagequant-2.12.3
|
archive=libimagequant-2.12.5
|
||||||
|
|
||||||
./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/master/$archive.tar.gz
|
./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/master/$archive.tar.gz
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ Many of Pillow's features require external libraries:
|
||||||
|
|
||||||
* **libimagequant** provides improved color quantization
|
* **libimagequant** provides improved color quantization
|
||||||
|
|
||||||
* Pillow has been tested with libimagequant **2.6-2.12.3**
|
* Pillow has been tested with libimagequant **2.6-2.12.5**
|
||||||
* Libimagequant is licensed GPLv3, which is more restrictive than
|
* Libimagequant is licensed GPLv3, which is more restrictive than
|
||||||
the Pillow license, therefore we will not be distributing binaries
|
the Pillow license, therefore we will not be distributing binaries
|
||||||
with libimagequant support enabled.
|
with libimagequant support enabled.
|
||||||
|
|
4
setup.py
4
setup.py
|
@ -432,7 +432,9 @@ class pil_build_ext(build_ext):
|
||||||
# pythonX.Y.dll.a is in the /usr/lib/pythonX.Y/config directory
|
# pythonX.Y.dll.a is in the /usr/lib/pythonX.Y/config directory
|
||||||
_add_directory(
|
_add_directory(
|
||||||
library_dirs,
|
library_dirs,
|
||||||
os.path.join("/usr/lib", "python%s" % sys.version[:3], "config"),
|
os.path.join(
|
||||||
|
"/usr/lib", "python{}.{}".format(*sys.version_info), "config"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
elif sys.platform == "darwin":
|
elif sys.platform == "darwin":
|
||||||
|
|
|
@ -489,6 +489,11 @@ def _write_multiple_frames(im, fp, palette):
|
||||||
offset = frame_data["bbox"][:2]
|
offset = frame_data["bbox"][:2]
|
||||||
_write_frame_data(fp, im_frame, offset, frame_data["encoderinfo"])
|
_write_frame_data(fp, im_frame, offset, frame_data["encoderinfo"])
|
||||||
return True
|
return True
|
||||||
|
elif "duration" in im.encoderinfo and isinstance(
|
||||||
|
im.encoderinfo["duration"], (list, tuple)
|
||||||
|
):
|
||||||
|
# Since multiple frames will not be written, add together the frame durations
|
||||||
|
im.encoderinfo["duration"] = sum(im.encoderinfo["duration"])
|
||||||
|
|
||||||
|
|
||||||
def _save_all(im, fp, filename):
|
def _save_all(im, fp, filename):
|
||||||
|
|
|
@ -263,6 +263,9 @@ class IcoImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
Handles classic, XP and Vista icon formats.
|
Handles classic, XP and Vista icon formats.
|
||||||
|
|
||||||
|
When saving, PNG compression is used. Support for this was only added in
|
||||||
|
Windows Vista.
|
||||||
|
|
||||||
This plugin is a refactored version of Win32IconImagePlugin by Bryan Davis
|
This plugin is a refactored version of Win32IconImagePlugin by Bryan Davis
|
||||||
<casadebender@gmail.com>.
|
<casadebender@gmail.com>.
|
||||||
https://code.google.com/archive/p/casadebender/wikis/Win32IconImagePlugin.wiki
|
https://code.google.com/archive/p/casadebender/wikis/Win32IconImagePlugin.wiki
|
||||||
|
|
|
@ -2110,7 +2110,7 @@ class Image(object):
|
||||||
debugging purposes.
|
debugging purposes.
|
||||||
|
|
||||||
On Unix platforms, this method saves the image to a temporary
|
On Unix platforms, this method saves the image to a temporary
|
||||||
PPM file, and calls the **display**, **eog** or **xv**
|
PNG file, and calls the **display**, **eog** or **xv**
|
||||||
utility, depending on which one can be found.
|
utility, depending on which one can be found.
|
||||||
|
|
||||||
On macOS, this method saves the image to a temporary PNG file, and
|
On macOS, this method saves the image to a temporary PNG file, and
|
||||||
|
|
|
@ -546,11 +546,20 @@ def truetype(font=None, size=10, index=0, encoding="", layout_engine=None):
|
||||||
This function loads a font object from the given file or file-like
|
This function loads a font object from the given file or file-like
|
||||||
object, and creates a font object for a font of the given size.
|
object, and creates a font object for a font of the given size.
|
||||||
|
|
||||||
|
Pillow uses FreeType to open font files. If you are opening many fonts
|
||||||
|
simultaneously on Windows, be aware that Windows limits the number of files
|
||||||
|
that can be open in C at once to 512. If you approach that limit, an
|
||||||
|
``OSError`` may be thrown, reporting that FreeType "cannot open resource".
|
||||||
|
|
||||||
This function requires the _imagingft service.
|
This function requires the _imagingft service.
|
||||||
|
|
||||||
:param font: A filename or file-like object containing a TrueType font.
|
:param font: A filename or file-like object containing a TrueType font.
|
||||||
Under Windows, if the file is not found in this filename,
|
If the file is not found in this filename, the loader may also
|
||||||
the loader also looks in Windows :file:`fonts/` directory.
|
search in other directories, such as the :file:`fonts/`
|
||||||
|
directory on Windows or :file:`/Library/Fonts/`,
|
||||||
|
:file:`/System/Library/Fonts/` and :file:`~/Library/Fonts/` on
|
||||||
|
macOS.
|
||||||
|
|
||||||
:param size: The requested size, in points.
|
:param size: The requested size, in points.
|
||||||
:param index: Which font face to load (default is first available face).
|
:param index: Which font face to load (default is first available face).
|
||||||
:param encoding: Which font encoding to use (default is Unicode). Common
|
:param encoding: Which font encoding to use (default is Unicode). Common
|
||||||
|
|
|
@ -179,7 +179,7 @@ else:
|
||||||
with open(path, "r") as f:
|
with open(path, "r") as f:
|
||||||
command = self.get_command_ex(file, **options)[0]
|
command = self.get_command_ex(file, **options)[0]
|
||||||
subprocess.Popen(
|
subprocess.Popen(
|
||||||
["im=$(cat);" + command + " $im;" "rm -f $im"], shell=True, stdin=f
|
["im=$(cat);" + command + " $im; rm -f $im"], shell=True, stdin=f
|
||||||
)
|
)
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -1191,7 +1191,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print("have getvalue. just sending in a string from getvalue")
|
print("have getvalue. just sending in a string from getvalue")
|
||||||
n, err = decoder.decode(self.fp.getvalue())
|
n, err = decoder.decode(self.fp.getvalue())
|
||||||
elif hasattr(self.fp, "fileno"):
|
elif fp:
|
||||||
# we've got a actual file on disk, pass in the fp.
|
# we've got a actual file on disk, pass in the fp.
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print("have fileno, calling fileno version of the decoder.")
|
print("have fileno, calling fileno version of the decoder.")
|
||||||
|
@ -1202,6 +1202,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
# we have something else.
|
# we have something else.
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print("don't have fileno or getvalue. just reading")
|
print("don't have fileno or getvalue. just reading")
|
||||||
|
self.fp.seek(0)
|
||||||
# UNDONE -- so much for that buffer size thing.
|
# UNDONE -- so much for that buffer size thing.
|
||||||
n, err = decoder.decode(self.fp.read())
|
n, err = decoder.decode(self.fp.read())
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,9 @@ libs = {
|
||||||
"dir": "tiff-4.0.10",
|
"dir": "tiff-4.0.10",
|
||||||
},
|
},
|
||||||
"freetype": {
|
"freetype": {
|
||||||
"url": "https://download.savannah.gnu.org/releases/freetype/freetype-2.10.0.tar.gz", # noqa: E501
|
"url": "https://download.savannah.gnu.org/releases/freetype/freetype-2.10.1.tar.gz", # noqa: E501
|
||||||
"filename": PILLOW_DEPENDS_DIR + "freetype-2.10.0.tar.gz",
|
"filename": PILLOW_DEPENDS_DIR + "freetype-2.10.1.tar.gz",
|
||||||
"dir": "freetype-2.10.0",
|
"dir": "freetype-2.10.1",
|
||||||
},
|
},
|
||||||
"lcms": {
|
"lcms": {
|
||||||
"url": SF_MIRROR + "/project/lcms/lcms/2.7/lcms2-2.7.zip",
|
"url": SF_MIRROR + "/project/lcms/lcms/2.7/lcms2-2.7.zip",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user