mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +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