mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +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:
 | 
			
		||||
    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:
 | 
			
		||||
      run:
 | 
			
		||||
        shell: bash.exe --login -eo pipefail "{0}"
 | 
			
		||||
    env:
 | 
			
		||||
      MSYSTEM: MINGW64
 | 
			
		||||
      MSYSTEM: ${{ matrix.mingw }}
 | 
			
		||||
      CHERE_INVOKING: 1
 | 
			
		||||
 | 
			
		||||
    timeout-minutes: 30
 | 
			
		||||
    name: MSYS2 MinGW 64-bit
 | 
			
		||||
    name: ${{ matrix.name }}
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v2
 | 
			
		||||
| 
						 | 
				
			
			@ -218,23 +230,23 @@ jobs:
 | 
			
		|||
      - name: Install Dependencies
 | 
			
		||||
        run: |
 | 
			
		||||
          pacman -S --noconfirm \
 | 
			
		||||
              mingw-w64-x86_64-python3-cffi \
 | 
			
		||||
              mingw-w64-x86_64-python3-numpy \
 | 
			
		||||
              mingw-w64-x86_64-python3-olefile \
 | 
			
		||||
              mingw-w64-x86_64-python3-pip \
 | 
			
		||||
              mingw-w64-x86_64-python3-pyqt5 \
 | 
			
		||||
              mingw-w64-x86_64-python3-pytest \
 | 
			
		||||
              mingw-w64-x86_64-python3-pytest-cov \
 | 
			
		||||
              mingw-w64-x86_64-python3-setuptools \
 | 
			
		||||
              mingw-w64-x86_64-freetype \
 | 
			
		||||
              mingw-w64-x86_64-ghostscript \
 | 
			
		||||
              mingw-w64-x86_64-lcms2 \
 | 
			
		||||
              mingw-w64-x86_64-libimagequant \
 | 
			
		||||
              mingw-w64-x86_64-libjpeg-turbo \
 | 
			
		||||
              mingw-w64-x86_64-libraqm \
 | 
			
		||||
              mingw-w64-x86_64-libtiff \
 | 
			
		||||
              mingw-w64-x86_64-libwebp \
 | 
			
		||||
              mingw-w64-x86_64-openjpeg2 \
 | 
			
		||||
              ${{ matrix.package }}-python3-cffi \
 | 
			
		||||
              ${{ matrix.package }}-python3-numpy \
 | 
			
		||||
              ${{ matrix.package }}-python3-olefile \
 | 
			
		||||
              ${{ matrix.package }}-python3-pip \
 | 
			
		||||
              ${{ matrix.package }}-python3-pyqt5 \
 | 
			
		||||
              ${{ matrix.package }}-python3-pytest \
 | 
			
		||||
              ${{ matrix.package }}-python3-pytest-cov \
 | 
			
		||||
              ${{ matrix.package }}-python3-setuptools \
 | 
			
		||||
              ${{ matrix.package }}-freetype \
 | 
			
		||||
              ${{ matrix.package }}-ghostscript \
 | 
			
		||||
              ${{ matrix.package }}-lcms2 \
 | 
			
		||||
              ${{ matrix.package }}-libimagequant \
 | 
			
		||||
              ${{ matrix.package }}-libjpeg-turbo \
 | 
			
		||||
              ${{ matrix.package }}-libraqm \
 | 
			
		||||
              ${{ matrix.package }}-libtiff \
 | 
			
		||||
              ${{ matrix.package }}-libwebp \
 | 
			
		||||
              ${{ matrix.package }}-openjpeg2 \
 | 
			
		||||
              subversion
 | 
			
		||||
 | 
			
		||||
          python3 -m pip install pyroma
 | 
			
		||||
| 
						 | 
				
			
			@ -254,4 +266,4 @@ jobs:
 | 
			
		|||
          python3 -m pip install codecov
 | 
			
		||||
          bash <(curl -s https://codecov.io/bash) -F GHA_Windows
 | 
			
		||||
        env:
 | 
			
		||||
          CODECOV_NAME: MSYS2 MinGW 64-bit
 | 
			
		||||
          CODECOV_NAME: ${{ matrix.name }}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
repos:
 | 
			
		||||
  - repo: https://github.com/psf/black
 | 
			
		||||
    rev: 6bedb5c58a7d8c25aa9509f8217bc24e9797e90d  # frozen: 19.10b0
 | 
			
		||||
    rev: e66be67b9b6811913470f70c28b4d50f94d05b22  # frozen: 20.8b1
 | 
			
		||||
    hooks:
 | 
			
		||||
      - id: black
 | 
			
		||||
        args: ["--target-version", "py35"]
 | 
			
		||||
| 
						 | 
				
			
			@ -9,7 +9,7 @@ repos:
 | 
			
		|||
        types: []
 | 
			
		||||
 | 
			
		||||
  - repo: https://github.com/timothycrosley/isort
 | 
			
		||||
    rev: 9ae09866e278fbc6ec0383ccb16b5c84e78e6e4d  # frozen: 5.3.2
 | 
			
		||||
    rev: 377d260ffa6f746693f97b46d95025afc4bd8275  # frozen: 5.4.2
 | 
			
		||||
    hooks:
 | 
			
		||||
      - id: isort
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ repos:
 | 
			
		|||
        additional_dependencies: [flake8-2020, flake8-implicit-str-concat]
 | 
			
		||||
 | 
			
		||||
  - repo: https://github.com/pre-commit/pygrep-hooks
 | 
			
		||||
    rev: 20b9ac745c5adaab12b845b3564c773dcc051d0e  # frozen: v1.5.2
 | 
			
		||||
    rev: eae6397e4c259ed3d057511f6dd5330b92867e62  # frozen: v1.6.0
 | 
			
		||||
    hooks:
 | 
			
		||||
      - id: python-check-blanket-noqa
 | 
			
		||||
      - id: rst-backticks
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								CHANGES.rst
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								CHANGES.rst
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -5,6 +5,24 @@ Changelog (Pillow)
 | 
			
		|||
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
 | 
			
		||||
  [radarhere]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -119,60 +119,59 @@ def test_qtables_leak():
 | 
			
		|||
 | 
			
		||||
def test_exif_leak():
 | 
			
		||||
    """
 | 
			
		||||
pre patch:
 | 
			
		||||
    pre patch:
 | 
			
		||||
 | 
			
		||||
    MB
 | 
			
		||||
177.1^                                                                       #
 | 
			
		||||
     |                                                                    @@@#
 | 
			
		||||
     |                                                                :@@@@@@#
 | 
			
		||||
     |                                                             ::::@@@@@@#
 | 
			
		||||
     |                                                         ::::::::@@@@@@#
 | 
			
		||||
     |                                                     @@::::: ::::@@@@@@#
 | 
			
		||||
     |                                                  @@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |                                               @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |                                           @@::@@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |                                        @@@@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |                                   @@@@@@ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |                                @@@@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |                            @::@@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |                        ::::@: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |                     :@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |                ::@@::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |            @@::: @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |         @::@ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |      :::@: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
     |   @@@:: @: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
   0 +----------------------------------------------------------------------->Gi
 | 
			
		||||
     0                                                                   11.37
 | 
			
		||||
        MB
 | 
			
		||||
    177.1^                                                                       #
 | 
			
		||||
         |                                                                    @@@#
 | 
			
		||||
         |                                                                :@@@@@@#
 | 
			
		||||
         |                                                             ::::@@@@@@#
 | 
			
		||||
         |                                                         ::::::::@@@@@@#
 | 
			
		||||
         |                                                     @@::::: ::::@@@@@@#
 | 
			
		||||
         |                                                  @@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |                                               @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |                                           @@::@@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |                                        @@@@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |                                   @@@@@@ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |                                @@@@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |                            @::@@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |                        ::::@: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |                     :@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |                ::@@::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |            @@::: @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |         @::@ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |      :::@: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
         |   @@@:: @: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
 | 
			
		||||
       0 +----------------------------------------------------------------------->Gi
 | 
			
		||||
         0                                                                   11.37
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
post patch:
 | 
			
		||||
    post patch:
 | 
			
		||||
 | 
			
		||||
    MB
 | 
			
		||||
21.06^        ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |      ##::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |    @@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     | @@@@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
     | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
   0 +----------------------------------------------------------------------->Gi
 | 
			
		||||
     0                                                                   11.33
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
        MB
 | 
			
		||||
    21.06^        ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |      ##::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |     @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |    @@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         |   @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         | @@@@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
         | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
 | 
			
		||||
       0 +----------------------------------------------------------------------->Gi
 | 
			
		||||
         0                                                                   11.33
 | 
			
		||||
    """
 | 
			
		||||
    im = hopper("RGB")
 | 
			
		||||
    exif = b"12345678" * 4096
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -183,31 +182,30 @@ post patch:
 | 
			
		|||
 | 
			
		||||
def test_base_save():
 | 
			
		||||
    """
 | 
			
		||||
base case:
 | 
			
		||||
    MB
 | 
			
		||||
20.99^           :::::         :::::::::::::::::::::::::::::::::::::::::::@:::
 | 
			
		||||
     |         ##: : ::::::@::::::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |       @@# : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |       @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |       @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |     @@@ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |     @ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     | :@@@@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
     | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
   0 +----------------------------------------------------------------------->Gi
 | 
			
		||||
     0                                                                   7.882
 | 
			
		||||
"""
 | 
			
		||||
    base case:
 | 
			
		||||
        MB
 | 
			
		||||
    20.99^           :::::         :::::::::::::::::::::::::::::::::::::::::::@:::
 | 
			
		||||
         |         ##: : ::::::@::::::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |       @@# : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |       @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |       @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |     @@@ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |     @ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         |    @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         | :@@@@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
         | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
 | 
			
		||||
       0 +----------------------------------------------------------------------->Gi
 | 
			
		||||
         0                                                                   7.882"""
 | 
			
		||||
    im = hopper("RGB")
 | 
			
		||||
 | 
			
		||||
    for _ in range(iterations):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,9 +6,9 @@ TEST_FILE = "Tests/images/libtiff_segfault.tif"
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def test_libtiff_segfault():
 | 
			
		||||
    """ This test should not segfault. It will on Pillow <= 3.1.0 and
 | 
			
		||||
        libtiff >= 4.0.0
 | 
			
		||||
        """
 | 
			
		||||
    """This test should not segfault. It will on Pillow <= 3.1.0 and
 | 
			
		||||
    libtiff >= 4.0.0
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    with pytest.raises(OSError):
 | 
			
		||||
        with Image.open(TEST_FILE) as im:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,8 +16,8 @@ def get_files(d, ext=".bmp"):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def test_bad():
 | 
			
		||||
    """ These shouldn't crash/dos, but they shouldn't return anything
 | 
			
		||||
    either """
 | 
			
		||||
    """These shouldn't crash/dos, but they shouldn't return anything
 | 
			
		||||
    either"""
 | 
			
		||||
    for f in get_files("b"):
 | 
			
		||||
 | 
			
		||||
        def open(f):
 | 
			
		||||
| 
						 | 
				
			
			@ -32,8 +32,8 @@ def test_bad():
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def test_questionable():
 | 
			
		||||
    """ These shouldn't crash/dos, but it's not well defined that these
 | 
			
		||||
    are in spec """
 | 
			
		||||
    """These shouldn't crash/dos, but it's not well defined that these
 | 
			
		||||
    are in spec"""
 | 
			
		||||
    supported = [
 | 
			
		||||
        "pal8os2v2.bmp",
 | 
			
		||||
        "rgb24prof.bmp",
 | 
			
		||||
| 
						 | 
				
			
			@ -57,8 +57,8 @@ def test_questionable():
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def test_good():
 | 
			
		||||
    """ These should all work. There's a set of target files in the
 | 
			
		||||
    html directory that we can compare against. """
 | 
			
		||||
    """These should all work. There's a set of target files in the
 | 
			
		||||
    html directory that we can compare against."""
 | 
			
		||||
 | 
			
		||||
    # Target files, if they're not just replacing the extension
 | 
			
		||||
    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:
 | 
			
		||||
        frames = [im.copy(), Image.new("RGBA", im.size, (255, 0, 0, 255))]
 | 
			
		||||
        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:
 | 
			
		||||
        exception = None
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ class TestFileJpeg:
 | 
			
		|||
        return im
 | 
			
		||||
 | 
			
		||||
    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 mode: optional image mode
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,8 @@ class TestFileJpeg:
 | 
			
		|||
            assert k > 0.9
 | 
			
		||||
 | 
			
		||||
    @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(xdpi, ydpi=None):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -402,8 +402,8 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
			
		|||
            assert "temp.tif" == reread.tag[269][0]
 | 
			
		||||
 | 
			
		||||
    def test_12bit_rawmode(self):
 | 
			
		||||
        """ Are we generating the same interpretation
 | 
			
		||||
        of the image as Imagemagick is? """
 | 
			
		||||
        """Are we generating the same interpretation
 | 
			
		||||
        of the image as Imagemagick is?"""
 | 
			
		||||
        TiffImagePlugin.READ_LIBTIFF = True
 | 
			
		||||
        with Image.open("Tests/images/12bit.cropped.tif") as im:
 | 
			
		||||
            im.load()
 | 
			
		||||
| 
						 | 
				
			
			@ -503,9 +503,9 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
			
		|||
            assert len(reloaded.tag_v2[320]) == 768
 | 
			
		||||
 | 
			
		||||
    def xtest_bw_compression_w_rgb(self, tmp_path):
 | 
			
		||||
        """ 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
 | 
			
		||||
            capture that but not now"""
 | 
			
		||||
        """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
 | 
			
		||||
        capture that but not now"""
 | 
			
		||||
 | 
			
		||||
        im = hopper("RGB")
 | 
			
		||||
        out = str(tmp_path / "temp.tif")
 | 
			
		||||
| 
						 | 
				
			
			@ -768,7 +768,7 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
			
		|||
            assert im.mode == "RGBA"
 | 
			
		||||
            assert im.size == (100, 40)
 | 
			
		||||
            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()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,13 +7,13 @@ from .test_file_libtiff import LibTiffTestCase
 | 
			
		|||
 | 
			
		||||
class TestFileLibTiffSmall(LibTiffTestCase):
 | 
			
		||||
 | 
			
		||||
    """ The small lena image was failing on open in the libtiff
 | 
			
		||||
        decoder because the file pointer was set to the wrong place
 | 
			
		||||
        by a spurious seek. It wasn't failing with the byteio method.
 | 
			
		||||
    """The small lena image was failing on open in the libtiff
 | 
			
		||||
    decoder because the file pointer was set to the wrong place
 | 
			
		||||
    by a spurious seek. It wasn't failing with the byteio method.
 | 
			
		||||
 | 
			
		||||
        It was fixed by forcing an lseek to the beginning of the
 | 
			
		||||
        file just before reading in libtiff. These tests remain
 | 
			
		||||
        to ensure that it stays fixed. """
 | 
			
		||||
    It was fixed by forcing an lseek to the beginning of the
 | 
			
		||||
    file just before reading in libtiff. These tests remain
 | 
			
		||||
    to ensure that it stays fixed."""
 | 
			
		||||
 | 
			
		||||
    def test_g4_hopper_file(self, tmp_path):
 | 
			
		||||
        """Testing the open file load path"""
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -225,8 +225,8 @@ class TestFileTiff:
 | 
			
		|||
            assert im.getpixel((0, 1)) == 0
 | 
			
		||||
 | 
			
		||||
    def test_12bit_rawmode(self):
 | 
			
		||||
        """ Are we generating the same interpretation
 | 
			
		||||
        of the image as Imagemagick is? """
 | 
			
		||||
        """Are we generating the same interpretation
 | 
			
		||||
        of the image as Imagemagick is?"""
 | 
			
		||||
 | 
			
		||||
        with Image.open("Tests/images/12bit.cropped.tif") as im:
 | 
			
		||||
            # 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):
 | 
			
		||||
    """ Test writing arbitrary metadata into the tiff image directory
 | 
			
		||||
        Use case is ImageJ private tags, one numeric, one arbitrary
 | 
			
		||||
        data.  https://github.com/python-pillow/Pillow/issues/291
 | 
			
		||||
        """
 | 
			
		||||
    """Test writing arbitrary metadata into the tiff image directory
 | 
			
		||||
    Use case is ImageJ private tags, one numeric, one arbitrary
 | 
			
		||||
    data.  https://github.com/python-pillow/Pillow/issues/291
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    img = hopper()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,7 +85,10 @@ def test_wedge():
 | 
			
		|||
        im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong"
 | 
			
		||||
    )
 | 
			
		||||
    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(
 | 
			
		||||
        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"
 | 
			
		||||
    )
 | 
			
		||||
    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(
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
    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(
 | 
			
		||||
        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(
 | 
			
		||||
        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(
 | 
			
		||||
        "test_module", [PIL, Image],
 | 
			
		||||
        "test_module",
 | 
			
		||||
        [PIL, Image],
 | 
			
		||||
    )
 | 
			
		||||
    def test_pillow_version(self, test_module):
 | 
			
		||||
        with pytest.warns(DeprecationWarning):
 | 
			
		||||
| 
						 | 
				
			
			@ -735,7 +736,7 @@ class TestImage:
 | 
			
		|||
            assert test_module.PILLOW_VERSION > "7.0.0"
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
        """
 | 
			
		||||
        for file in [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -132,9 +132,11 @@ class TestImageGetPixel(AccessTest):
 | 
			
		|||
 | 
			
		||||
        # check putpixel negative index
 | 
			
		||||
        im.putpixel((-1, -1), c)
 | 
			
		||||
        assert im.getpixel((-1, -1)) == c, (
 | 
			
		||||
            "put/getpixel roundtrip negative index failed for mode %s, color %s"
 | 
			
		||||
            % (mode, c)
 | 
			
		||||
        assert (
 | 
			
		||||
            im.getpixel((-1, -1)) == c
 | 
			
		||||
        ), "put/getpixel roundtrip negative index failed for mode %s, color %s" % (
 | 
			
		||||
            mode,
 | 
			
		||||
            c,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        # Check 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,9 @@ def test_sanity():
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def test_16bit_lut():
 | 
			
		||||
    """ Tests for 16 bit -> 8 bit lut for converting I->L images
 | 
			
		||||
        see https://github.com/python-pillow/Pillow/issues/440
 | 
			
		||||
        """
 | 
			
		||||
    """Tests for 16 bit -> 8 bit lut for converting I->L images
 | 
			
		||||
    see https://github.com/python-pillow/Pillow/issues/440
 | 
			
		||||
    """
 | 
			
		||||
    im = hopper("I")
 | 
			
		||||
    im.point(list(range(256)) * 256, "L")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -437,7 +437,7 @@ def test_extended_information():
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def test_profile_typesafety():
 | 
			
		||||
    """ Profile init type safety
 | 
			
		||||
    """Profile init type safety
 | 
			
		||||
 | 
			
		||||
    prepatch, these would segfault, postpatch they should emit a typeerror
 | 
			
		||||
    """
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -667,7 +667,10 @@ def test_floodfill_border():
 | 
			
		|||
 | 
			
		||||
    # Act
 | 
			
		||||
    ImageDraw.floodfill(
 | 
			
		||||
        im, centre_point, ImageColor.getrgb("red"), border=ImageColor.getrgb("black"),
 | 
			
		||||
        im,
 | 
			
		||||
        centre_point,
 | 
			
		||||
        ImageColor.getrgb("red"),
 | 
			
		||||
        border=ImageColor.getrgb("black"),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Assert
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,9 @@ def test_similar():
 | 
			
		|||
        (0, size_final[1] - size_bitmap[1]), text, fill=(0, 0, 0), font=font_bitmap
 | 
			
		||||
    )
 | 
			
		||||
    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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,8 @@ def test_register():
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize(
 | 
			
		||||
    "order", [-1, 0],
 | 
			
		||||
    "order",
 | 
			
		||||
    [-1, 0],
 | 
			
		||||
)
 | 
			
		||||
def test_viewer_show(order):
 | 
			
		||||
    class TestViewer(ImageShow.Viewer):
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +42,8 @@ def test_viewer_show(order):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
@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():
 | 
			
		||||
    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                    |
 | 
			
		||||
|                                  +--------------------------+-----------------------+
 | 
			
		||||
|                                  | 3.6                      |x86-64                 |
 | 
			
		||||
|                                  +--------------------------+-----------------------+
 | 
			
		||||
|                                  | 3.7/MinGW                |x86                    |
 | 
			
		||||
+----------------------------------+--------------------------+-----------------------+
 | 
			
		||||
| Windows Server 2019              | 3.6, 3.7, 3.8            |x86, x86-64            |
 | 
			
		||||
|                                  +--------------------------+-----------------------+
 | 
			
		||||
|                                  | PyPy3                    |x86                    |
 | 
			
		||||
|                                  +--------------------------+-----------------------+
 | 
			
		||||
|                                  | 3.8/MinGW                |x86, x86-64            |
 | 
			
		||||
+----------------------------------+--------------------------+-----------------------+
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -665,7 +665,7 @@ class Image:
 | 
			
		|||
        )
 | 
			
		||||
 | 
			
		||||
    def _repr_png_(self):
 | 
			
		||||
        """ iPython display hook support
 | 
			
		||||
        """iPython display hook support
 | 
			
		||||
 | 
			
		||||
        :returns: png version of the image as bytes
 | 
			
		||||
        """
 | 
			
		||||
| 
						 | 
				
			
			@ -1181,7 +1181,7 @@ class Image:
 | 
			
		|||
        available filters, see the :py:mod:`~PIL.ImageFilter` module.
 | 
			
		||||
 | 
			
		||||
        :param filter: Filter kernel.
 | 
			
		||||
        :returns: An :py:class:`~PIL.Image.Image` object.  """
 | 
			
		||||
        :returns: An :py:class:`~PIL.Image.Image` object."""
 | 
			
		||||
 | 
			
		||||
        from . import ImageFilter
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1506,7 +1506,7 @@ class Image:
 | 
			
		|||
            self.im.paste(im, box)
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
        :param im: image to composite over this one
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -277,8 +277,8 @@ def get_display_profile(handle=None):
 | 
			
		|||
 | 
			
		||||
class PyCMSError(Exception):
 | 
			
		||||
 | 
			
		||||
    """ (pyCMS) Exception class.
 | 
			
		||||
    This is used for all errors in the pyCMS API. """
 | 
			
		||||
    """(pyCMS) Exception class.
 | 
			
		||||
    This is used for all errors in the pyCMS API."""
 | 
			
		||||
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,36 +28,36 @@ MIRROR_MATRIX = [
 | 
			
		|||
class LutBuilder:
 | 
			
		||||
    """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:(...
 | 
			
		||||
             .1.
 | 
			
		||||
             111)->1
 | 
			
		||||
        4:(...
 | 
			
		||||
           .1.
 | 
			
		||||
           111)->1
 | 
			
		||||
 | 
			
		||||
      (whitespaces including linebreaks are ignored). The option 4
 | 
			
		||||
      describes a series of symmetry operations (in this case a
 | 
			
		||||
      4-rotation), the pattern is described by:
 | 
			
		||||
    (whitespaces including linebreaks are ignored). The option 4
 | 
			
		||||
    describes a series of symmetry operations (in this case a
 | 
			
		||||
    4-rotation), the pattern is described by:
 | 
			
		||||
 | 
			
		||||
      - . or X - Ignore
 | 
			
		||||
      - 1 - Pixel is on
 | 
			
		||||
      - 0 - Pixel is off
 | 
			
		||||
    - . or X - Ignore
 | 
			
		||||
    - 1 - Pixel is on
 | 
			
		||||
    - 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
 | 
			
		||||
      returned if no other match is found.
 | 
			
		||||
    The default is to return the current pixel value, which is
 | 
			
		||||
    returned if no other match is found.
 | 
			
		||||
 | 
			
		||||
      Operations:
 | 
			
		||||
    Operations:
 | 
			
		||||
 | 
			
		||||
      - 4 - 4 way rotation
 | 
			
		||||
      - N - Negate
 | 
			
		||||
      - 1 - Dummy op for no other operation (an op must always be given)
 | 
			
		||||
      - M - Mirroring
 | 
			
		||||
    - 4 - 4 way rotation
 | 
			
		||||
    - N - Negate
 | 
			
		||||
    - 1 - Dummy op for no other operation (an op must always be given)
 | 
			
		||||
    - M - Mirroring
 | 
			
		||||
 | 
			
		||||
      Example::
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
          lb = LutBuilder(patterns = ["4:(... .1. 111)->1"])
 | 
			
		||||
          lut = lb.build_lut()
 | 
			
		||||
        lb = LutBuilder(patterns = ["4:(... .1. 111)->1"])
 | 
			
		||||
        lut = lb.build_lut()
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1110,7 +1110,10 @@ def _write_multiple_frames(im, fp, chunk, rawmode):
 | 
			
		|||
 | 
			
		||||
    # animation control
 | 
			
		||||
    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)
 | 
			
		||||
| 
						 | 
				
			
			@ -1155,7 +1158,9 @@ def _write_multiple_frames(im, fp, chunk, rawmode):
 | 
			
		|||
        else:
 | 
			
		||||
            fdat_chunks = _fdat(fp, chunk, seq_num)
 | 
			
		||||
            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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -286,7 +286,7 @@ _write_dispatch = {}
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
    e.g., DigitalZoomRatio - 0.00/0.00  indicates that no digital zoom was used
 | 
			
		||||
| 
						 | 
				
			
			@ -907,7 +907,7 @@ class ImageFileDirectory_v1(ImageFileDirectory_v2):
 | 
			
		|||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def from_v2(cls, original):
 | 
			
		||||
        """ Returns an
 | 
			
		||||
        """Returns an
 | 
			
		||||
        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`
 | 
			
		||||
        instance with the same data as is contained in the original
 | 
			
		||||
        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
 | 
			
		||||
| 
						 | 
				
			
			@ -924,7 +924,7 @@ class ImageFileDirectory_v1(ImageFileDirectory_v2):
 | 
			
		|||
        return ifd
 | 
			
		||||
 | 
			
		||||
    def to_v2(self):
 | 
			
		||||
        """ Returns an
 | 
			
		||||
        """Returns an
 | 
			
		||||
        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
 | 
			
		||||
        instance with the same data as is contained in the original
 | 
			
		||||
        :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`
 | 
			
		||||
| 
						 | 
				
			
			@ -1094,8 +1094,8 @@ class TiffImageFile(ImageFile.ImageFile):
 | 
			
		|||
            self._close_exclusive_fp_after_loading = True
 | 
			
		||||
 | 
			
		||||
    def _load_libtiff(self):
 | 
			
		||||
        """ Overload method triggered when we detect a compressed tiff
 | 
			
		||||
            Calls out to libtiff """
 | 
			
		||||
        """Overload method triggered when we detect a compressed tiff
 | 
			
		||||
        Calls out to libtiff"""
 | 
			
		||||
 | 
			
		||||
        Image.Image.load(self)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user