mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +03:00 
			
		
		
		
	Merge branch 'master' into mingw-setup
This commit is contained in:
		
						commit
						9667d5c6cc
					
				
							
								
								
									
										52
									
								
								.github/workflows/test-windows.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								.github/workflows/test-windows.yml
									
									
									
									
										vendored
									
									
								
							| 
						 | 
					@ -198,15 +198,27 @@ jobs:
 | 
				
			||||||
  msys:
 | 
					  msys:
 | 
				
			||||||
    runs-on: windows-2019
 | 
					    runs-on: windows-2019
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    strategy:
 | 
				
			||||||
 | 
					      fail-fast: false
 | 
				
			||||||
 | 
					      matrix:
 | 
				
			||||||
 | 
					        mingw: ["MINGW32", "MINGW64"]
 | 
				
			||||||
 | 
					        include:
 | 
				
			||||||
 | 
					          - mingw: "MINGW32"
 | 
				
			||||||
 | 
					            name: "MSYS2 MinGW 32-bit"
 | 
				
			||||||
 | 
					            package: "mingw-w64-i686"
 | 
				
			||||||
 | 
					          - mingw: "MINGW64"
 | 
				
			||||||
 | 
					            name: "MSYS2 MinGW 64-bit"
 | 
				
			||||||
 | 
					            package: "mingw-w64-x86_64"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    defaults:
 | 
					    defaults:
 | 
				
			||||||
      run:
 | 
					      run:
 | 
				
			||||||
        shell: bash.exe --login -eo pipefail "{0}"
 | 
					        shell: bash.exe --login -eo pipefail "{0}"
 | 
				
			||||||
    env:
 | 
					    env:
 | 
				
			||||||
      MSYSTEM: MINGW64
 | 
					      MSYSTEM: ${{ matrix.mingw }}
 | 
				
			||||||
      CHERE_INVOKING: 1
 | 
					      CHERE_INVOKING: 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    timeout-minutes: 30
 | 
					    timeout-minutes: 30
 | 
				
			||||||
    name: MSYS2 MinGW 64-bit
 | 
					    name: ${{ matrix.name }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - uses: actions/checkout@v2
 | 
					      - uses: actions/checkout@v2
 | 
				
			||||||
| 
						 | 
					@ -218,23 +230,23 @@ jobs:
 | 
				
			||||||
      - name: Install Dependencies
 | 
					      - name: Install Dependencies
 | 
				
			||||||
        run: |
 | 
					        run: |
 | 
				
			||||||
          pacman -S --noconfirm \
 | 
					          pacman -S --noconfirm \
 | 
				
			||||||
              mingw-w64-x86_64-python3-cffi \
 | 
					              ${{ matrix.package }}-python3-cffi \
 | 
				
			||||||
              mingw-w64-x86_64-python3-numpy \
 | 
					              ${{ matrix.package }}-python3-numpy \
 | 
				
			||||||
              mingw-w64-x86_64-python3-olefile \
 | 
					              ${{ matrix.package }}-python3-olefile \
 | 
				
			||||||
              mingw-w64-x86_64-python3-pip \
 | 
					              ${{ matrix.package }}-python3-pip \
 | 
				
			||||||
              mingw-w64-x86_64-python3-pyqt5 \
 | 
					              ${{ matrix.package }}-python3-pyqt5 \
 | 
				
			||||||
              mingw-w64-x86_64-python3-pytest \
 | 
					              ${{ matrix.package }}-python3-pytest \
 | 
				
			||||||
              mingw-w64-x86_64-python3-pytest-cov \
 | 
					              ${{ matrix.package }}-python3-pytest-cov \
 | 
				
			||||||
              mingw-w64-x86_64-python3-setuptools \
 | 
					              ${{ matrix.package }}-python3-setuptools \
 | 
				
			||||||
              mingw-w64-x86_64-freetype \
 | 
					              ${{ matrix.package }}-freetype \
 | 
				
			||||||
              mingw-w64-x86_64-ghostscript \
 | 
					              ${{ matrix.package }}-ghostscript \
 | 
				
			||||||
              mingw-w64-x86_64-lcms2 \
 | 
					              ${{ matrix.package }}-lcms2 \
 | 
				
			||||||
              mingw-w64-x86_64-libimagequant \
 | 
					              ${{ matrix.package }}-libimagequant \
 | 
				
			||||||
              mingw-w64-x86_64-libjpeg-turbo \
 | 
					              ${{ matrix.package }}-libjpeg-turbo \
 | 
				
			||||||
              mingw-w64-x86_64-libraqm \
 | 
					              ${{ matrix.package }}-libraqm \
 | 
				
			||||||
              mingw-w64-x86_64-libtiff \
 | 
					              ${{ matrix.package }}-libtiff \
 | 
				
			||||||
              mingw-w64-x86_64-libwebp \
 | 
					              ${{ matrix.package }}-libwebp \
 | 
				
			||||||
              mingw-w64-x86_64-openjpeg2 \
 | 
					              ${{ matrix.package }}-openjpeg2 \
 | 
				
			||||||
              subversion
 | 
					              subversion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          python3 -m pip install pyroma
 | 
					          python3 -m pip install pyroma
 | 
				
			||||||
| 
						 | 
					@ -254,4 +266,4 @@ jobs:
 | 
				
			||||||
          python3 -m pip install codecov
 | 
					          python3 -m pip install codecov
 | 
				
			||||||
          bash <(curl -s https://codecov.io/bash) -F GHA_Windows
 | 
					          bash <(curl -s https://codecov.io/bash) -F GHA_Windows
 | 
				
			||||||
        env:
 | 
					        env:
 | 
				
			||||||
          CODECOV_NAME: MSYS2 MinGW 64-bit
 | 
					          CODECOV_NAME: ${{ matrix.name }}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
repos:
 | 
					repos:
 | 
				
			||||||
  - repo: https://github.com/psf/black
 | 
					  - repo: https://github.com/psf/black
 | 
				
			||||||
    rev: 6bedb5c58a7d8c25aa9509f8217bc24e9797e90d  # frozen: 19.10b0
 | 
					    rev: e66be67b9b6811913470f70c28b4d50f94d05b22  # frozen: 20.8b1
 | 
				
			||||||
    hooks:
 | 
					    hooks:
 | 
				
			||||||
      - id: black
 | 
					      - id: black
 | 
				
			||||||
        args: ["--target-version", "py35"]
 | 
					        args: ["--target-version", "py35"]
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ repos:
 | 
				
			||||||
        types: []
 | 
					        types: []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  - repo: https://github.com/timothycrosley/isort
 | 
					  - repo: https://github.com/timothycrosley/isort
 | 
				
			||||||
    rev: 9ae09866e278fbc6ec0383ccb16b5c84e78e6e4d  # frozen: 5.3.2
 | 
					    rev: 377d260ffa6f746693f97b46d95025afc4bd8275  # frozen: 5.4.2
 | 
				
			||||||
    hooks:
 | 
					    hooks:
 | 
				
			||||||
      - id: isort
 | 
					      - id: isort
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,7 @@ repos:
 | 
				
			||||||
        additional_dependencies: [flake8-2020, flake8-implicit-str-concat]
 | 
					        additional_dependencies: [flake8-2020, flake8-implicit-str-concat]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  - repo: https://github.com/pre-commit/pygrep-hooks
 | 
					  - repo: https://github.com/pre-commit/pygrep-hooks
 | 
				
			||||||
    rev: 20b9ac745c5adaab12b845b3564c773dcc051d0e  # frozen: v1.5.2
 | 
					    rev: eae6397e4c259ed3d057511f6dd5330b92867e62  # frozen: v1.6.0
 | 
				
			||||||
    hooks:
 | 
					    hooks:
 | 
				
			||||||
      - id: python-check-blanket-noqa
 | 
					      - id: python-check-blanket-noqa
 | 
				
			||||||
      - id: rst-backticks
 | 
					      - id: rst-backticks
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								CHANGES.rst
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								CHANGES.rst
									
									
									
									
									
								
							| 
						 | 
					@ -5,6 +5,24 @@ Changelog (Pillow)
 | 
				
			||||||
8.0.0 (unreleased)
 | 
					8.0.0 (unreleased)
 | 
				
			||||||
------------------
 | 
					------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fix IFDRational __eq__ bug #4888
 | 
				
			||||||
 | 
					  [luphord, radarhere]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fixed duplicate variable name #4885
 | 
				
			||||||
 | 
					  [liZe, radarhere]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Added homebrew zlib include directory #4842
 | 
				
			||||||
 | 
					  [radarhere]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Corrected inverted PDF CMYK colors #4866
 | 
				
			||||||
 | 
					  [radarhere]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Do not try to close file pointer if file pointer is empty #4823
 | 
				
			||||||
 | 
					  [radarhere]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- ImageOps.autocontrast: add mask parameter #4843
 | 
				
			||||||
 | 
					  [navneeth, hugovk]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Read EXIF data tEXt chunk into info as bytes instead of string #4828
 | 
					- Read EXIF data tEXt chunk into info as bytes instead of string #4828
 | 
				
			||||||
  [radarhere]
 | 
					  [radarhere]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,60 +119,59 @@ def test_qtables_leak():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_exif_leak():
 | 
					def test_exif_leak():
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
pre patch:
 | 
					    pre patch:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MB
 | 
					        MB
 | 
				
			||||||
177.1^                                                                       #
 | 
					    177.1^                                                                       #
 | 
				
			||||||
     |                                                                    @@@#
 | 
					         |                                                                    @@@#
 | 
				
			||||||
     |                                                                :@@@@@@#
 | 
					         |                                                                :@@@@@@#
 | 
				
			||||||
     |                                                             ::::@@@@@@#
 | 
					         |                                                             ::::@@@@@@#
 | 
				
			||||||
     |                                                         ::::::::@@@@@@#
 | 
					         |                                                         ::::::::@@@@@@#
 | 
				
			||||||
     |                                                     @@::::: ::::@@@@@@#
 | 
					         |                                                     @@::::: ::::@@@@@@#
 | 
				
			||||||
     |                                                  @@@@ ::::: ::::@@@@@@#
 | 
					         |                                                  @@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |                                               @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |                                               @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |                                           @@::@@@@@@@ ::::: ::::@@@@@@#
 | 
					         |                                           @@::@@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |                                        @@@@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |                                        @@@@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |                                   @@@@@@ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |                                   @@@@@@ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |                                @@@@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |                                @@@@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |                            @::@@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |                            @::@@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |                        ::::@: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |                        ::::@: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |                     :@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |                     :@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |                ::@@::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |                ::@@::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |            @@::: @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |            @@::: @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |         @::@ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |         @::@ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |      :::@: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |      :::@: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
     |   @@@:: @: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
					         |   @@@:: @: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
				
			||||||
   0 +----------------------------------------------------------------------->Gi
 | 
					       0 +----------------------------------------------------------------------->Gi
 | 
				
			||||||
     0                                                                   11.37
 | 
					         0                                                                   11.37
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
post patch:
 | 
					    post patch:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MB
 | 
					        MB
 | 
				
			||||||
21.06^        ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					    21.06^        ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |      ##::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |      ##::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |    @@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |    @@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     | @@@@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         | @@@@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
     | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
					         | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
				
			||||||
   0 +----------------------------------------------------------------------->Gi
 | 
					       0 +----------------------------------------------------------------------->Gi
 | 
				
			||||||
     0                                                                   11.33
 | 
					         0                                                                   11.33
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
    im = hopper("RGB")
 | 
					    im = hopper("RGB")
 | 
				
			||||||
    exif = b"12345678" * 4096
 | 
					    exif = b"12345678" * 4096
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -183,31 +182,30 @@ post patch:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_base_save():
 | 
					def test_base_save():
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
base case:
 | 
					    base case:
 | 
				
			||||||
    MB
 | 
					        MB
 | 
				
			||||||
20.99^           :::::         :::::::::::::::::::::::::::::::::::::::::::@:::
 | 
					    20.99^           :::::         :::::::::::::::::::::::::::::::::::::::::::@:::
 | 
				
			||||||
     |         ##: : ::::::@::::::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |         ##: : ::::::@::::::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |       @@# : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |       @@# : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |       @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |       @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |       @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |       @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |     @@@ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |     @@@ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |     @ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |     @ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     | :@@@@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         | :@@@@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
     | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
					         | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
				
			||||||
   0 +----------------------------------------------------------------------->Gi
 | 
					       0 +----------------------------------------------------------------------->Gi
 | 
				
			||||||
     0                                                                   7.882
 | 
					         0                                                                   7.882"""
 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
    im = hopper("RGB")
 | 
					    im = hopper("RGB")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for _ in range(iterations):
 | 
					    for _ in range(iterations):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,9 +6,9 @@ TEST_FILE = "Tests/images/libtiff_segfault.tif"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_libtiff_segfault():
 | 
					def test_libtiff_segfault():
 | 
				
			||||||
    """ This test should not segfault. It will on Pillow <= 3.1.0 and
 | 
					    """This test should not segfault. It will on Pillow <= 3.1.0 and
 | 
				
			||||||
        libtiff >= 4.0.0
 | 
					    libtiff >= 4.0.0
 | 
				
			||||||
        """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    with pytest.raises(OSError):
 | 
					    with pytest.raises(OSError):
 | 
				
			||||||
        with Image.open(TEST_FILE) as im:
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,8 +16,8 @@ def get_files(d, ext=".bmp"):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_bad():
 | 
					def test_bad():
 | 
				
			||||||
    """ These shouldn't crash/dos, but they shouldn't return anything
 | 
					    """These shouldn't crash/dos, but they shouldn't return anything
 | 
				
			||||||
    either """
 | 
					    either"""
 | 
				
			||||||
    for f in get_files("b"):
 | 
					    for f in get_files("b"):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def open(f):
 | 
					        def open(f):
 | 
				
			||||||
| 
						 | 
					@ -32,8 +32,8 @@ def test_bad():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_questionable():
 | 
					def test_questionable():
 | 
				
			||||||
    """ These shouldn't crash/dos, but it's not well defined that these
 | 
					    """These shouldn't crash/dos, but it's not well defined that these
 | 
				
			||||||
    are in spec """
 | 
					    are in spec"""
 | 
				
			||||||
    supported = [
 | 
					    supported = [
 | 
				
			||||||
        "pal8os2v2.bmp",
 | 
					        "pal8os2v2.bmp",
 | 
				
			||||||
        "rgb24prof.bmp",
 | 
					        "rgb24prof.bmp",
 | 
				
			||||||
| 
						 | 
					@ -57,8 +57,8 @@ def test_questionable():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_good():
 | 
					def test_good():
 | 
				
			||||||
    """ These should all work. There's a set of target files in the
 | 
					    """These should all work. There's a set of target files in the
 | 
				
			||||||
    html directory that we can compare against. """
 | 
					    html directory that we can compare against."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Target files, if they're not just replacing the extension
 | 
					    # Target files, if they're not just replacing the extension
 | 
				
			||||||
    file_map = {
 | 
					    file_map = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -359,7 +359,10 @@ def test_apng_save_split_fdat(tmp_path):
 | 
				
			||||||
    with Image.open("Tests/images/old-style-jpeg-compression.png") as im:
 | 
					    with Image.open("Tests/images/old-style-jpeg-compression.png") as im:
 | 
				
			||||||
        frames = [im.copy(), Image.new("RGBA", im.size, (255, 0, 0, 255))]
 | 
					        frames = [im.copy(), Image.new("RGBA", im.size, (255, 0, 0, 255))]
 | 
				
			||||||
        im.save(
 | 
					        im.save(
 | 
				
			||||||
            test_file, save_all=True, default_image=True, append_images=frames,
 | 
					            test_file,
 | 
				
			||||||
 | 
					            save_all=True,
 | 
				
			||||||
 | 
					            default_image=True,
 | 
				
			||||||
 | 
					            append_images=frames,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    with Image.open(test_file) as im:
 | 
					    with Image.open(test_file) as im:
 | 
				
			||||||
        exception = None
 | 
					        exception = None
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ class TestFileJpeg:
 | 
				
			||||||
        return im
 | 
					        return im
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def gen_random_image(self, size, mode="RGB"):
 | 
					    def gen_random_image(self, size, mode="RGB"):
 | 
				
			||||||
        """ Generates a very hard to compress file
 | 
					        """Generates a very hard to compress file
 | 
				
			||||||
        :param size: tuple
 | 
					        :param size: tuple
 | 
				
			||||||
        :param mode: optional image mode
 | 
					        :param mode: optional image mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,7 +99,8 @@ class TestFileJpeg:
 | 
				
			||||||
            assert k > 0.9
 | 
					            assert k > 0.9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.parametrize(
 | 
					    @pytest.mark.parametrize(
 | 
				
			||||||
        "test_image_path", [TEST_FILE, "Tests/images/pil_sample_cmyk.jpg"],
 | 
					        "test_image_path",
 | 
				
			||||||
 | 
					        [TEST_FILE, "Tests/images/pil_sample_cmyk.jpg"],
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    def test_dpi(self, test_image_path):
 | 
					    def test_dpi(self, test_image_path):
 | 
				
			||||||
        def test(xdpi, ydpi=None):
 | 
					        def test(xdpi, ydpi=None):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -402,8 +402,8 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
            assert "temp.tif" == reread.tag[269][0]
 | 
					            assert "temp.tif" == reread.tag[269][0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_12bit_rawmode(self):
 | 
					    def test_12bit_rawmode(self):
 | 
				
			||||||
        """ Are we generating the same interpretation
 | 
					        """Are we generating the same interpretation
 | 
				
			||||||
        of the image as Imagemagick is? """
 | 
					        of the image as Imagemagick is?"""
 | 
				
			||||||
        TiffImagePlugin.READ_LIBTIFF = True
 | 
					        TiffImagePlugin.READ_LIBTIFF = True
 | 
				
			||||||
        with Image.open("Tests/images/12bit.cropped.tif") as im:
 | 
					        with Image.open("Tests/images/12bit.cropped.tif") as im:
 | 
				
			||||||
            im.load()
 | 
					            im.load()
 | 
				
			||||||
| 
						 | 
					@ -503,9 +503,9 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
            assert len(reloaded.tag_v2[320]) == 768
 | 
					            assert len(reloaded.tag_v2[320]) == 768
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def xtest_bw_compression_w_rgb(self, tmp_path):
 | 
					    def xtest_bw_compression_w_rgb(self, tmp_path):
 | 
				
			||||||
        """ This test passes, but when running all tests causes a failure due
 | 
					        """This test passes, but when running all tests causes a failure due
 | 
				
			||||||
            to output on stderr from the error thrown by libtiff. We need to
 | 
					        to output on stderr from the error thrown by libtiff. We need to
 | 
				
			||||||
            capture that but not now"""
 | 
					        capture that but not now"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = hopper("RGB")
 | 
					        im = hopper("RGB")
 | 
				
			||||||
        out = str(tmp_path / "temp.tif")
 | 
					        out = str(tmp_path / "temp.tif")
 | 
				
			||||||
| 
						 | 
					@ -768,7 +768,7 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
            assert im.mode == "RGBA"
 | 
					            assert im.mode == "RGBA"
 | 
				
			||||||
            assert im.size == (100, 40)
 | 
					            assert im.size == (100, 40)
 | 
				
			||||||
            assert im.tile, [
 | 
					            assert im.tile, [
 | 
				
			||||||
                ("libtiff", (0, 0, 100, 40), 0, ("RGBa;16N", "tiff_lzw", False, 38236),)
 | 
					                ("libtiff", (0, 0, 100, 40), 0, ("RGBa;16N", "tiff_lzw", False, 38236))
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
            im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,13 +7,13 @@ from .test_file_libtiff import LibTiffTestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestFileLibTiffSmall(LibTiffTestCase):
 | 
					class TestFileLibTiffSmall(LibTiffTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """ The small lena image was failing on open in the libtiff
 | 
					    """The small lena image was failing on open in the libtiff
 | 
				
			||||||
        decoder because the file pointer was set to the wrong place
 | 
					    decoder because the file pointer was set to the wrong place
 | 
				
			||||||
        by a spurious seek. It wasn't failing with the byteio method.
 | 
					    by a spurious seek. It wasn't failing with the byteio method.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        It was fixed by forcing an lseek to the beginning of the
 | 
					    It was fixed by forcing an lseek to the beginning of the
 | 
				
			||||||
        file just before reading in libtiff. These tests remain
 | 
					    file just before reading in libtiff. These tests remain
 | 
				
			||||||
        to ensure that it stays fixed. """
 | 
					    to ensure that it stays fixed."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_g4_hopper_file(self, tmp_path):
 | 
					    def test_g4_hopper_file(self, tmp_path):
 | 
				
			||||||
        """Testing the open file load path"""
 | 
					        """Testing the open file load path"""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -225,8 +225,8 @@ class TestFileTiff:
 | 
				
			||||||
            assert im.getpixel((0, 1)) == 0
 | 
					            assert im.getpixel((0, 1)) == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_12bit_rawmode(self):
 | 
					    def test_12bit_rawmode(self):
 | 
				
			||||||
        """ Are we generating the same interpretation
 | 
					        """Are we generating the same interpretation
 | 
				
			||||||
        of the image as Imagemagick is? """
 | 
					        of the image as Imagemagick is?"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with Image.open("Tests/images/12bit.cropped.tif") as im:
 | 
					        with Image.open("Tests/images/12bit.cropped.tif") as im:
 | 
				
			||||||
            # to make the target --
 | 
					            # to make the target --
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,10 +12,10 @@ TAG_IDS = {info.name: info.value for info in TiffTags.TAGS_V2.values()}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_rt_metadata(tmp_path):
 | 
					def test_rt_metadata(tmp_path):
 | 
				
			||||||
    """ Test writing arbitrary metadata into the tiff image directory
 | 
					    """Test writing arbitrary metadata into the tiff image directory
 | 
				
			||||||
        Use case is ImageJ private tags, one numeric, one arbitrary
 | 
					    Use case is ImageJ private tags, one numeric, one arbitrary
 | 
				
			||||||
        data.  https://github.com/python-pillow/Pillow/issues/291
 | 
					    data.  https://github.com/python-pillow/Pillow/issues/291
 | 
				
			||||||
        """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    img = hopper()
 | 
					    img = hopper()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,7 +85,10 @@ def test_wedge():
 | 
				
			||||||
        im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong"
 | 
					        im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    assert_image_similar(
 | 
					    assert_image_similar(
 | 
				
			||||||
        im.getchannel(1), comparable.getchannel(1), 1, "Saturation conversion is wrong",
 | 
					        im.getchannel(1),
 | 
				
			||||||
 | 
					        comparable.getchannel(1),
 | 
				
			||||||
 | 
					        1,
 | 
				
			||||||
 | 
					        "Saturation conversion is wrong",
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    assert_image_similar(
 | 
					    assert_image_similar(
 | 
				
			||||||
        im.getchannel(2), comparable.getchannel(2), 1, "Value conversion is wrong"
 | 
					        im.getchannel(2), comparable.getchannel(2), 1, "Value conversion is wrong"
 | 
				
			||||||
| 
						 | 
					@ -113,7 +116,10 @@ def test_convert():
 | 
				
			||||||
        im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong"
 | 
					        im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    assert_image_similar(
 | 
					    assert_image_similar(
 | 
				
			||||||
        im.getchannel(1), comparable.getchannel(1), 1, "Saturation conversion is wrong",
 | 
					        im.getchannel(1),
 | 
				
			||||||
 | 
					        comparable.getchannel(1),
 | 
				
			||||||
 | 
					        1,
 | 
				
			||||||
 | 
					        "Saturation conversion is wrong",
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    assert_image_similar(
 | 
					    assert_image_similar(
 | 
				
			||||||
        im.getchannel(2), comparable.getchannel(2), 1, "Value conversion is wrong"
 | 
					        im.getchannel(2), comparable.getchannel(2), 1, "Value conversion is wrong"
 | 
				
			||||||
| 
						 | 
					@ -126,11 +132,20 @@ def test_hsv_to_rgb():
 | 
				
			||||||
    comparable = to_rgb_colorsys(comparable)
 | 
					    comparable = to_rgb_colorsys(comparable)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert_image_similar(
 | 
					    assert_image_similar(
 | 
				
			||||||
        converted.getchannel(0), comparable.getchannel(0), 3, "R conversion is wrong",
 | 
					        converted.getchannel(0),
 | 
				
			||||||
 | 
					        comparable.getchannel(0),
 | 
				
			||||||
 | 
					        3,
 | 
				
			||||||
 | 
					        "R conversion is wrong",
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    assert_image_similar(
 | 
					    assert_image_similar(
 | 
				
			||||||
        converted.getchannel(1), comparable.getchannel(1), 3, "G conversion is wrong",
 | 
					        converted.getchannel(1),
 | 
				
			||||||
 | 
					        comparable.getchannel(1),
 | 
				
			||||||
 | 
					        3,
 | 
				
			||||||
 | 
					        "G conversion is wrong",
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    assert_image_similar(
 | 
					    assert_image_similar(
 | 
				
			||||||
        converted.getchannel(2), comparable.getchannel(2), 3, "B conversion is wrong",
 | 
					        converted.getchannel(2),
 | 
				
			||||||
 | 
					        comparable.getchannel(2),
 | 
				
			||||||
 | 
					        3,
 | 
				
			||||||
 | 
					        "B conversion is wrong",
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -707,7 +707,8 @@ class TestImage:
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.parametrize(
 | 
					    @pytest.mark.parametrize(
 | 
				
			||||||
        "test_module", [PIL, Image],
 | 
					        "test_module",
 | 
				
			||||||
 | 
					        [PIL, Image],
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    def test_pillow_version(self, test_module):
 | 
					    def test_pillow_version(self, test_module):
 | 
				
			||||||
        with pytest.warns(DeprecationWarning):
 | 
					        with pytest.warns(DeprecationWarning):
 | 
				
			||||||
| 
						 | 
					@ -735,7 +736,7 @@ class TestImage:
 | 
				
			||||||
            assert test_module.PILLOW_VERSION > "7.0.0"
 | 
					            assert test_module.PILLOW_VERSION > "7.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_overrun(self):
 | 
					    def test_overrun(self):
 | 
				
			||||||
        """ For overrun completeness, test as:
 | 
					        """For overrun completeness, test as:
 | 
				
			||||||
        valgrind pytest -qq Tests/test_image.py::TestImage::test_overrun | grep decode.c
 | 
					        valgrind pytest -qq Tests/test_image.py::TestImage::test_overrun | grep decode.c
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        for file in [
 | 
					        for file in [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,9 +132,11 @@ class TestImageGetPixel(AccessTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # check putpixel negative index
 | 
					        # check putpixel negative index
 | 
				
			||||||
        im.putpixel((-1, -1), c)
 | 
					        im.putpixel((-1, -1), c)
 | 
				
			||||||
        assert im.getpixel((-1, -1)) == c, (
 | 
					        assert (
 | 
				
			||||||
            "put/getpixel roundtrip negative index failed for mode %s, color %s"
 | 
					            im.getpixel((-1, -1)) == c
 | 
				
			||||||
            % (mode, c)
 | 
					        ), "put/getpixel roundtrip negative index failed for mode %s, color %s" % (
 | 
				
			||||||
 | 
					            mode,
 | 
				
			||||||
 | 
					            c,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Check 0
 | 
					        # Check 0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,9 +24,9 @@ def test_sanity():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_16bit_lut():
 | 
					def test_16bit_lut():
 | 
				
			||||||
    """ Tests for 16 bit -> 8 bit lut for converting I->L images
 | 
					    """Tests for 16 bit -> 8 bit lut for converting I->L images
 | 
				
			||||||
        see https://github.com/python-pillow/Pillow/issues/440
 | 
					    see https://github.com/python-pillow/Pillow/issues/440
 | 
				
			||||||
        """
 | 
					    """
 | 
				
			||||||
    im = hopper("I")
 | 
					    im = hopper("I")
 | 
				
			||||||
    im.point(list(range(256)) * 256, "L")
 | 
					    im.point(list(range(256)) * 256, "L")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -437,7 +437,7 @@ def test_extended_information():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_profile_typesafety():
 | 
					def test_profile_typesafety():
 | 
				
			||||||
    """ Profile init type safety
 | 
					    """Profile init type safety
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    prepatch, these would segfault, postpatch they should emit a typeerror
 | 
					    prepatch, these would segfault, postpatch they should emit a typeerror
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -667,7 +667,10 @@ def test_floodfill_border():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Act
 | 
					    # Act
 | 
				
			||||||
    ImageDraw.floodfill(
 | 
					    ImageDraw.floodfill(
 | 
				
			||||||
        im, centre_point, ImageColor.getrgb("red"), border=ImageColor.getrgb("black"),
 | 
					        im,
 | 
				
			||||||
 | 
					        centre_point,
 | 
				
			||||||
 | 
					        ImageColor.getrgb("red"),
 | 
				
			||||||
 | 
					        border=ImageColor.getrgb("black"),
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Assert
 | 
					    # Assert
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,9 @@ def test_similar():
 | 
				
			||||||
        (0, size_final[1] - size_bitmap[1]), text, fill=(0, 0, 0), font=font_bitmap
 | 
					        (0, size_final[1] - size_bitmap[1]), text, fill=(0, 0, 0), font=font_bitmap
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    draw_outline.text(
 | 
					    draw_outline.text(
 | 
				
			||||||
        (0, size_final[1] - size_outline[1]), text, fill=(0, 0, 0), font=font_outline,
 | 
					        (0, size_final[1] - size_outline[1]),
 | 
				
			||||||
 | 
					        text,
 | 
				
			||||||
 | 
					        fill=(0, 0, 0),
 | 
				
			||||||
 | 
					        font=font_outline,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    assert_image_similar(im_bitmap, im_outline, 20)
 | 
					    assert_image_similar(im_bitmap, im_outline, 20)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,8 @@ def test_register():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.mark.parametrize(
 | 
					@pytest.mark.parametrize(
 | 
				
			||||||
    "order", [-1, 0],
 | 
					    "order",
 | 
				
			||||||
 | 
					    [-1, 0],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
def test_viewer_show(order):
 | 
					def test_viewer_show(order):
 | 
				
			||||||
    class TestViewer(ImageShow.Viewer):
 | 
					    class TestViewer(ImageShow.Viewer):
 | 
				
			||||||
| 
						 | 
					@ -41,7 +42,8 @@ def test_viewer_show(order):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.mark.skipif(
 | 
					@pytest.mark.skipif(
 | 
				
			||||||
    not on_ci() or is_win32(), reason="Only run on CIs; hangs on Windows CIs",
 | 
					    not on_ci() or is_win32(),
 | 
				
			||||||
 | 
					    reason="Only run on CIs; hangs on Windows CIs",
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
def test_show():
 | 
					def test_show():
 | 
				
			||||||
    for mode in ("1", "I;16", "LA", "RGB", "RGBA"):
 | 
					    for mode in ("1", "I;16", "LA", "RGB", "RGBA"):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -450,12 +450,12 @@ These platforms are built and tested for every change.
 | 
				
			||||||
| Windows Server 2016              | 3.8                      |x86                    |
 | 
					| Windows Server 2016              | 3.8                      |x86                    |
 | 
				
			||||||
|                                  +--------------------------+-----------------------+
 | 
					|                                  +--------------------------+-----------------------+
 | 
				
			||||||
|                                  | 3.6                      |x86-64                 |
 | 
					|                                  | 3.6                      |x86-64                 |
 | 
				
			||||||
|                                  +--------------------------+-----------------------+
 | 
					 | 
				
			||||||
|                                  | 3.7/MinGW                |x86                    |
 | 
					 | 
				
			||||||
+----------------------------------+--------------------------+-----------------------+
 | 
					+----------------------------------+--------------------------+-----------------------+
 | 
				
			||||||
| Windows Server 2019              | 3.6, 3.7, 3.8            |x86, x86-64            |
 | 
					| Windows Server 2019              | 3.6, 3.7, 3.8            |x86, x86-64            |
 | 
				
			||||||
|                                  +--------------------------+-----------------------+
 | 
					|                                  +--------------------------+-----------------------+
 | 
				
			||||||
|                                  | PyPy3                    |x86                    |
 | 
					|                                  | PyPy3                    |x86                    |
 | 
				
			||||||
 | 
					|                                  +--------------------------+-----------------------+
 | 
				
			||||||
 | 
					|                                  | 3.8/MinGW                |x86, x86-64            |
 | 
				
			||||||
+----------------------------------+--------------------------+-----------------------+
 | 
					+----------------------------------+--------------------------+-----------------------+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -665,7 +665,7 @@ class Image:
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _repr_png_(self):
 | 
					    def _repr_png_(self):
 | 
				
			||||||
        """ iPython display hook support
 | 
					        """iPython display hook support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :returns: png version of the image as bytes
 | 
					        :returns: png version of the image as bytes
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -1181,7 +1181,7 @@ class Image:
 | 
				
			||||||
        available filters, see the :py:mod:`~PIL.ImageFilter` module.
 | 
					        available filters, see the :py:mod:`~PIL.ImageFilter` module.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param filter: Filter kernel.
 | 
					        :param filter: Filter kernel.
 | 
				
			||||||
        :returns: An :py:class:`~PIL.Image.Image` object.  """
 | 
					        :returns: An :py:class:`~PIL.Image.Image` object."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        from . import ImageFilter
 | 
					        from . import ImageFilter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1506,7 +1506,7 @@ class Image:
 | 
				
			||||||
            self.im.paste(im, box)
 | 
					            self.im.paste(im, box)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def alpha_composite(self, im, dest=(0, 0), source=(0, 0)):
 | 
					    def alpha_composite(self, im, dest=(0, 0), source=(0, 0)):
 | 
				
			||||||
        """ 'In-place' analog of Image.alpha_composite. Composites an image
 | 
					        """'In-place' analog of Image.alpha_composite. Composites an image
 | 
				
			||||||
        onto this image.
 | 
					        onto this image.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param im: image to composite over this one
 | 
					        :param im: image to composite over this one
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -277,8 +277,8 @@ def get_display_profile(handle=None):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PyCMSError(Exception):
 | 
					class PyCMSError(Exception):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """ (pyCMS) Exception class.
 | 
					    """(pyCMS) Exception class.
 | 
				
			||||||
    This is used for all errors in the pyCMS API. """
 | 
					    This is used for all errors in the pyCMS API."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,36 +28,36 @@ MIRROR_MATRIX = [
 | 
				
			||||||
class LutBuilder:
 | 
					class LutBuilder:
 | 
				
			||||||
    """A class for building a MorphLut from a descriptive language
 | 
					    """A class for building a MorphLut from a descriptive language
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      The input patterns is a list of a strings sequences like these::
 | 
					    The input patterns is a list of a strings sequences like these::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          4:(...
 | 
					        4:(...
 | 
				
			||||||
             .1.
 | 
					           .1.
 | 
				
			||||||
             111)->1
 | 
					           111)->1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      (whitespaces including linebreaks are ignored). The option 4
 | 
					    (whitespaces including linebreaks are ignored). The option 4
 | 
				
			||||||
      describes a series of symmetry operations (in this case a
 | 
					    describes a series of symmetry operations (in this case a
 | 
				
			||||||
      4-rotation), the pattern is described by:
 | 
					    4-rotation), the pattern is described by:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - . or X - Ignore
 | 
					    - . or X - Ignore
 | 
				
			||||||
      - 1 - Pixel is on
 | 
					    - 1 - Pixel is on
 | 
				
			||||||
      - 0 - Pixel is off
 | 
					    - 0 - Pixel is off
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      The result of the operation is described after "->" string.
 | 
					    The result of the operation is described after "->" string.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      The default is to return the current pixel value, which is
 | 
					    The default is to return the current pixel value, which is
 | 
				
			||||||
      returned if no other match is found.
 | 
					    returned if no other match is found.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Operations:
 | 
					    Operations:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - 4 - 4 way rotation
 | 
					    - 4 - 4 way rotation
 | 
				
			||||||
      - N - Negate
 | 
					    - N - Negate
 | 
				
			||||||
      - 1 - Dummy op for no other operation (an op must always be given)
 | 
					    - 1 - Dummy op for no other operation (an op must always be given)
 | 
				
			||||||
      - M - Mirroring
 | 
					    - M - Mirroring
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Example::
 | 
					    Example::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          lb = LutBuilder(patterns = ["4:(... .1. 111)->1"])
 | 
					        lb = LutBuilder(patterns = ["4:(... .1. 111)->1"])
 | 
				
			||||||
          lut = lb.build_lut()
 | 
					        lut = lb.build_lut()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1110,7 +1110,10 @@ def _write_multiple_frames(im, fp, chunk, rawmode):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # animation control
 | 
					    # animation control
 | 
				
			||||||
    chunk(
 | 
					    chunk(
 | 
				
			||||||
        fp, b"acTL", o32(len(im_frames)), o32(loop),  # 0: num_frames  # 4: num_plays
 | 
					        fp,
 | 
				
			||||||
 | 
					        b"acTL",
 | 
				
			||||||
 | 
					        o32(len(im_frames)),  # 0: num_frames
 | 
				
			||||||
 | 
					        o32(loop),  # 4: num_plays
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # default image IDAT (if it exists)
 | 
					    # default image IDAT (if it exists)
 | 
				
			||||||
| 
						 | 
					@ -1155,7 +1158,9 @@ def _write_multiple_frames(im, fp, chunk, rawmode):
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            fdat_chunks = _fdat(fp, chunk, seq_num)
 | 
					            fdat_chunks = _fdat(fp, chunk, seq_num)
 | 
				
			||||||
            ImageFile._save(
 | 
					            ImageFile._save(
 | 
				
			||||||
                im_frame, fdat_chunks, [("zip", (0, 0) + im_frame.size, 0, rawmode)],
 | 
					                im_frame,
 | 
				
			||||||
 | 
					                fdat_chunks,
 | 
				
			||||||
 | 
					                [("zip", (0, 0) + im_frame.size, 0, rawmode)],
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            seq_num = fdat_chunks.seq_num
 | 
					            seq_num = fdat_chunks.seq_num
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -286,7 +286,7 @@ _write_dispatch = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IFDRational(Rational):
 | 
					class IFDRational(Rational):
 | 
				
			||||||
    """ Implements a rational class where 0/0 is a legal value to match
 | 
					    """Implements a rational class where 0/0 is a legal value to match
 | 
				
			||||||
    the in the wild use of exif rationals.
 | 
					    the in the wild use of exif rationals.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    e.g., DigitalZoomRatio - 0.00/0.00  indicates that no digital zoom was used
 | 
					    e.g., DigitalZoomRatio - 0.00/0.00  indicates that no digital zoom was used
 | 
				
			||||||
| 
						 | 
					@ -907,7 +907,7 @@ class ImageFileDirectory_v1(ImageFileDirectory_v2):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def from_v2(cls, original):
 | 
					    def from_v2(cls, original):
 | 
				
			||||||
        """ Returns an
 | 
					        """Returns an
 | 
				
			||||||
        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`
 | 
					        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`
 | 
				
			||||||
        instance with the same data as is contained in the original
 | 
					        instance with the same data as is contained in the original
 | 
				
			||||||
        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
 | 
					        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
 | 
				
			||||||
| 
						 | 
					@ -924,7 +924,7 @@ class ImageFileDirectory_v1(ImageFileDirectory_v2):
 | 
				
			||||||
        return ifd
 | 
					        return ifd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_v2(self):
 | 
					    def to_v2(self):
 | 
				
			||||||
        """ Returns an
 | 
					        """Returns an
 | 
				
			||||||
        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
 | 
					        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
 | 
				
			||||||
        instance with the same data as is contained in the original
 | 
					        instance with the same data as is contained in the original
 | 
				
			||||||
        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`
 | 
					        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`
 | 
				
			||||||
| 
						 | 
					@ -1094,8 +1094,8 @@ class TiffImageFile(ImageFile.ImageFile):
 | 
				
			||||||
            self._close_exclusive_fp_after_loading = True
 | 
					            self._close_exclusive_fp_after_loading = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _load_libtiff(self):
 | 
					    def _load_libtiff(self):
 | 
				
			||||||
        """ Overload method triggered when we detect a compressed tiff
 | 
					        """Overload method triggered when we detect a compressed tiff
 | 
				
			||||||
            Calls out to libtiff """
 | 
					        Calls out to libtiff"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Image.Image.load(self)
 | 
					        Image.Image.load(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user