mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-07-15 02:32:29 +03:00
merge() function tool and coverage improvement
This commit is contained in:
parent
99dd55324d
commit
812925ed49
200
.appveyor.yml
200
.appveyor.yml
|
@ -1,100 +1,100 @@
|
||||||
skip_commits:
|
skip_commits:
|
||||||
files:
|
files:
|
||||||
- ".github/**/*"
|
- ".github/**/*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**/*"
|
- "docs/**/*"
|
||||||
- "wheels/**/*"
|
- "wheels/**/*"
|
||||||
|
|
||||||
version: '{build}'
|
version: '{build}'
|
||||||
clone_folder: c:\pillow
|
clone_folder: c:\pillow
|
||||||
init:
|
init:
|
||||||
- ECHO %PYTHON%
|
- ECHO %PYTHON%
|
||||||
#- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
#- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
# Uncomment previous line to get RDP access during the build.
|
# Uncomment previous line to get RDP access during the build.
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
COVERAGE_CORE: sysmon
|
COVERAGE_CORE: sysmon
|
||||||
EXECUTABLE: python.exe
|
EXECUTABLE: python.exe
|
||||||
TEST_OPTIONS:
|
TEST_OPTIONS:
|
||||||
DEPLOY: YES
|
DEPLOY: YES
|
||||||
matrix:
|
matrix:
|
||||||
- PYTHON: C:/Python312
|
- PYTHON: C:/Python312
|
||||||
ARCHITECTURE: x86
|
ARCHITECTURE: x86
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||||
- PYTHON: C:/Python38-x64
|
- PYTHON: C:/Python38-x64
|
||||||
ARCHITECTURE: AMD64
|
ARCHITECTURE: AMD64
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||||
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- '%PYTHON%\%EXECUTABLE% --version'
|
- '%PYTHON%\%EXECUTABLE% --version'
|
||||||
- '%PYTHON%\%EXECUTABLE% -m pip install --upgrade pip'
|
- '%PYTHON%\%EXECUTABLE% -m pip install --upgrade pip'
|
||||||
- curl -fsSL -o pillow-test-images.zip https://github.com/python-pillow/test-images/archive/main.zip
|
- curl -fsSL -o pillow-test-images.zip https://github.com/python-pillow/test-images/archive/main.zip
|
||||||
- 7z x pillow-test-images.zip -oc:\
|
- 7z x pillow-test-images.zip -oc:\
|
||||||
- xcopy /S /Y c:\test-images-main\* c:\pillow\tests\images
|
- xcopy /S /Y c:\test-images-main\* c:\pillow\tests\images
|
||||||
- curl -fsSL -o nasm-win64.zip https://raw.githubusercontent.com/python-pillow/pillow-depends/main/nasm-2.16.03-win64.zip
|
- curl -fsSL -o nasm-win64.zip https://raw.githubusercontent.com/python-pillow/pillow-depends/main/nasm-2.16.03-win64.zip
|
||||||
- 7z x nasm-win64.zip -oc:\
|
- 7z x nasm-win64.zip -oc:\
|
||||||
- choco install ghostscript --version=10.3.1
|
- choco install ghostscript --version=10.3.1
|
||||||
- path c:\nasm-2.16.03;C:\Program Files\gs\gs10.03.1\bin;%PATH%
|
- path c:\nasm-2.16.03;C:\Program Files\gs\gs10.03.1\bin;%PATH%
|
||||||
- cd c:\pillow\winbuild\
|
- cd c:\pillow\winbuild\
|
||||||
- ps: |
|
- ps: |
|
||||||
c:\python38\python.exe c:\pillow\winbuild\build_prepare.py -v --depends=C:\pillow-depends\
|
c:\python38\python.exe c:\pillow\winbuild\build_prepare.py -v --depends=C:\pillow-depends\
|
||||||
c:\pillow\winbuild\build\build_dep_all.cmd
|
c:\pillow\winbuild\build\build_dep_all.cmd
|
||||||
$host.SetShouldExit(0)
|
$host.SetShouldExit(0)
|
||||||
- path C:\pillow\winbuild\build\bin;%PATH%
|
- path C:\pillow\winbuild\build\bin;%PATH%
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- cd c:\pillow
|
- cd c:\pillow
|
||||||
- winbuild\build\build_env.cmd
|
- winbuild\build\build_env.cmd
|
||||||
- '%PYTHON%\%EXECUTABLE% -m pip install -v -C raqm=vendor -C fribidi=vendor .'
|
- '%PYTHON%\%EXECUTABLE% -m pip install -v -C raqm=vendor -C fribidi=vendor .'
|
||||||
- '%PYTHON%\%EXECUTABLE% selftest.py --installed'
|
- '%PYTHON%\%EXECUTABLE% selftest.py --installed'
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- cd c:\pillow
|
- cd c:\pillow
|
||||||
- '%PYTHON%\%EXECUTABLE% -m pip install pytest pytest-cov pytest-timeout defusedxml numpy olefile pyroma'
|
- '%PYTHON%\%EXECUTABLE% -m pip install pytest pytest-cov pytest-timeout defusedxml numpy olefile pyroma'
|
||||||
- c:\"Program Files (x86)"\"Windows Kits"\10\Debuggers\x86\gflags.exe /p /enable %PYTHON%\%EXECUTABLE%
|
- c:\"Program Files (x86)"\"Windows Kits"\10\Debuggers\x86\gflags.exe /p /enable %PYTHON%\%EXECUTABLE%
|
||||||
- '%PYTHON%\%EXECUTABLE% -c "from PIL import Image"'
|
- '%PYTHON%\%EXECUTABLE% -c "from PIL import Image"'
|
||||||
- '%PYTHON%\%EXECUTABLE% -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests'
|
- '%PYTHON%\%EXECUTABLE% -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests'
|
||||||
#- '%PYTHON%\%EXECUTABLE% test-installed.py -v -s %TEST_OPTIONS%' TODO TEST_OPTIONS with pytest?
|
#- '%PYTHON%\%EXECUTABLE% test-installed.py -v -s %TEST_OPTIONS%' TODO TEST_OPTIONS with pytest?
|
||||||
|
|
||||||
after_test:
|
after_test:
|
||||||
- curl -Os https://uploader.codecov.io/latest/windows/codecov.exe
|
- curl -Os https://uploader.codecov.io/latest/windows/codecov.exe
|
||||||
- .\codecov.exe --file coverage.xml --name %PYTHON% --flags AppVeyor
|
- .\codecov.exe --file coverage.xml --name %PYTHON% --flags AppVeyor
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
- '%LOCALAPPDATA%\pip\Cache'
|
- '%LOCALAPPDATA%\pip\Cache'
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: pillow\*.egg
|
- path: pillow\*.egg
|
||||||
name: egg
|
name: egg
|
||||||
- path: pillow\*.whl
|
- path: pillow\*.whl
|
||||||
name: wheel
|
name: wheel
|
||||||
|
|
||||||
before_deploy:
|
before_deploy:
|
||||||
- cd c:\pillow
|
- cd c:\pillow
|
||||||
- '%PYTHON%\%EXECUTABLE% -m pip wheel -v -C raqm=vendor -C fribidi=vendor .'
|
- '%PYTHON%\%EXECUTABLE% -m pip wheel -v -C raqm=vendor -C fribidi=vendor .'
|
||||||
- ps: Get-ChildItem .\*.whl | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
- ps: Get-ChildItem .\*.whl | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
provider: S3
|
provider: S3
|
||||||
region: us-west-2
|
region: us-west-2
|
||||||
access_key_id: AKIAIRAXC62ZNTVQJMOQ
|
access_key_id: AKIAIRAXC62ZNTVQJMOQ
|
||||||
secret_access_key:
|
secret_access_key:
|
||||||
secure: Hwb6klTqtBeMgxAjRoDltiiqpuH8xbwD4UooDzBSiCWXjuFj1lyl4kHgHwTCCGqi
|
secure: Hwb6klTqtBeMgxAjRoDltiiqpuH8xbwD4UooDzBSiCWXjuFj1lyl4kHgHwTCCGqi
|
||||||
bucket: pillow-nightly
|
bucket: pillow-nightly
|
||||||
folder: win/$(APPVEYOR_BUILD_NUMBER)/
|
folder: win/$(APPVEYOR_BUILD_NUMBER)/
|
||||||
artifact: /.*egg|wheel/
|
artifact: /.*egg|wheel/
|
||||||
on:
|
on:
|
||||||
APPVEYOR_REPO_NAME: python-pillow/Pillow
|
APPVEYOR_REPO_NAME: python-pillow/Pillow
|
||||||
branch: main
|
branch: main
|
||||||
deploy: YES
|
deploy: YES
|
||||||
|
|
||||||
|
|
||||||
# Uncomment the following lines to get RDP access after the build/test and block for
|
# Uncomment the following lines to get RDP access after the build/test and block for
|
||||||
# up to the timeout limit (~1hr)
|
# up to the timeout limit (~1hr)
|
||||||
#
|
#
|
||||||
#on_finish:
|
#on_finish:
|
||||||
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# gather the coverage data
|
# gather the coverage data
|
||||||
python3 -m pip install coverage
|
python3 -m pip install coverage
|
||||||
if [[ $MATRIX_DOCKER ]]; then
|
if [[ $MATRIX_DOCKER ]]; then
|
||||||
python3 -m coverage xml --ignore-errors
|
python3 -m coverage xml --ignore-errors
|
||||||
else
|
else
|
||||||
python3 -m coverage xml
|
python3 -m coverage xml
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
cibuildwheel==2.19.1
|
cibuildwheel==2.19.1
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
mypy==1.10.0
|
mypy==1.10.0
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
# A clang-format style that approximates Python's PEP 7
|
# A clang-format style that approximates Python's PEP 7
|
||||||
# Useful for IDE integration
|
# Useful for IDE integration
|
||||||
BasedOnStyle: Google
|
BasedOnStyle: Google
|
||||||
AlwaysBreakAfterReturnType: All
|
AlwaysBreakAfterReturnType: All
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
AlignAfterOpenBracket: AlwaysBreak
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
BinPackArguments: false
|
BinPackArguments: false
|
||||||
BinPackParameters: false
|
BinPackParameters: false
|
||||||
BreakBeforeBraces: Attach
|
BreakBeforeBraces: Attach
|
||||||
ColumnLimit: 88
|
ColumnLimit: 88
|
||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
IndentGotoLabels: false
|
IndentGotoLabels: false
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
SortIncludes: false
|
SortIncludes: false
|
||||||
SpaceBeforeParens: ControlStatements
|
SpaceBeforeParens: ControlStatements
|
||||||
SpacesInParentheses: false
|
SpacesInParentheses: false
|
||||||
TabWidth: 4
|
TabWidth: 4
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
|
|
51
.coveragerc
51
.coveragerc
|
@ -1,24 +1,27 @@
|
||||||
# .coveragerc to control coverage.py
|
# .coveragerc to control coverage.py
|
||||||
|
|
||||||
[report]
|
[report]
|
||||||
# Regexes for lines to exclude from consideration
|
# Regexes for lines to exclude from consideration
|
||||||
exclude_also =
|
exclude_also =
|
||||||
# Don't complain if non-runnable code isn't run
|
# Don't complain if non-runnable code isn't run
|
||||||
if 0:
|
if 0:
|
||||||
if __name__ == .__main__.:
|
if __name__ == .__main__.:
|
||||||
# Don't complain about debug code
|
# Don't complain about debug code
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
# Don't complain about compatibility code for missing optional dependencies
|
# Don't complain about compatibility code for missing optional dependencies
|
||||||
except ImportError
|
except ImportError
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
# Empty bodies in protocols or abstract methods
|
# Empty bodies in protocols or abstract methods
|
||||||
^\s*def [a-zA-Z0-9_]+\(.*\)(\s*->.*)?:\s*\.\.\.(\s*#.*)?$
|
^\s*def [a-zA-Z0-9_]+\(.*\)(\s*->.*)?:\s*\.\.\.(\s*#.*)?$
|
||||||
^\s*\.\.\.(\s*#.*)?$
|
^\s*\.\.\.(\s*#.*)?$
|
||||||
|
|
||||||
[run]
|
[run]
|
||||||
omit =
|
omit =
|
||||||
Tests/32bit_segfault_check.py
|
# Tests/32bit_segfault_check.py
|
||||||
Tests/bench_cffi_access.py
|
# Tests/bench_cffi_access.py
|
||||||
Tests/check_*.py
|
# Tests/check_*.py
|
||||||
Tests/createfontdatachunk.py
|
# Tests/createfontdatachunk.py
|
||||||
|
Tests/*
|
||||||
|
src/*
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
# Top-most EditorConfig file
|
# Top-most EditorConfig file
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
# Unix-style newlines with a newline ending every file
|
# Unix-style newlines with a newline ending every file
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
|
|
||||||
# Four-space indentation
|
# Four-space indentation
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[*.{toml,yml}]
|
[*.{toml,yml}]
|
||||||
# Two-space indentation
|
# Two-space indentation
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
# Tab indentation (no size specified)
|
# Tab indentation (no size specified)
|
||||||
[Makefile]
|
[Makefile]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Flake8
|
# Flake8
|
||||||
8de95676e0fd89f2326b3953488ab66ff29cd2d0
|
8de95676e0fd89f2326b3953488ab66ff29cd2d0
|
||||||
# Format with Black
|
# Format with Black
|
||||||
53a7e3500437a9fd5826bc04758f7116bd7e52dc
|
53a7e3500437a9fd5826bc04758f7116bd7e52dc
|
||||||
# Format the C code with ClangFormat
|
# Format the C code with ClangFormat
|
||||||
46b7e86bab79450ec0a2866c6c0c679afb659d17
|
46b7e86bab79450ec0a2866c6c0c679afb659d17
|
||||||
|
|
6
.gitattributes
vendored
6
.gitattributes
vendored
|
@ -1,3 +1,3 @@
|
||||||
*.eps binary
|
*.eps binary
|
||||||
*.ppm binary
|
*.ppm binary
|
||||||
*.container binary
|
*.container binary
|
||||||
|
|
78
.github/CONTRIBUTING.md
vendored
78
.github/CONTRIBUTING.md
vendored
|
@ -1,39 +1,39 @@
|
||||||
# Contributing to Pillow
|
# Contributing to Pillow
|
||||||
|
|
||||||
Bug fixes, feature additions, tests, documentation and more can be contributed via [issues](https://github.com/python-pillow/Pillow/issues) and/or [pull requests](https://github.com/python-pillow/Pillow/pulls). All contributions are welcome.
|
Bug fixes, feature additions, tests, documentation and more can be contributed via [issues](https://github.com/python-pillow/Pillow/issues) and/or [pull requests](https://github.com/python-pillow/Pillow/pulls). All contributions are welcome.
|
||||||
|
|
||||||
## Bug fixes, feature additions, etc.
|
## Bug fixes, feature additions, etc.
|
||||||
|
|
||||||
Please send a pull request to the `main` branch. Please include [documentation](https://pillow.readthedocs.io) and [tests](../Tests/README.rst) for new features. Tests or documentation without bug fixes or feature additions are welcome too. Feel free to ask questions [via issues](https://github.com/python-pillow/Pillow/issues/new), [discussions](https://github.com/python-pillow/Pillow/discussions/new), [Gitter](https://gitter.im/python-pillow/Pillow) or irc://irc.freenode.net#pil
|
Please send a pull request to the `main` branch. Please include [documentation](https://pillow.readthedocs.io) and [tests](../Tests/README.rst) for new features. Tests or documentation without bug fixes or feature additions are welcome too. Feel free to ask questions [via issues](https://github.com/python-pillow/Pillow/issues/new), [discussions](https://github.com/python-pillow/Pillow/discussions/new), [Gitter](https://gitter.im/python-pillow/Pillow) or irc://irc.freenode.net#pil
|
||||||
|
|
||||||
- Fork the Pillow repository.
|
- Fork the Pillow repository.
|
||||||
- Create a branch from `main`.
|
- Create a branch from `main`.
|
||||||
- Develop bug fixes, features, tests, etc.
|
- Develop bug fixes, features, tests, etc.
|
||||||
- Run the test suite. You can enable GitHub Actions (https://github.com/MY-USERNAME/Pillow/actions) and [AppVeyor](https://ci.appveyor.com/projects/new) on your repo to catch test failures prior to the pull request, and [Codecov](https://codecov.io/gh) to see if the changed code is covered by tests.
|
- Run the test suite. You can enable GitHub Actions (https://github.com/MY-USERNAME/Pillow/actions) and [AppVeyor](https://ci.appveyor.com/projects/new) on your repo to catch test failures prior to the pull request, and [Codecov](https://codecov.io/gh) to see if the changed code is covered by tests.
|
||||||
- Create a pull request to pull the changes from your branch to the Pillow `main`.
|
- Create a pull request to pull the changes from your branch to the Pillow `main`.
|
||||||
|
|
||||||
### Guidelines
|
### Guidelines
|
||||||
|
|
||||||
- Separate code commits from reformatting commits.
|
- Separate code commits from reformatting commits.
|
||||||
- Provide tests for any newly added code.
|
- Provide tests for any newly added code.
|
||||||
- Follow PEP 8.
|
- Follow PEP 8.
|
||||||
- When committing only documentation changes please include `[ci skip]` in the commit message to avoid running tests on AppVeyor.
|
- When committing only documentation changes please include `[ci skip]` in the commit message to avoid running tests on AppVeyor.
|
||||||
- Include [release notes](https://github.com/python-pillow/Pillow/tree/main/docs/releasenotes) as needed or appropriate with your bug fixes, feature additions and tests.
|
- Include [release notes](https://github.com/python-pillow/Pillow/tree/main/docs/releasenotes) as needed or appropriate with your bug fixes, feature additions and tests.
|
||||||
- Do not add to the [changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) for proposed changes, as that is updated after changes are merged.
|
- Do not add to the [changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) for proposed changes, as that is updated after changes are merged.
|
||||||
|
|
||||||
## Reporting Issues
|
## Reporting Issues
|
||||||
|
|
||||||
When reporting issues, please include code that reproduces the issue and whenever possible, an image that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.
|
When reporting issues, please include code that reproduces the issue and whenever possible, an image that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.
|
||||||
|
|
||||||
The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as plone, Django, or buildout, try to replicate the issue just using Pillow.
|
The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as plone, Django, or buildout, try to replicate the issue just using Pillow.
|
||||||
|
|
||||||
### Provide details
|
### Provide details
|
||||||
|
|
||||||
- What did you do?
|
- What did you do?
|
||||||
- What did you expect to happen?
|
- What did you expect to happen?
|
||||||
- What actually happened?
|
- What actually happened?
|
||||||
- What versions of Pillow and Python are you using?
|
- What versions of Pillow and Python are you using?
|
||||||
|
|
||||||
## Security vulnerabilities
|
## Security vulnerabilities
|
||||||
|
|
||||||
Please see our [security policy](https://github.com/python-pillow/Pillow/blob/main/.github/SECURITY.md).
|
Please see our [security policy](https://github.com/python-pillow/Pillow/blob/main/.github/SECURITY.md).
|
||||||
|
|
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
|
@ -1 +1 @@
|
||||||
tidelift: "pypi/pillow"
|
tidelift: "pypi/pillow"
|
||||||
|
|
148
.github/ISSUE_TEMPLATE/ISSUE_REPORT.md
vendored
148
.github/ISSUE_TEMPLATE/ISSUE_REPORT.md
vendored
|
@ -1,74 +1,74 @@
|
||||||
---
|
---
|
||||||
name: Issue report
|
name: Issue report
|
||||||
about: Create a report to help us improve Pillow
|
about: Create a report to help us improve Pillow
|
||||||
---
|
---
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Thank you for reporting an issue.
|
Thank you for reporting an issue.
|
||||||
|
|
||||||
Follow these guidelines to ensure your issue is handled properly.
|
Follow these guidelines to ensure your issue is handled properly.
|
||||||
|
|
||||||
If you have a ...
|
If you have a ...
|
||||||
|
|
||||||
1. General question: consider asking the question on Stack Overflow
|
1. General question: consider asking the question on Stack Overflow
|
||||||
with the python-imaging-library tag:
|
with the python-imaging-library tag:
|
||||||
|
|
||||||
* https://stackoverflow.com/questions/tagged/python-imaging-library
|
* https://stackoverflow.com/questions/tagged/python-imaging-library
|
||||||
|
|
||||||
Do not ask a question in both places.
|
Do not ask a question in both places.
|
||||||
|
|
||||||
If you think you have found a bug or have an unexplained exception
|
If you think you have found a bug or have an unexplained exception
|
||||||
then file a bug report here.
|
then file a bug report here.
|
||||||
|
|
||||||
2. Bug report: include a self-contained, copy-pastable example that
|
2. Bug report: include a self-contained, copy-pastable example that
|
||||||
generates the issue if possible. Be concise with code posted.
|
generates the issue if possible. Be concise with code posted.
|
||||||
Guidelines on how to provide a good bug report:
|
Guidelines on how to provide a good bug report:
|
||||||
|
|
||||||
* https://stackoverflow.com/help/mcve
|
* https://stackoverflow.com/help/mcve
|
||||||
|
|
||||||
Bug reports which follow these guidelines are easier to diagnose,
|
Bug reports which follow these guidelines are easier to diagnose,
|
||||||
and are often handled much more quickly.
|
and are often handled much more quickly.
|
||||||
|
|
||||||
3. Feature request: do a quick search of existing issues
|
3. Feature request: do a quick search of existing issues
|
||||||
to make sure this has not been asked before.
|
to make sure this has not been asked before.
|
||||||
|
|
||||||
We know asking good questions takes effort, and we appreciate your time.
|
We know asking good questions takes effort, and we appreciate your time.
|
||||||
Thank you.
|
Thank you.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### What did you do?
|
### What did you do?
|
||||||
|
|
||||||
### What did you expect to happen?
|
### What did you expect to happen?
|
||||||
|
|
||||||
### What actually happened?
|
### What actually happened?
|
||||||
|
|
||||||
### What are your OS, Python and Pillow versions?
|
### What are your OS, Python and Pillow versions?
|
||||||
|
|
||||||
* OS:
|
* OS:
|
||||||
* Python:
|
* Python:
|
||||||
* Pillow:
|
* Pillow:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Please paste here the output of running:
|
Please paste here the output of running:
|
||||||
|
|
||||||
python3 -m PIL.report
|
python3 -m PIL.report
|
||||||
or
|
or
|
||||||
python3 -m PIL --report
|
python3 -m PIL --report
|
||||||
|
|
||||||
Or the output of the following Python code:
|
Or the output of the following Python code:
|
||||||
|
|
||||||
from PIL import report
|
from PIL import report
|
||||||
# or
|
# or
|
||||||
from PIL import features
|
from PIL import features
|
||||||
features.pilinfo(supported_formats=False)
|
features.pilinfo(supported_formats=False)
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.
|
Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.
|
||||||
|
|
||||||
The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as Plone, Django, or Buildout, try to replicate the issue just using Pillow.
|
The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as Plone, Django, or Buildout, try to replicate the issue just using Pillow.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
```python
|
```python
|
||||||
code goes here
|
code goes here
|
||||||
```
|
```
|
||||||
|
|
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -1,7 +1,7 @@
|
||||||
Fixes # .
|
Fixes # .
|
||||||
|
|
||||||
Changes proposed in this pull request:
|
Changes proposed in this pull request:
|
||||||
|
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
|
10
.github/SECURITY.md
vendored
10
.github/SECURITY.md
vendored
|
@ -1,5 +1,5 @@
|
||||||
# Security policy
|
# Security policy
|
||||||
|
|
||||||
To report sensitive vulnerability information, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
|
To report sensitive vulnerability information, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
|
||||||
|
|
||||||
If your organisation/employer is a distributor of Pillow and would like advance notification of security-related bugs, please let us know your preferred contact method.
|
If your organisation/employer is a distributor of Pillow and would like advance notification of security-related bugs, please let us know your preferred contact method.
|
||||||
|
|
30
.github/mergify.yml
vendored
30
.github/mergify.yml
vendored
|
@ -1,15 +1,15 @@
|
||||||
pull_request_rules:
|
pull_request_rules:
|
||||||
- name: Automatic merge
|
- name: Automatic merge
|
||||||
conditions:
|
conditions:
|
||||||
- "#approved-reviews-by>=1"
|
- "#approved-reviews-by>=1"
|
||||||
- label=automerge
|
- label=automerge
|
||||||
- status-success=Lint
|
- status-success=Lint
|
||||||
- status-success=Test Successful
|
- status-success=Test Successful
|
||||||
- status-success=Docker Test Successful
|
- status-success=Docker Test Successful
|
||||||
- status-success=Windows Test Successful
|
- status-success=Windows Test Successful
|
||||||
- status-success=MinGW
|
- status-success=MinGW
|
||||||
- status-success=Cygwin Test Successful
|
- status-success=Cygwin Test Successful
|
||||||
- status-success=continuous-integration/appveyor/pr
|
- status-success=continuous-integration/appveyor/pr
|
||||||
actions:
|
actions:
|
||||||
merge:
|
merge:
|
||||||
method: merge
|
method: merge
|
||||||
|
|
36
.github/problem-matchers/gcc.json
vendored
36
.github/problem-matchers/gcc.json
vendored
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"__comment": "Based on vscode-cpptools' Extension/package.json gcc rule",
|
"__comment": "Based on vscode-cpptools' Extension/package.json gcc rule",
|
||||||
"problemMatcher": [
|
"problemMatcher": [
|
||||||
{
|
{
|
||||||
"owner": "gcc-problem-matcher",
|
"owner": "gcc-problem-matcher",
|
||||||
"pattern": [
|
"pattern": [
|
||||||
{
|
{
|
||||||
"regexp": "^\\s*(.*):(\\d+):(\\d+):\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
|
"regexp": "^\\s*(.*):(\\d+):(\\d+):\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
|
||||||
"file": 1,
|
"file": 1,
|
||||||
"line": 2,
|
"line": 2,
|
||||||
"column": 3,
|
"column": 3,
|
||||||
"severity": 4,
|
"severity": 4,
|
||||||
"message": 5
|
"message": 5
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
56
.github/release-drafter.yml
vendored
56
.github/release-drafter.yml
vendored
|
@ -1,28 +1,28 @@
|
||||||
name-template: "$NEXT_MINOR_VERSION"
|
name-template: "$NEXT_MINOR_VERSION"
|
||||||
tag-template: "$NEXT_MINOR_VERSION"
|
tag-template: "$NEXT_MINOR_VERSION"
|
||||||
change-template: '- $TITLE #$NUMBER [@$AUTHOR]'
|
change-template: '- $TITLE #$NUMBER [@$AUTHOR]'
|
||||||
|
|
||||||
categories:
|
categories:
|
||||||
- title: "Dependencies"
|
- title: "Dependencies"
|
||||||
label: "Dependency"
|
label: "Dependency"
|
||||||
- title: "Deprecations"
|
- title: "Deprecations"
|
||||||
label: "Deprecation"
|
label: "Deprecation"
|
||||||
- title: "Documentation"
|
- title: "Documentation"
|
||||||
label: "Documentation"
|
label: "Documentation"
|
||||||
- title: "Removals"
|
- title: "Removals"
|
||||||
label: "Removal"
|
label: "Removal"
|
||||||
- title: "Testing"
|
- title: "Testing"
|
||||||
label: "Testing"
|
label: "Testing"
|
||||||
- title: "Type hints"
|
- title: "Type hints"
|
||||||
label: "Type hints"
|
label: "Type hints"
|
||||||
|
|
||||||
exclude-labels:
|
exclude-labels:
|
||||||
- "changelog: skip"
|
- "changelog: skip"
|
||||||
|
|
||||||
template: |
|
template: |
|
||||||
|
|
||||||
https://pillow.readthedocs.io/en/stable/releasenotes/$NEXT_MINOR_VERSION.html
|
https://pillow.readthedocs.io/en/stable/releasenotes/$NEXT_MINOR_VERSION.html
|
||||||
|
|
||||||
## Changes
|
## Changes
|
||||||
|
|
||||||
$CHANGES
|
$CHANGES
|
||||||
|
|
34
.github/renovate.json
vendored
34
.github/renovate.json
vendored
|
@ -1,17 +1,17 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
"extends": [
|
"extends": [
|
||||||
"config:base"
|
"config:base"
|
||||||
],
|
],
|
||||||
"labels": [
|
"labels": [
|
||||||
"Dependency"
|
"Dependency"
|
||||||
],
|
],
|
||||||
"packageRules": [
|
"packageRules": [
|
||||||
{
|
{
|
||||||
"groupName": "github-actions",
|
"groupName": "github-actions",
|
||||||
"matchManagers": ["github-actions"],
|
"matchManagers": ["github-actions"],
|
||||||
"separateMajorMinor": "false"
|
"separateMajorMinor": "false"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"schedule": ["on the 3rd day of the month"]
|
"schedule": ["on the 3rd day of the month"]
|
||||||
}
|
}
|
||||||
|
|
120
.github/workflows/cifuzz.yml
vendored
120
.github/workflows/cifuzz.yml
vendored
|
@ -1,60 +1,60 @@
|
||||||
name: CIFuzz
|
name: CIFuzz
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "**"
|
- "**"
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/cifuzz.yml"
|
- ".github/workflows/cifuzz.yml"
|
||||||
- "**.c"
|
- "**.c"
|
||||||
- "**.h"
|
- "**.h"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/cifuzz.yml"
|
- ".github/workflows/cifuzz.yml"
|
||||||
- "**.c"
|
- "**.c"
|
||||||
- "**.h"
|
- "**.h"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Fuzzing:
|
Fuzzing:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Build Fuzzers
|
- name: Build Fuzzers
|
||||||
id: build
|
id: build
|
||||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||||
with:
|
with:
|
||||||
oss-fuzz-project-name: 'pillow'
|
oss-fuzz-project-name: 'pillow'
|
||||||
language: python
|
language: python
|
||||||
dry-run: false
|
dry-run: false
|
||||||
- name: Run Fuzzers
|
- name: Run Fuzzers
|
||||||
id: run
|
id: run
|
||||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||||
with:
|
with:
|
||||||
oss-fuzz-project-name: 'pillow'
|
oss-fuzz-project-name: 'pillow'
|
||||||
fuzz-seconds: 600
|
fuzz-seconds: 600
|
||||||
language: python
|
language: python
|
||||||
dry-run: false
|
dry-run: false
|
||||||
- name: Upload New Crash
|
- name: Upload New Crash
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
if: failure() && steps.build.outcome == 'success'
|
if: failure() && steps.build.outcome == 'success'
|
||||||
with:
|
with:
|
||||||
name: artifacts
|
name: artifacts
|
||||||
path: ./out/artifacts
|
path: ./out/artifacts
|
||||||
- name: Upload Legacy Crash
|
- name: Upload Legacy Crash
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
if: steps.run.outcome == 'success'
|
if: steps.run.outcome == 'success'
|
||||||
with:
|
with:
|
||||||
name: crash
|
name: crash
|
||||||
path: ./out/crash*
|
path: ./out/crash*
|
||||||
- name: Fail on legacy crash
|
- name: Fail on legacy crash
|
||||||
if: success()
|
if: success()
|
||||||
run: |
|
run: |
|
||||||
[ ! -e out/crash-* ]
|
[ ! -e out/crash-* ]
|
||||||
echo No legacy crash detected
|
echo No legacy crash detected
|
||||||
|
|
138
.github/workflows/docs.yml
vendored
138
.github/workflows/docs.yml
vendored
|
@ -1,69 +1,69 @@
|
||||||
name: Docs
|
name: Docs
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "**"
|
- "**"
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "src/PIL/**"
|
- "src/PIL/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "src/PIL/**"
|
- "src/PIL/**"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FORCE_COLOR: 1
|
FORCE_COLOR: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Docs
|
name: Docs
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
cache: pip
|
cache: pip
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
".ci/*.sh"
|
".ci/*.sh"
|
||||||
"pyproject.toml"
|
"pyproject.toml"
|
||||||
|
|
||||||
- name: Build system information
|
- name: Build system information
|
||||||
run: python3 .github/workflows/system-info.py
|
run: python3 .github/workflows/system-info.py
|
||||||
|
|
||||||
- name: Cache libimagequant
|
- name: Cache libimagequant
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
id: cache-libimagequant
|
id: cache-libimagequant
|
||||||
with:
|
with:
|
||||||
path: ~/cache-libimagequant
|
path: ~/cache-libimagequant
|
||||||
key: ${{ runner.os }}-libimagequant-${{ hashFiles('depends/install_imagequant.sh') }}
|
key: ${{ runner.os }}-libimagequant-${{ hashFiles('depends/install_imagequant.sh') }}
|
||||||
|
|
||||||
- name: Install Linux dependencies
|
- name: Install Linux dependencies
|
||||||
run: |
|
run: |
|
||||||
.ci/install.sh
|
.ci/install.sh
|
||||||
env:
|
env:
|
||||||
GHA_PYTHON_VERSION: "3.x"
|
GHA_PYTHON_VERSION: "3.x"
|
||||||
GHA_LIBIMAGEQUANT_CACHE_HIT: ${{ steps.cache-libimagequant.outputs.cache-hit }}
|
GHA_LIBIMAGEQUANT_CACHE_HIT: ${{ steps.cache-libimagequant.outputs.cache-hit }}
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
.ci/build.sh
|
.ci/build.sh
|
||||||
|
|
||||||
- name: Docs
|
- name: Docs
|
||||||
run: |
|
run: |
|
||||||
make doccheck
|
make doccheck
|
||||||
|
|
108
.github/workflows/lint.yml
vendored
108
.github/workflows/lint.yml
vendored
|
@ -1,54 +1,54 @@
|
||||||
name: Lint
|
name: Lint
|
||||||
|
|
||||||
on: [push, pull_request, workflow_dispatch]
|
on: [push, pull_request, workflow_dispatch]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FORCE_COLOR: 1
|
FORCE_COLOR: 1
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
name: Lint
|
name: Lint
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: pre-commit cache
|
- name: pre-commit cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/pre-commit
|
path: ~/.cache/pre-commit
|
||||||
key: lint-pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }}
|
key: lint-pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
lint-pre-commit-
|
lint-pre-commit-
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
cache: pip
|
cache: pip
|
||||||
cache-dependency-path: "setup.py"
|
cache-dependency-path: "setup.py"
|
||||||
|
|
||||||
- name: Build system information
|
- name: Build system information
|
||||||
run: python3 .github/workflows/system-info.py
|
run: python3 .github/workflows/system-info.py
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python3 -m pip install -U pip
|
python3 -m pip install -U pip
|
||||||
python3 -m pip install -U tox
|
python3 -m pip install -U tox
|
||||||
|
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: tox -e lint
|
run: tox -e lint
|
||||||
env:
|
env:
|
||||||
PRE_COMMIT_COLOR: always
|
PRE_COMMIT_COLOR: always
|
||||||
|
|
||||||
- name: Mypy
|
- name: Mypy
|
||||||
run: tox -e mypy
|
run: tox -e mypy
|
||||||
|
|
72
.github/workflows/macos-install.sh
vendored
72
.github/workflows/macos-install.sh
vendored
|
@ -1,36 +1,36 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
brew install \
|
brew install \
|
||||||
freetype \
|
freetype \
|
||||||
ghostscript \
|
ghostscript \
|
||||||
libimagequant \
|
libimagequant \
|
||||||
libjpeg \
|
libjpeg \
|
||||||
libtiff \
|
libtiff \
|
||||||
little-cms2 \
|
little-cms2 \
|
||||||
openjpeg \
|
openjpeg \
|
||||||
webp
|
webp
|
||||||
if [[ "$ImageOS" == "macos13" ]]; then
|
if [[ "$ImageOS" == "macos13" ]]; then
|
||||||
brew install --ignore-dependencies libraqm
|
brew install --ignore-dependencies libraqm
|
||||||
else
|
else
|
||||||
brew install libraqm
|
brew install libraqm
|
||||||
fi
|
fi
|
||||||
export PKG_CONFIG_PATH="/usr/local/opt/openblas/lib/pkgconfig"
|
export PKG_CONFIG_PATH="/usr/local/opt/openblas/lib/pkgconfig"
|
||||||
|
|
||||||
# TODO Update condition when cffi supports 3.13
|
# TODO Update condition when cffi supports 3.13
|
||||||
if ! [[ "$GHA_PYTHON_VERSION" == "3.13" ]]; then PYTHONOPTIMIZE=0 python3 -m pip install cffi ; fi
|
if ! [[ "$GHA_PYTHON_VERSION" == "3.13" ]]; then PYTHONOPTIMIZE=0 python3 -m pip install cffi ; fi
|
||||||
|
|
||||||
python3 -m pip install coverage
|
python3 -m pip install coverage
|
||||||
python3 -m pip install defusedxml
|
python3 -m pip install defusedxml
|
||||||
python3 -m pip install olefile
|
python3 -m pip install olefile
|
||||||
python3 -m pip install -U pytest
|
python3 -m pip install -U pytest
|
||||||
python3 -m pip install -U pytest-cov
|
python3 -m pip install -U pytest-cov
|
||||||
python3 -m pip install -U pytest-timeout
|
python3 -m pip install -U pytest-timeout
|
||||||
python3 -m pip install pyroma
|
python3 -m pip install pyroma
|
||||||
|
|
||||||
# TODO Update condition when NumPy supports 3.13
|
# TODO Update condition when NumPy supports 3.13
|
||||||
if ! [[ "$GHA_PYTHON_VERSION" == "3.13" ]]; then python3 -m pip install numpy ; fi
|
if ! [[ "$GHA_PYTHON_VERSION" == "3.13" ]]; then python3 -m pip install numpy ; fi
|
||||||
|
|
||||||
# extra test images
|
# extra test images
|
||||||
pushd depends && ./install_extra_test_images.sh && popd
|
pushd depends && ./install_extra_test_images.sh && popd
|
||||||
|
|
56
.github/workflows/release-drafter.yml
vendored
56
.github/workflows/release-drafter.yml
vendored
|
@ -1,28 +1,28 @@
|
||||||
name: Release drafter
|
name: Release drafter
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
# branches to consider in the event; optional, defaults to all
|
# branches to consider in the event; optional, defaults to all
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update_release_draft:
|
update_release_draft:
|
||||||
permissions:
|
permissions:
|
||||||
contents: write # for release-drafter/release-drafter to create a github release
|
contents: write # for release-drafter/release-drafter to create a github release
|
||||||
pull-requests: write # for release-drafter/release-drafter to add label to PR
|
pull-requests: write # for release-drafter/release-drafter to add label to PR
|
||||||
if: github.repository == 'python-pillow/Pillow'
|
if: github.repository == 'python-pillow/Pillow'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
# Drafts your next release notes as pull requests are merged into "main"
|
# Drafts your next release notes as pull requests are merged into "main"
|
||||||
- uses: release-drafter/release-drafter@v6
|
- uses: release-drafter/release-drafter@v6
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
62
.github/workflows/stale.yml
vendored
62
.github/workflows/stale.yml
vendored
|
@ -1,31 +1,31 @@
|
||||||
name: Close stale issues
|
name: Close stale issues
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "10 0 * * *"
|
- cron: "10 0 * * *"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
issues: write
|
issues: write
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
stale:
|
stale:
|
||||||
if: github.repository_owner == 'python-pillow'
|
if: github.repository_owner == 'python-pillow'
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Check issues"
|
- name: "Check issues"
|
||||||
uses: actions/stale@v9
|
uses: actions/stale@v9
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
only-labels: "Awaiting OP Action"
|
only-labels: "Awaiting OP Action"
|
||||||
close-issue-message: "Closing this issue as no feedback has been received."
|
close-issue-message: "Closing this issue as no feedback has been received."
|
||||||
days-before-stale: 7
|
days-before-stale: 7
|
||||||
days-before-issue-close: 0
|
days-before-issue-close: 0
|
||||||
days-before-pr-close: -1
|
days-before-pr-close: -1
|
||||||
labels-to-remove-when-unstale: "Awaiting OP Action"
|
labels-to-remove-when-unstale: "Awaiting OP Action"
|
||||||
|
|
56
.github/workflows/system-info.py
vendored
56
.github/workflows/system-info.py
vendored
|
@ -1,28 +1,28 @@
|
||||||
"""
|
"""
|
||||||
Print out some handy system info like Travis CI does.
|
Print out some handy system info like Travis CI does.
|
||||||
|
|
||||||
This sort of info is missing from GitHub Actions.
|
This sort of info is missing from GitHub Actions.
|
||||||
|
|
||||||
Requested here:
|
Requested here:
|
||||||
https://github.com/actions/virtual-environments/issues/79
|
https://github.com/actions/virtual-environments/issues/79
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
print("Build system information")
|
print("Build system information")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
print("sys.version\t\t", sys.version.split("\n"))
|
print("sys.version\t\t", sys.version.split("\n"))
|
||||||
print("os.name\t\t\t", os.name)
|
print("os.name\t\t\t", os.name)
|
||||||
print("sys.platform\t\t", sys.platform)
|
print("sys.platform\t\t", sys.platform)
|
||||||
print("platform.system()\t", platform.system())
|
print("platform.system()\t", platform.system())
|
||||||
print("platform.machine()\t", platform.machine())
|
print("platform.machine()\t", platform.machine())
|
||||||
print("platform.platform()\t", platform.platform())
|
print("platform.platform()\t", platform.platform())
|
||||||
print("platform.version()\t", platform.version())
|
print("platform.version()\t", platform.version())
|
||||||
print("platform.uname()\t", platform.uname())
|
print("platform.uname()\t", platform.uname())
|
||||||
if sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
print("platform.mac_ver()\t", platform.mac_ver())
|
print("platform.mac_ver()\t", platform.mac_ver())
|
||||||
|
|
302
.github/workflows/test-cygwin.yml
vendored
302
.github/workflows/test-cygwin.yml
vendored
|
@ -1,151 +1,151 @@
|
||||||
name: Test Cygwin
|
name: Test Cygwin
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "**"
|
- "**"
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- ".github/workflows/wheels*"
|
- ".github/workflows/wheels*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "wheels/**"
|
- "wheels/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- ".github/workflows/wheels*"
|
- ".github/workflows/wheels*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "wheels/**"
|
- "wheels/**"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
COVERAGE_CORE: sysmon
|
COVERAGE_CORE: sysmon
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-minor-version: [8, 9]
|
python-minor-version: [8, 9]
|
||||||
|
|
||||||
timeout-minutes: 40
|
timeout-minutes: 40
|
||||||
|
|
||||||
name: Python 3.${{ matrix.python-minor-version }}
|
name: Python 3.${{ matrix.python-minor-version }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Fix line endings
|
- name: Fix line endings
|
||||||
run: |
|
run: |
|
||||||
git config --global core.autocrlf input
|
git config --global core.autocrlf input
|
||||||
|
|
||||||
- name: Checkout Pillow
|
- name: Checkout Pillow
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Cygwin
|
- name: Install Cygwin
|
||||||
uses: cygwin/cygwin-install-action@v4
|
uses: cygwin/cygwin-install-action@v4
|
||||||
with:
|
with:
|
||||||
packages: >
|
packages: >
|
||||||
gcc-g++
|
gcc-g++
|
||||||
ghostscript
|
ghostscript
|
||||||
git
|
git
|
||||||
ImageMagick
|
ImageMagick
|
||||||
jpeg
|
jpeg
|
||||||
libfreetype-devel
|
libfreetype-devel
|
||||||
libimagequant-devel
|
libimagequant-devel
|
||||||
libjpeg-devel
|
libjpeg-devel
|
||||||
liblapack-devel
|
liblapack-devel
|
||||||
liblcms2-devel
|
liblcms2-devel
|
||||||
libopenjp2-devel
|
libopenjp2-devel
|
||||||
libraqm-devel
|
libraqm-devel
|
||||||
libtiff-devel
|
libtiff-devel
|
||||||
libwebp-devel
|
libwebp-devel
|
||||||
libxcb-devel
|
libxcb-devel
|
||||||
libxcb-xinerama0
|
libxcb-xinerama0
|
||||||
make
|
make
|
||||||
netpbm
|
netpbm
|
||||||
perl
|
perl
|
||||||
python3${{ matrix.python-minor-version }}-cffi
|
python3${{ matrix.python-minor-version }}-cffi
|
||||||
python3${{ matrix.python-minor-version }}-cython
|
python3${{ matrix.python-minor-version }}-cython
|
||||||
python3${{ matrix.python-minor-version }}-devel
|
python3${{ matrix.python-minor-version }}-devel
|
||||||
python3${{ matrix.python-minor-version }}-numpy
|
python3${{ matrix.python-minor-version }}-numpy
|
||||||
python3${{ matrix.python-minor-version }}-sip
|
python3${{ matrix.python-minor-version }}-sip
|
||||||
python3${{ matrix.python-minor-version }}-tkinter
|
python3${{ matrix.python-minor-version }}-tkinter
|
||||||
wget
|
wget
|
||||||
xorg-server-extra
|
xorg-server-extra
|
||||||
zlib-devel
|
zlib-devel
|
||||||
|
|
||||||
- name: Add Lapack to PATH
|
- name: Add Lapack to PATH
|
||||||
uses: egor-tensin/cleanup-path@v4
|
uses: egor-tensin/cleanup-path@v4
|
||||||
with:
|
with:
|
||||||
dirs: 'C:\cygwin\bin;C:\cygwin\lib\lapack'
|
dirs: 'C:\cygwin\bin;C:\cygwin\lib\lapack'
|
||||||
|
|
||||||
- name: Select Python version
|
- name: Select Python version
|
||||||
run: |
|
run: |
|
||||||
ln -sf c:/cygwin/bin/python3.${{ matrix.python-minor-version }} c:/cygwin/bin/python3
|
ln -sf c:/cygwin/bin/python3.${{ matrix.python-minor-version }} c:/cygwin/bin/python3
|
||||||
|
|
||||||
- name: pip cache
|
- name: pip cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: 'C:\cygwin\home\runneradmin\.cache\pip'
|
path: 'C:\cygwin\home\runneradmin\.cache\pip'
|
||||||
key: ${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-${{ hashFiles('.ci/install.sh') }}
|
key: ${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-${{ hashFiles('.ci/install.sh') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-
|
${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-
|
||||||
|
|
||||||
- name: Build system information
|
- name: Build system information
|
||||||
run: |
|
run: |
|
||||||
dash.exe -c "python3 .github/workflows/system-info.py"
|
dash.exe -c "python3 .github/workflows/system-info.py"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
bash.exe .ci/install.sh
|
bash.exe .ci/install.sh
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash.exe -eo pipefail -o igncr "{0}"
|
shell: bash.exe -eo pipefail -o igncr "{0}"
|
||||||
run: |
|
run: |
|
||||||
.ci/build.sh
|
.ci/build.sh
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: |
|
run: |
|
||||||
bash.exe xvfb-run -s '-screen 0 1024x768x24' .ci/test.sh
|
bash.exe xvfb-run -s '-screen 0 1024x768x24' .ci/test.sh
|
||||||
|
|
||||||
- name: Prepare to upload errors
|
- name: Prepare to upload errors
|
||||||
if: failure()
|
if: failure()
|
||||||
run: |
|
run: |
|
||||||
dash.exe -c "mkdir -p Tests/errors"
|
dash.exe -c "mkdir -p Tests/errors"
|
||||||
|
|
||||||
- name: Upload errors
|
- name: Upload errors
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: errors
|
name: errors
|
||||||
path: Tests/errors
|
path: Tests/errors
|
||||||
|
|
||||||
- name: After success
|
- name: After success
|
||||||
run: |
|
run: |
|
||||||
bash.exe .ci/after_success.sh
|
bash.exe .ci/after_success.sh
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v4
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
file: ./coverage.xml
|
file: ./coverage.xml
|
||||||
flags: GHA_Cygwin
|
flags: GHA_Cygwin
|
||||||
name: Cygwin Python 3.${{ matrix.python-minor-version }}
|
name: Cygwin Python 3.${{ matrix.python-minor-version }}
|
||||||
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
||||||
|
|
||||||
success:
|
success:
|
||||||
permissions:
|
permissions:
|
||||||
contents: none
|
contents: none
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Cygwin Test Successful
|
name: Cygwin Test Successful
|
||||||
steps:
|
steps:
|
||||||
- name: Success
|
- name: Success
|
||||||
run: echo Cygwin Test Successful
|
run: echo Cygwin Test Successful
|
||||||
|
|
236
.github/workflows/test-docker.yml
vendored
236
.github/workflows/test-docker.yml
vendored
|
@ -1,118 +1,118 @@
|
||||||
name: Test Docker
|
name: Test Docker
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "**"
|
- "**"
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- ".github/workflows/wheels*"
|
- ".github/workflows/wheels*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "wheels/**"
|
- "wheels/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- ".github/workflows/wheels*"
|
- ".github/workflows/wheels*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "wheels/**"
|
- "wheels/**"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
docker: [
|
docker: [
|
||||||
# Run slower jobs first to give them a headstart and reduce waiting time
|
# Run slower jobs first to give them a headstart and reduce waiting time
|
||||||
ubuntu-22.04-jammy-arm64v8,
|
ubuntu-22.04-jammy-arm64v8,
|
||||||
ubuntu-24.04-noble-ppc64le,
|
ubuntu-24.04-noble-ppc64le,
|
||||||
ubuntu-24.04-noble-s390x,
|
ubuntu-24.04-noble-s390x,
|
||||||
# Then run the remainder
|
# Then run the remainder
|
||||||
alpine,
|
alpine,
|
||||||
amazon-2-amd64,
|
amazon-2-amd64,
|
||||||
amazon-2023-amd64,
|
amazon-2023-amd64,
|
||||||
arch,
|
arch,
|
||||||
centos-stream-9-amd64,
|
centos-stream-9-amd64,
|
||||||
debian-11-bullseye-amd64,
|
debian-11-bullseye-amd64,
|
||||||
debian-12-bookworm-x86,
|
debian-12-bookworm-x86,
|
||||||
debian-12-bookworm-amd64,
|
debian-12-bookworm-amd64,
|
||||||
fedora-39-amd64,
|
fedora-39-amd64,
|
||||||
fedora-40-amd64,
|
fedora-40-amd64,
|
||||||
gentoo,
|
gentoo,
|
||||||
ubuntu-20.04-focal-amd64,
|
ubuntu-20.04-focal-amd64,
|
||||||
ubuntu-22.04-jammy-amd64,
|
ubuntu-22.04-jammy-amd64,
|
||||||
ubuntu-24.04-noble-amd64,
|
ubuntu-24.04-noble-amd64,
|
||||||
]
|
]
|
||||||
dockerTag: [main]
|
dockerTag: [main]
|
||||||
include:
|
include:
|
||||||
- docker: "ubuntu-22.04-jammy-arm64v8"
|
- docker: "ubuntu-22.04-jammy-arm64v8"
|
||||||
qemu-arch: "aarch64"
|
qemu-arch: "aarch64"
|
||||||
- docker: "ubuntu-24.04-noble-ppc64le"
|
- docker: "ubuntu-24.04-noble-ppc64le"
|
||||||
qemu-arch: "ppc64le"
|
qemu-arch: "ppc64le"
|
||||||
- docker: "ubuntu-24.04-noble-s390x"
|
- docker: "ubuntu-24.04-noble-s390x"
|
||||||
qemu-arch: "s390x"
|
qemu-arch: "s390x"
|
||||||
|
|
||||||
name: ${{ matrix.docker }}
|
name: ${{ matrix.docker }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build system information
|
- name: Build system information
|
||||||
run: python3 .github/workflows/system-info.py
|
run: python3 .github/workflows/system-info.py
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
if: "matrix.qemu-arch"
|
if: "matrix.qemu-arch"
|
||||||
run: |
|
run: |
|
||||||
docker run --rm --privileged aptman/qus -s -- -p ${{ matrix.qemu-arch }}
|
docker run --rm --privileged aptman/qus -s -- -p ${{ matrix.qemu-arch }}
|
||||||
|
|
||||||
- name: Docker pull
|
- name: Docker pull
|
||||||
run: |
|
run: |
|
||||||
docker pull pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
|
docker pull pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
|
||||||
|
|
||||||
- name: Docker build
|
- name: Docker build
|
||||||
run: |
|
run: |
|
||||||
# The Pillow user in the docker container is UID 1001
|
# The Pillow user in the docker container is UID 1001
|
||||||
sudo chown -R 1001 $GITHUB_WORKSPACE
|
sudo chown -R 1001 $GITHUB_WORKSPACE
|
||||||
docker run --name pillow_container -v $GITHUB_WORKSPACE:/Pillow pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
|
docker run --name pillow_container -v $GITHUB_WORKSPACE:/Pillow pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
|
||||||
sudo chown -R runner $GITHUB_WORKSPACE
|
sudo chown -R runner $GITHUB_WORKSPACE
|
||||||
|
|
||||||
- name: After success
|
- name: After success
|
||||||
run: |
|
run: |
|
||||||
PATH="$PATH:~/.local/bin"
|
PATH="$PATH:~/.local/bin"
|
||||||
docker start pillow_container
|
docker start pillow_container
|
||||||
pil_path=`docker exec pillow_container /vpy3/bin/python -c 'import os, PIL;print(os.path.realpath(os.path.dirname(PIL.__file__)))'`
|
pil_path=`docker exec pillow_container /vpy3/bin/python -c 'import os, PIL;print(os.path.realpath(os.path.dirname(PIL.__file__)))'`
|
||||||
docker stop pillow_container
|
docker stop pillow_container
|
||||||
sudo mkdir -p $pil_path
|
sudo mkdir -p $pil_path
|
||||||
sudo cp src/PIL/*.py $pil_path
|
sudo cp src/PIL/*.py $pil_path
|
||||||
.ci/after_success.sh
|
.ci/after_success.sh
|
||||||
env:
|
env:
|
||||||
MATRIX_DOCKER: ${{ matrix.docker }}
|
MATRIX_DOCKER: ${{ matrix.docker }}
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v4
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
flags: GHA_Docker
|
flags: GHA_Docker
|
||||||
name: ${{ matrix.docker }}
|
name: ${{ matrix.docker }}
|
||||||
gcov: true
|
gcov: true
|
||||||
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
||||||
|
|
||||||
success:
|
success:
|
||||||
permissions:
|
permissions:
|
||||||
contents: none
|
contents: none
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Docker Test Successful
|
name: Docker Test Successful
|
||||||
steps:
|
steps:
|
||||||
- name: Success
|
- name: Success
|
||||||
run: echo Docker Test Successful
|
run: echo Docker Test Successful
|
||||||
|
|
186
.github/workflows/test-mingw.yml
vendored
186
.github/workflows/test-mingw.yml
vendored
|
@ -1,93 +1,93 @@
|
||||||
name: Test MinGW
|
name: Test MinGW
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "**"
|
- "**"
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- ".github/workflows/wheels*"
|
- ".github/workflows/wheels*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "wheels/**"
|
- "wheels/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- ".github/workflows/wheels*"
|
- ".github/workflows/wheels*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "wheels/**"
|
- "wheels/**"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
COVERAGE_CORE: sysmon
|
COVERAGE_CORE: sysmon
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
shell: bash.exe --login -eo pipefail "{0}"
|
shell: bash.exe --login -eo pipefail "{0}"
|
||||||
env:
|
env:
|
||||||
MSYSTEM: MINGW64
|
MSYSTEM: MINGW64
|
||||||
CHERE_INVOKING: 1
|
CHERE_INVOKING: 1
|
||||||
|
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
name: "MinGW"
|
name: "MinGW"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Pillow
|
- name: Checkout Pillow
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up shell
|
- name: Set up shell
|
||||||
run: echo "C:\msys64\usr\bin\" >> $env:GITHUB_PATH
|
run: echo "C:\msys64\usr\bin\" >> $env:GITHUB_PATH
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pacman -S --noconfirm \
|
pacman -S --noconfirm \
|
||||||
mingw-w64-x86_64-freetype \
|
mingw-w64-x86_64-freetype \
|
||||||
mingw-w64-x86_64-gcc \
|
mingw-w64-x86_64-gcc \
|
||||||
mingw-w64-x86_64-ghostscript \
|
mingw-w64-x86_64-ghostscript \
|
||||||
mingw-w64-x86_64-lcms2 \
|
mingw-w64-x86_64-lcms2 \
|
||||||
mingw-w64-x86_64-libimagequant \
|
mingw-w64-x86_64-libimagequant \
|
||||||
mingw-w64-x86_64-libjpeg-turbo \
|
mingw-w64-x86_64-libjpeg-turbo \
|
||||||
mingw-w64-x86_64-libraqm \
|
mingw-w64-x86_64-libraqm \
|
||||||
mingw-w64-x86_64-libtiff \
|
mingw-w64-x86_64-libtiff \
|
||||||
mingw-w64-x86_64-libwebp \
|
mingw-w64-x86_64-libwebp \
|
||||||
mingw-w64-x86_64-openjpeg2 \
|
mingw-w64-x86_64-openjpeg2 \
|
||||||
mingw-w64-x86_64-python3-cffi \
|
mingw-w64-x86_64-python3-cffi \
|
||||||
mingw-w64-x86_64-python3-numpy \
|
mingw-w64-x86_64-python3-numpy \
|
||||||
mingw-w64-x86_64-python3-olefile \
|
mingw-w64-x86_64-python3-olefile \
|
||||||
mingw-w64-x86_64-python3-setuptools \
|
mingw-w64-x86_64-python3-setuptools \
|
||||||
mingw-w64-x86_64-python-pyqt6
|
mingw-w64-x86_64-python-pyqt6
|
||||||
|
|
||||||
python3 -m ensurepip
|
python3 -m ensurepip
|
||||||
python3 -m pip install pyroma pytest pytest-cov pytest-timeout
|
python3 -m pip install pyroma pytest pytest-cov pytest-timeout
|
||||||
|
|
||||||
pushd depends && ./install_extra_test_images.sh && popd
|
pushd depends && ./install_extra_test_images.sh && popd
|
||||||
|
|
||||||
- name: Build Pillow
|
- name: Build Pillow
|
||||||
run: SETUPTOOLS_USE_DISTUTILS="stdlib" CFLAGS="-coverage" python3 -m pip install .
|
run: SETUPTOOLS_USE_DISTUTILS="stdlib" CFLAGS="-coverage" python3 -m pip install .
|
||||||
|
|
||||||
- name: Test Pillow
|
- name: Test Pillow
|
||||||
run: |
|
run: |
|
||||||
python3 selftest.py --installed
|
python3 selftest.py --installed
|
||||||
python3 -c "from PIL import Image"
|
python3 -c "from PIL import Image"
|
||||||
python3 -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests
|
python3 -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v4
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
file: ./coverage.xml
|
file: ./coverage.xml
|
||||||
flags: GHA_Windows
|
flags: GHA_Windows
|
||||||
name: "MSYS2 MinGW"
|
name: "MSYS2 MinGW"
|
||||||
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
||||||
|
|
112
.github/workflows/test-valgrind.yml
vendored
112
.github/workflows/test-valgrind.yml
vendored
|
@ -1,56 +1,56 @@
|
||||||
name: Test Valgrind
|
name: Test Valgrind
|
||||||
|
|
||||||
# like the Docker tests, but running valgrind only on *.c/*.h changes.
|
# like the Docker tests, but running valgrind only on *.c/*.h changes.
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "**"
|
- "**"
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/test-valgrind.yml"
|
- ".github/workflows/test-valgrind.yml"
|
||||||
- "**.c"
|
- "**.c"
|
||||||
- "**.h"
|
- "**.h"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/test-valgrind.yml"
|
- ".github/workflows/test-valgrind.yml"
|
||||||
- "**.c"
|
- "**.c"
|
||||||
- "**.h"
|
- "**.h"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
docker: [
|
docker: [
|
||||||
ubuntu-22.04-jammy-amd64-valgrind,
|
ubuntu-22.04-jammy-amd64-valgrind,
|
||||||
]
|
]
|
||||||
dockerTag: [main]
|
dockerTag: [main]
|
||||||
|
|
||||||
name: ${{ matrix.docker }}
|
name: ${{ matrix.docker }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build system information
|
- name: Build system information
|
||||||
run: python3 .github/workflows/system-info.py
|
run: python3 .github/workflows/system-info.py
|
||||||
|
|
||||||
- name: Docker pull
|
- name: Docker pull
|
||||||
run: |
|
run: |
|
||||||
docker pull pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
|
docker pull pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
|
||||||
|
|
||||||
- name: Build and Run Valgrind
|
- name: Build and Run Valgrind
|
||||||
run: |
|
run: |
|
||||||
# The Pillow user in the docker container is UID 1001
|
# The Pillow user in the docker container is UID 1001
|
||||||
sudo chown -R 1001 $GITHUB_WORKSPACE
|
sudo chown -R 1001 $GITHUB_WORKSPACE
|
||||||
docker run --name pillow_container -e "PILLOW_VALGRIND_TEST=true" -v $GITHUB_WORKSPACE:/Pillow pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
|
docker run --name pillow_container -e "PILLOW_VALGRIND_TEST=true" -v $GITHUB_WORKSPACE:/Pillow pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
|
||||||
sudo chown -R runner $GITHUB_WORKSPACE
|
sudo chown -R runner $GITHUB_WORKSPACE
|
||||||
|
|
462
.github/workflows/test-windows.yml
vendored
462
.github/workflows/test-windows.yml
vendored
|
@ -1,231 +1,231 @@
|
||||||
name: Test Windows
|
name: Test Windows
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "**"
|
- "**"
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- ".github/workflows/wheels*"
|
- ".github/workflows/wheels*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "wheels/**"
|
- "wheels/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- ".github/workflows/wheels*"
|
- ".github/workflows/wheels*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "wheels/**"
|
- "wheels/**"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
COVERAGE_CORE: sysmon
|
COVERAGE_CORE: sysmon
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ["pypy3.10", "pypy3.9", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
|
python-version: ["pypy3.10", "pypy3.9", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||||
|
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
|
|
||||||
name: Python ${{ matrix.python-version }}
|
name: Python ${{ matrix.python-version }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Pillow
|
- name: Checkout Pillow
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Checkout cached dependencies
|
- name: Checkout cached dependencies
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: python-pillow/pillow-depends
|
repository: python-pillow/pillow-depends
|
||||||
path: winbuild\depends
|
path: winbuild\depends
|
||||||
|
|
||||||
- name: Checkout extra test images
|
- name: Checkout extra test images
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: python-pillow/test-images
|
repository: python-pillow/test-images
|
||||||
path: Tests\test-images
|
path: Tests\test-images
|
||||||
|
|
||||||
# sets env: pythonLocation
|
# sets env: pythonLocation
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
allow-prereleases: true
|
allow-prereleases: true
|
||||||
cache: pip
|
cache: pip
|
||||||
cache-dependency-path: ".github/workflows/test-windows.yml"
|
cache-dependency-path: ".github/workflows/test-windows.yml"
|
||||||
|
|
||||||
- name: Print build system information
|
- name: Print build system information
|
||||||
run: python3 .github/workflows/system-info.py
|
run: python3 .github/workflows/system-info.py
|
||||||
|
|
||||||
- name: Install Python dependencies
|
- name: Install Python dependencies
|
||||||
run: >
|
run: >
|
||||||
python3 -m pip install
|
python3 -m pip install
|
||||||
coverage>=7.4.2
|
coverage>=7.4.2
|
||||||
defusedxml
|
defusedxml
|
||||||
olefile
|
olefile
|
||||||
pyroma
|
pyroma
|
||||||
pytest
|
pytest
|
||||||
pytest-cov
|
pytest-cov
|
||||||
pytest-timeout
|
pytest-timeout
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
id: install
|
id: install
|
||||||
run: |
|
run: |
|
||||||
choco install nasm --no-progress
|
choco install nasm --no-progress
|
||||||
echo "C:\Program Files\NASM" >> $env:GITHUB_PATH
|
echo "C:\Program Files\NASM" >> $env:GITHUB_PATH
|
||||||
|
|
||||||
choco install ghostscript --version=10.3.1 --no-progress
|
choco install ghostscript --version=10.3.1 --no-progress
|
||||||
echo "C:\Program Files\gs\gs10.00.0\bin" >> $env:GITHUB_PATH
|
echo "C:\Program Files\gs\gs10.00.0\bin" >> $env:GITHUB_PATH
|
||||||
|
|
||||||
# Install extra test images
|
# Install extra test images
|
||||||
xcopy /S /Y Tests\test-images\* Tests\images
|
xcopy /S /Y Tests\test-images\* Tests\images
|
||||||
|
|
||||||
# make cache key depend on VS version
|
# make cache key depend on VS version
|
||||||
& "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" `
|
& "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" `
|
||||||
| find """catalog_buildVersion""" `
|
| find """catalog_buildVersion""" `
|
||||||
| ForEach-Object { $a = $_.split(" ")[1]; echo "vs=$a" >> $env:GITHUB_OUTPUT }
|
| ForEach-Object { $a = $_.split(" ")[1]; echo "vs=$a" >> $env:GITHUB_OUTPUT }
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
- name: Cache build
|
- name: Cache build
|
||||||
id: build-cache
|
id: build-cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: winbuild\build
|
path: winbuild\build
|
||||||
key:
|
key:
|
||||||
${{ hashFiles('winbuild\build_prepare.py') }}-${{ hashFiles('.github\workflows\test-windows.yml') }}-${{ env.pythonLocation }}-${{ steps.install.outputs.vs }}
|
${{ hashFiles('winbuild\build_prepare.py') }}-${{ hashFiles('.github\workflows\test-windows.yml') }}-${{ env.pythonLocation }}-${{ steps.install.outputs.vs }}
|
||||||
|
|
||||||
- name: Prepare build
|
- name: Prepare build
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
& python.exe winbuild\build_prepare.py -v
|
& python.exe winbuild\build_prepare.py -v
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
- name: Build dependencies / libjpeg-turbo
|
- name: Build dependencies / libjpeg-turbo
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_libjpeg.cmd"
|
run: "& winbuild\\build\\build_dep_libjpeg.cmd"
|
||||||
|
|
||||||
- name: Build dependencies / zlib
|
- name: Build dependencies / zlib
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_zlib.cmd"
|
run: "& winbuild\\build\\build_dep_zlib.cmd"
|
||||||
|
|
||||||
- name: Build dependencies / xz
|
- name: Build dependencies / xz
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_xz.cmd"
|
run: "& winbuild\\build\\build_dep_xz.cmd"
|
||||||
|
|
||||||
- name: Build dependencies / WebP
|
- name: Build dependencies / WebP
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_libwebp.cmd"
|
run: "& winbuild\\build\\build_dep_libwebp.cmd"
|
||||||
|
|
||||||
- name: Build dependencies / LibTiff
|
- name: Build dependencies / LibTiff
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_libtiff.cmd"
|
run: "& winbuild\\build\\build_dep_libtiff.cmd"
|
||||||
|
|
||||||
# for FreeType CBDT/SBIX font support
|
# for FreeType CBDT/SBIX font support
|
||||||
- name: Build dependencies / libpng
|
- name: Build dependencies / libpng
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_libpng.cmd"
|
run: "& winbuild\\build\\build_dep_libpng.cmd"
|
||||||
|
|
||||||
# for FreeType WOFF2 font support
|
# for FreeType WOFF2 font support
|
||||||
- name: Build dependencies / brotli
|
- name: Build dependencies / brotli
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_brotli.cmd"
|
run: "& winbuild\\build\\build_dep_brotli.cmd"
|
||||||
|
|
||||||
- name: Build dependencies / FreeType
|
- name: Build dependencies / FreeType
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_freetype.cmd"
|
run: "& winbuild\\build\\build_dep_freetype.cmd"
|
||||||
|
|
||||||
- name: Build dependencies / LCMS2
|
- name: Build dependencies / LCMS2
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_lcms2.cmd"
|
run: "& winbuild\\build\\build_dep_lcms2.cmd"
|
||||||
|
|
||||||
- name: Build dependencies / OpenJPEG
|
- name: Build dependencies / OpenJPEG
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_openjpeg.cmd"
|
run: "& winbuild\\build\\build_dep_openjpeg.cmd"
|
||||||
|
|
||||||
# GPL licensed
|
# GPL licensed
|
||||||
- name: Build dependencies / libimagequant
|
- name: Build dependencies / libimagequant
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_libimagequant.cmd"
|
run: "& winbuild\\build\\build_dep_libimagequant.cmd"
|
||||||
|
|
||||||
# Raqm dependencies
|
# Raqm dependencies
|
||||||
- name: Build dependencies / HarfBuzz
|
- name: Build dependencies / HarfBuzz
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_harfbuzz.cmd"
|
run: "& winbuild\\build\\build_dep_harfbuzz.cmd"
|
||||||
|
|
||||||
# Raqm dependencies
|
# Raqm dependencies
|
||||||
- name: Build dependencies / FriBidi
|
- name: Build dependencies / FriBidi
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_fribidi.cmd"
|
run: "& winbuild\\build\\build_dep_fribidi.cmd"
|
||||||
|
|
||||||
# trim ~150MB for each job
|
# trim ~150MB for each job
|
||||||
- name: Optimize build cache
|
- name: Optimize build cache
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: rmdir /S /Q winbuild\build\src
|
run: rmdir /S /Q winbuild\build\src
|
||||||
shell: cmd
|
shell: cmd
|
||||||
|
|
||||||
- name: Build Pillow
|
- name: Build Pillow
|
||||||
run: |
|
run: |
|
||||||
$FLAGS="-C raqm=vendor -C fribidi=vendor"
|
$FLAGS="-C raqm=vendor -C fribidi=vendor"
|
||||||
cmd /c "winbuild\build\build_env.cmd && $env:pythonLocation\python.exe -m pip install -v $FLAGS ."
|
cmd /c "winbuild\build\build_env.cmd && $env:pythonLocation\python.exe -m pip install -v $FLAGS ."
|
||||||
& $env:pythonLocation\python.exe selftest.py --installed
|
& $env:pythonLocation\python.exe selftest.py --installed
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
# skip PyPy for speed
|
# skip PyPy for speed
|
||||||
- name: Enable heap verification
|
- name: Enable heap verification
|
||||||
if: "!contains(matrix.python-version, 'pypy')"
|
if: "!contains(matrix.python-version, 'pypy')"
|
||||||
run: |
|
run: |
|
||||||
& reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\python.exe" /v "GlobalFlag" /t REG_SZ /d "0x02000000" /f
|
& reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\python.exe" /v "GlobalFlag" /t REG_SZ /d "0x02000000" /f
|
||||||
|
|
||||||
- name: Test Pillow
|
- name: Test Pillow
|
||||||
run: |
|
run: |
|
||||||
path %GITHUB_WORKSPACE%\\winbuild\\build\\bin;%PATH%
|
path %GITHUB_WORKSPACE%\\winbuild\\build\\bin;%PATH%
|
||||||
python.exe -m pytest -vx -W always --cov PIL --cov Tests --cov-report term --cov-report xml Tests
|
python.exe -m pytest -vx -W always --cov PIL --cov Tests --cov-report term --cov-report xml Tests
|
||||||
shell: cmd
|
shell: cmd
|
||||||
|
|
||||||
- name: Prepare to upload errors
|
- name: Prepare to upload errors
|
||||||
if: failure()
|
if: failure()
|
||||||
run: |
|
run: |
|
||||||
mkdir -p Tests/errors
|
mkdir -p Tests/errors
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Upload errors
|
- name: Upload errors
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: errors
|
name: errors
|
||||||
path: Tests/errors
|
path: Tests/errors
|
||||||
|
|
||||||
- name: After success
|
- name: After success
|
||||||
run: |
|
run: |
|
||||||
.ci/after_success.sh
|
.ci/after_success.sh
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v4
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
file: ./coverage.xml
|
file: ./coverage.xml
|
||||||
flags: GHA_Windows
|
flags: GHA_Windows
|
||||||
name: ${{ runner.os }} Python ${{ matrix.python-version }}
|
name: ${{ runner.os }} Python ${{ matrix.python-version }}
|
||||||
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
||||||
|
|
||||||
success:
|
success:
|
||||||
permissions:
|
permissions:
|
||||||
contents: none
|
contents: none
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Windows Test Successful
|
name: Windows Test Successful
|
||||||
steps:
|
steps:
|
||||||
- name: Success
|
- name: Success
|
||||||
run: echo Windows Test Successful
|
run: echo Windows Test Successful
|
||||||
|
|
336
.github/workflows/test.yml
vendored
336
.github/workflows/test.yml
vendored
|
@ -1,168 +1,168 @@
|
||||||
name: Test
|
name: Test
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "**"
|
- "**"
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- ".github/workflows/wheels*"
|
- ".github/workflows/wheels*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "wheels/**"
|
- "wheels/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
- ".github/workflows/wheels*"
|
- ".github/workflows/wheels*"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "wheels/**"
|
- "wheels/**"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
COVERAGE_CORE: sysmon
|
COVERAGE_CORE: sysmon
|
||||||
FORCE_COLOR: 1
|
FORCE_COLOR: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [
|
os: [
|
||||||
"macos-14",
|
"macos-14",
|
||||||
"ubuntu-latest",
|
"ubuntu-latest",
|
||||||
]
|
]
|
||||||
python-version: [
|
python-version: [
|
||||||
"pypy3.10",
|
"pypy3.10",
|
||||||
"pypy3.9",
|
"pypy3.9",
|
||||||
"3.13",
|
"3.13",
|
||||||
"3.12",
|
"3.12",
|
||||||
"3.11",
|
"3.11",
|
||||||
"3.10",
|
"3.10",
|
||||||
"3.9",
|
"3.9",
|
||||||
"3.8",
|
"3.8",
|
||||||
]
|
]
|
||||||
include:
|
include:
|
||||||
- python-version: "3.11"
|
- python-version: "3.11"
|
||||||
PYTHONOPTIMIZE: 1
|
PYTHONOPTIMIZE: 1
|
||||||
REVERSE: "--reverse"
|
REVERSE: "--reverse"
|
||||||
- python-version: "3.10"
|
- python-version: "3.10"
|
||||||
PYTHONOPTIMIZE: 2
|
PYTHONOPTIMIZE: 2
|
||||||
# M1 only available for 3.10+
|
# M1 only available for 3.10+
|
||||||
- os: "macos-13"
|
- os: "macos-13"
|
||||||
python-version: "3.9"
|
python-version: "3.9"
|
||||||
- os: "macos-13"
|
- os: "macos-13"
|
||||||
python-version: "3.8"
|
python-version: "3.8"
|
||||||
exclude:
|
exclude:
|
||||||
- os: "macos-14"
|
- os: "macos-14"
|
||||||
python-version: "3.9"
|
python-version: "3.9"
|
||||||
- os: "macos-14"
|
- os: "macos-14"
|
||||||
python-version: "3.8"
|
python-version: "3.8"
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
|
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
allow-prereleases: true
|
allow-prereleases: true
|
||||||
cache: pip
|
cache: pip
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
".ci/*.sh"
|
".ci/*.sh"
|
||||||
"pyproject.toml"
|
"pyproject.toml"
|
||||||
|
|
||||||
- name: Build system information
|
- name: Build system information
|
||||||
run: python3 .github/workflows/system-info.py
|
run: python3 .github/workflows/system-info.py
|
||||||
|
|
||||||
- name: Cache libimagequant
|
- name: Cache libimagequant
|
||||||
if: startsWith(matrix.os, 'ubuntu')
|
if: startsWith(matrix.os, 'ubuntu')
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
id: cache-libimagequant
|
id: cache-libimagequant
|
||||||
with:
|
with:
|
||||||
path: ~/cache-libimagequant
|
path: ~/cache-libimagequant
|
||||||
key: ${{ runner.os }}-libimagequant-${{ hashFiles('depends/install_imagequant.sh') }}
|
key: ${{ runner.os }}-libimagequant-${{ hashFiles('depends/install_imagequant.sh') }}
|
||||||
|
|
||||||
- name: Install Linux dependencies
|
- name: Install Linux dependencies
|
||||||
if: startsWith(matrix.os, 'ubuntu')
|
if: startsWith(matrix.os, 'ubuntu')
|
||||||
run: |
|
run: |
|
||||||
.ci/install.sh
|
.ci/install.sh
|
||||||
env:
|
env:
|
||||||
GHA_PYTHON_VERSION: ${{ matrix.python-version }}
|
GHA_PYTHON_VERSION: ${{ matrix.python-version }}
|
||||||
GHA_LIBIMAGEQUANT_CACHE_HIT: ${{ steps.cache-libimagequant.outputs.cache-hit }}
|
GHA_LIBIMAGEQUANT_CACHE_HIT: ${{ steps.cache-libimagequant.outputs.cache-hit }}
|
||||||
|
|
||||||
- name: Install macOS dependencies
|
- name: Install macOS dependencies
|
||||||
if: startsWith(matrix.os, 'macOS')
|
if: startsWith(matrix.os, 'macOS')
|
||||||
run: |
|
run: |
|
||||||
.github/workflows/macos-install.sh
|
.github/workflows/macos-install.sh
|
||||||
env:
|
env:
|
||||||
GHA_PYTHON_VERSION: ${{ matrix.python-version }}
|
GHA_PYTHON_VERSION: ${{ matrix.python-version }}
|
||||||
|
|
||||||
- name: Register gcc problem matcher
|
- name: Register gcc problem matcher
|
||||||
if: "matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'"
|
if: "matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'"
|
||||||
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
.ci/build.sh
|
.ci/build.sh
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: |
|
run: |
|
||||||
if [ $REVERSE ]; then
|
if [ $REVERSE ]; then
|
||||||
python3 -m pip install pytest-reverse
|
python3 -m pip install pytest-reverse
|
||||||
fi
|
fi
|
||||||
if [ "${{ matrix.os }}" = "ubuntu-latest" ]; then
|
if [ "${{ matrix.os }}" = "ubuntu-latest" ]; then
|
||||||
xvfb-run -s '-screen 0 1024x768x24' sway&
|
xvfb-run -s '-screen 0 1024x768x24' sway&
|
||||||
export WAYLAND_DISPLAY=wayland-1
|
export WAYLAND_DISPLAY=wayland-1
|
||||||
.ci/test.sh
|
.ci/test.sh
|
||||||
else
|
else
|
||||||
.ci/test.sh
|
.ci/test.sh
|
||||||
fi
|
fi
|
||||||
env:
|
env:
|
||||||
PYTHONOPTIMIZE: ${{ matrix.PYTHONOPTIMIZE }}
|
PYTHONOPTIMIZE: ${{ matrix.PYTHONOPTIMIZE }}
|
||||||
REVERSE: ${{ matrix.REVERSE }}
|
REVERSE: ${{ matrix.REVERSE }}
|
||||||
|
|
||||||
- name: Prepare to upload errors
|
- name: Prepare to upload errors
|
||||||
if: failure()
|
if: failure()
|
||||||
run: |
|
run: |
|
||||||
mkdir -p Tests/errors
|
mkdir -p Tests/errors
|
||||||
|
|
||||||
- name: Upload errors
|
- name: Upload errors
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: errors
|
name: errors
|
||||||
path: Tests/errors
|
path: Tests/errors
|
||||||
|
|
||||||
- name: After success
|
- name: After success
|
||||||
run: |
|
run: |
|
||||||
.ci/after_success.sh
|
.ci/after_success.sh
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v4
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
flags: ${{ matrix.os == 'ubuntu-latest' && 'GHA_Ubuntu' || 'GHA_macOS' }}
|
flags: ${{ matrix.os == 'ubuntu-latest' && 'GHA_Ubuntu' || 'GHA_macOS' }}
|
||||||
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
|
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
|
||||||
gcov: true
|
gcov: true
|
||||||
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
||||||
|
|
||||||
success:
|
success:
|
||||||
permissions:
|
permissions:
|
||||||
contents: none
|
contents: none
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Test Successful
|
name: Test Successful
|
||||||
steps:
|
steps:
|
||||||
- name: Success
|
- name: Success
|
||||||
run: echo Test Successful
|
run: echo Test Successful
|
||||||
|
|
304
.github/workflows/wheels-dependencies.sh
vendored
304
.github/workflows/wheels-dependencies.sh
vendored
|
@ -1,152 +1,152 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Define custom utilities
|
# Define custom utilities
|
||||||
# Test for macOS with [ -n "$IS_MACOS" ]
|
# Test for macOS with [ -n "$IS_MACOS" ]
|
||||||
if [ -z "$IS_MACOS" ]; then
|
if [ -z "$IS_MACOS" ]; then
|
||||||
export MB_ML_LIBC=${AUDITWHEEL_POLICY::9}
|
export MB_ML_LIBC=${AUDITWHEEL_POLICY::9}
|
||||||
export MB_ML_VER=${AUDITWHEEL_POLICY:9}
|
export MB_ML_VER=${AUDITWHEEL_POLICY:9}
|
||||||
fi
|
fi
|
||||||
export PLAT=$CIBW_ARCHS
|
export PLAT=$CIBW_ARCHS
|
||||||
source wheels/multibuild/common_utils.sh
|
source wheels/multibuild/common_utils.sh
|
||||||
source wheels/multibuild/library_builders.sh
|
source wheels/multibuild/library_builders.sh
|
||||||
if [ -z "$IS_MACOS" ]; then
|
if [ -z "$IS_MACOS" ]; then
|
||||||
source wheels/multibuild/manylinux_utils.sh
|
source wheels/multibuild/manylinux_utils.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ARCHIVE_SDIR=pillow-depends-main
|
ARCHIVE_SDIR=pillow-depends-main
|
||||||
|
|
||||||
# Package versions for fresh source builds
|
# Package versions for fresh source builds
|
||||||
FREETYPE_VERSION=2.13.2
|
FREETYPE_VERSION=2.13.2
|
||||||
HARFBUZZ_VERSION=8.5.0
|
HARFBUZZ_VERSION=8.5.0
|
||||||
LIBPNG_VERSION=1.6.43
|
LIBPNG_VERSION=1.6.43
|
||||||
JPEGTURBO_VERSION=3.0.3
|
JPEGTURBO_VERSION=3.0.3
|
||||||
OPENJPEG_VERSION=2.5.2
|
OPENJPEG_VERSION=2.5.2
|
||||||
XZ_VERSION=5.4.5
|
XZ_VERSION=5.4.5
|
||||||
TIFF_VERSION=4.6.0
|
TIFF_VERSION=4.6.0
|
||||||
LCMS2_VERSION=2.16
|
LCMS2_VERSION=2.16
|
||||||
if [[ -n "$IS_MACOS" ]]; then
|
if [[ -n "$IS_MACOS" ]]; then
|
||||||
GIFLIB_VERSION=5.2.2
|
GIFLIB_VERSION=5.2.2
|
||||||
else
|
else
|
||||||
GIFLIB_VERSION=5.2.1
|
GIFLIB_VERSION=5.2.1
|
||||||
fi
|
fi
|
||||||
if [[ -n "$IS_MACOS" ]] || [[ "$MB_ML_VER" != 2014 ]]; then
|
if [[ -n "$IS_MACOS" ]] || [[ "$MB_ML_VER" != 2014 ]]; then
|
||||||
ZLIB_VERSION=1.3.1
|
ZLIB_VERSION=1.3.1
|
||||||
else
|
else
|
||||||
ZLIB_VERSION=1.2.8
|
ZLIB_VERSION=1.2.8
|
||||||
fi
|
fi
|
||||||
LIBWEBP_VERSION=1.4.0
|
LIBWEBP_VERSION=1.4.0
|
||||||
BZIP2_VERSION=1.0.8
|
BZIP2_VERSION=1.0.8
|
||||||
LIBXCB_VERSION=1.17.0
|
LIBXCB_VERSION=1.17.0
|
||||||
BROTLI_VERSION=1.1.0
|
BROTLI_VERSION=1.1.0
|
||||||
|
|
||||||
if [[ -n "$IS_MACOS" ]] && [[ "$CIBW_ARCHS" == "x86_64" ]]; then
|
if [[ -n "$IS_MACOS" ]] && [[ "$CIBW_ARCHS" == "x86_64" ]]; then
|
||||||
function build_openjpeg {
|
function build_openjpeg {
|
||||||
local out_dir=$(fetch_unpack https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz openjpeg-${OPENJPEG_VERSION}.tar.gz)
|
local out_dir=$(fetch_unpack https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz openjpeg-${OPENJPEG_VERSION}.tar.gz)
|
||||||
(cd $out_dir \
|
(cd $out_dir \
|
||||||
&& cmake -DCMAKE_INSTALL_PREFIX=$BUILD_PREFIX -DCMAKE_INSTALL_NAME_DIR=$BUILD_PREFIX/lib . \
|
&& cmake -DCMAKE_INSTALL_PREFIX=$BUILD_PREFIX -DCMAKE_INSTALL_NAME_DIR=$BUILD_PREFIX/lib . \
|
||||||
&& make install)
|
&& make install)
|
||||||
touch openjpeg-stamp
|
touch openjpeg-stamp
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
function build_brotli {
|
function build_brotli {
|
||||||
local cmake=$(get_modern_cmake)
|
local cmake=$(get_modern_cmake)
|
||||||
local out_dir=$(fetch_unpack https://github.com/google/brotli/archive/v$BROTLI_VERSION.tar.gz brotli-1.1.0.tar.gz)
|
local out_dir=$(fetch_unpack https://github.com/google/brotli/archive/v$BROTLI_VERSION.tar.gz brotli-1.1.0.tar.gz)
|
||||||
(cd $out_dir \
|
(cd $out_dir \
|
||||||
&& $cmake -DCMAKE_INSTALL_PREFIX=$BUILD_PREFIX -DCMAKE_INSTALL_NAME_DIR=$BUILD_PREFIX/lib . \
|
&& $cmake -DCMAKE_INSTALL_PREFIX=$BUILD_PREFIX -DCMAKE_INSTALL_NAME_DIR=$BUILD_PREFIX/lib . \
|
||||||
&& make install)
|
&& make install)
|
||||||
if [[ "$MB_ML_LIBC" == "manylinux" ]]; then
|
if [[ "$MB_ML_LIBC" == "manylinux" ]]; then
|
||||||
cp /usr/local/lib64/libbrotli* /usr/local/lib
|
cp /usr/local/lib64/libbrotli* /usr/local/lib
|
||||||
cp /usr/local/lib64/pkgconfig/libbrotli* /usr/local/lib/pkgconfig
|
cp /usr/local/lib64/pkgconfig/libbrotli* /usr/local/lib/pkgconfig
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function build {
|
function build {
|
||||||
if [[ -n "$IS_MACOS" ]] && [[ "$CIBW_ARCHS" == "arm64" ]]; then
|
if [[ -n "$IS_MACOS" ]] && [[ "$CIBW_ARCHS" == "arm64" ]]; then
|
||||||
sudo chown -R runner /usr/local
|
sudo chown -R runner /usr/local
|
||||||
fi
|
fi
|
||||||
build_xz
|
build_xz
|
||||||
if [ -z "$IS_ALPINE" ] && [ -z "$IS_MACOS" ]; then
|
if [ -z "$IS_ALPINE" ] && [ -z "$IS_MACOS" ]; then
|
||||||
yum remove -y zlib-devel
|
yum remove -y zlib-devel
|
||||||
fi
|
fi
|
||||||
build_new_zlib
|
build_new_zlib
|
||||||
|
|
||||||
build_simple xcb-proto 1.17.0 https://xorg.freedesktop.org/archive/individual/proto
|
build_simple xcb-proto 1.17.0 https://xorg.freedesktop.org/archive/individual/proto
|
||||||
if [ -n "$IS_MACOS" ]; then
|
if [ -n "$IS_MACOS" ]; then
|
||||||
build_simple xorgproto 2024.1 https://www.x.org/pub/individual/proto
|
build_simple xorgproto 2024.1 https://www.x.org/pub/individual/proto
|
||||||
build_simple libXau 1.0.11 https://www.x.org/pub/individual/lib
|
build_simple libXau 1.0.11 https://www.x.org/pub/individual/lib
|
||||||
build_simple libpthread-stubs 0.5 https://xcb.freedesktop.org/dist
|
build_simple libpthread-stubs 0.5 https://xcb.freedesktop.org/dist
|
||||||
if [[ "$CIBW_ARCHS" == "arm64" ]]; then
|
if [[ "$CIBW_ARCHS" == "arm64" ]]; then
|
||||||
cp /usr/local/share/pkgconfig/xcb-proto.pc /usr/local/lib/pkgconfig
|
cp /usr/local/share/pkgconfig/xcb-proto.pc /usr/local/lib/pkgconfig
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
sed s/\${pc_sysrootdir\}// /usr/local/share/pkgconfig/xcb-proto.pc > /usr/local/lib/pkgconfig/xcb-proto.pc
|
sed s/\${pc_sysrootdir\}// /usr/local/share/pkgconfig/xcb-proto.pc > /usr/local/lib/pkgconfig/xcb-proto.pc
|
||||||
fi
|
fi
|
||||||
build_simple libxcb $LIBXCB_VERSION https://www.x.org/releases/individual/lib
|
build_simple libxcb $LIBXCB_VERSION https://www.x.org/releases/individual/lib
|
||||||
|
|
||||||
build_libjpeg_turbo
|
build_libjpeg_turbo
|
||||||
build_tiff
|
build_tiff
|
||||||
build_libpng
|
build_libpng
|
||||||
build_lcms2
|
build_lcms2
|
||||||
build_openjpeg
|
build_openjpeg
|
||||||
if [ -f /usr/local/lib64/libopenjp2.so ]; then
|
if [ -f /usr/local/lib64/libopenjp2.so ]; then
|
||||||
cp /usr/local/lib64/libopenjp2.so /usr/local/lib
|
cp /usr/local/lib64/libopenjp2.so /usr/local/lib
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ORIGINAL_CFLAGS=$CFLAGS
|
ORIGINAL_CFLAGS=$CFLAGS
|
||||||
CFLAGS="$CFLAGS -O3 -DNDEBUG"
|
CFLAGS="$CFLAGS -O3 -DNDEBUG"
|
||||||
if [[ -n "$IS_MACOS" ]]; then
|
if [[ -n "$IS_MACOS" ]]; then
|
||||||
CFLAGS="$CFLAGS -Wl,-headerpad_max_install_names"
|
CFLAGS="$CFLAGS -Wl,-headerpad_max_install_names"
|
||||||
fi
|
fi
|
||||||
build_libwebp
|
build_libwebp
|
||||||
CFLAGS=$ORIGINAL_CFLAGS
|
CFLAGS=$ORIGINAL_CFLAGS
|
||||||
|
|
||||||
build_brotli
|
build_brotli
|
||||||
|
|
||||||
if [ -n "$IS_MACOS" ]; then
|
if [ -n "$IS_MACOS" ]; then
|
||||||
# Custom freetype build
|
# Custom freetype build
|
||||||
build_simple freetype $FREETYPE_VERSION https://download.savannah.gnu.org/releases/freetype tar.gz --with-harfbuzz=no
|
build_simple freetype $FREETYPE_VERSION https://download.savannah.gnu.org/releases/freetype tar.gz --with-harfbuzz=no
|
||||||
else
|
else
|
||||||
build_freetype
|
build_freetype
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$IS_MACOS" ]; then
|
if [ -z "$IS_MACOS" ]; then
|
||||||
export FREETYPE_LIBS=-lfreetype
|
export FREETYPE_LIBS=-lfreetype
|
||||||
export FREETYPE_CFLAGS=-I/usr/local/include/freetype2/
|
export FREETYPE_CFLAGS=-I/usr/local/include/freetype2/
|
||||||
fi
|
fi
|
||||||
build_simple harfbuzz $HARFBUZZ_VERSION https://github.com/harfbuzz/harfbuzz/releases/download/$HARFBUZZ_VERSION tar.xz --with-freetype=yes --with-glib=no
|
build_simple harfbuzz $HARFBUZZ_VERSION https://github.com/harfbuzz/harfbuzz/releases/download/$HARFBUZZ_VERSION tar.xz --with-freetype=yes --with-glib=no
|
||||||
if [ -z "$IS_MACOS" ]; then
|
if [ -z "$IS_MACOS" ]; then
|
||||||
export FREETYPE_LIBS=""
|
export FREETYPE_LIBS=""
|
||||||
export FREETYPE_CFLAGS=""
|
export FREETYPE_CFLAGS=""
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Any stuff that you need to do before you start building the wheels
|
# Any stuff that you need to do before you start building the wheels
|
||||||
# Runs in the root directory of this repository.
|
# Runs in the root directory of this repository.
|
||||||
curl -fsSL -o pillow-depends-main.zip https://github.com/python-pillow/pillow-depends/archive/main.zip
|
curl -fsSL -o pillow-depends-main.zip https://github.com/python-pillow/pillow-depends/archive/main.zip
|
||||||
untar pillow-depends-main.zip
|
untar pillow-depends-main.zip
|
||||||
|
|
||||||
if [[ -n "$IS_MACOS" ]]; then
|
if [[ -n "$IS_MACOS" ]]; then
|
||||||
# libtiff and libxcb cause a conflict with building libtiff and libxcb
|
# libtiff and libxcb cause a conflict with building libtiff and libxcb
|
||||||
# libxau and libxdmcp cause an issue on macOS < 11
|
# libxau and libxdmcp cause an issue on macOS < 11
|
||||||
# remove cairo to fix building harfbuzz on arm64
|
# remove cairo to fix building harfbuzz on arm64
|
||||||
# remove lcms2 and libpng to fix building openjpeg on arm64
|
# remove lcms2 and libpng to fix building openjpeg on arm64
|
||||||
# remove jpeg-turbo to avoid inclusion on arm64
|
# remove jpeg-turbo to avoid inclusion on arm64
|
||||||
# remove webp and zstd to avoid inclusion on x86_64
|
# remove webp and zstd to avoid inclusion on x86_64
|
||||||
# curl from brew requires zstd, use system curl
|
# curl from brew requires zstd, use system curl
|
||||||
brew remove --ignore-dependencies libpng libtiff libxcb libxau libxdmcp curl cairo lcms2 zstd
|
brew remove --ignore-dependencies libpng libtiff libxcb libxau libxdmcp curl cairo lcms2 zstd
|
||||||
if [[ "$CIBW_ARCHS" == "arm64" ]]; then
|
if [[ "$CIBW_ARCHS" == "arm64" ]]; then
|
||||||
brew remove --ignore-dependencies jpeg-turbo
|
brew remove --ignore-dependencies jpeg-turbo
|
||||||
else
|
else
|
||||||
brew remove --ignore-dependencies webp
|
brew remove --ignore-dependencies webp
|
||||||
fi
|
fi
|
||||||
|
|
||||||
brew install pkg-config
|
brew install pkg-config
|
||||||
fi
|
fi
|
||||||
|
|
||||||
wrap_wheel_builder build
|
wrap_wheel_builder build
|
||||||
|
|
||||||
# Append licenses
|
# Append licenses
|
||||||
for filename in wheels/dependency_licenses/*; do
|
for filename in wheels/dependency_licenses/*; do
|
||||||
echo -e "\n\n----\n\n$(basename $filename | cut -f 1 -d '.')\n" | cat >> LICENSE
|
echo -e "\n\n----\n\n$(basename $filename | cut -f 1 -d '.')\n" | cat >> LICENSE
|
||||||
cat $filename >> LICENSE
|
cat $filename >> LICENSE
|
||||||
done
|
done
|
||||||
|
|
44
.github/workflows/wheels-test.ps1
vendored
44
.github/workflows/wheels-test.ps1
vendored
|
@ -1,22 +1,22 @@
|
||||||
param ([string]$venv, [string]$pillow="C:\pillow")
|
param ([string]$venv, [string]$pillow="C:\pillow")
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
$ProgressPreference = 'SilentlyContinue'
|
$ProgressPreference = 'SilentlyContinue'
|
||||||
Set-PSDebug -Trace 1
|
Set-PSDebug -Trace 1
|
||||||
if ("$venv" -like "*\cibw-run-*\pp*-win_amd64\*") {
|
if ("$venv" -like "*\cibw-run-*\pp*-win_amd64\*") {
|
||||||
# unlike CPython, PyPy requires Visual C++ Redistributable to be installed
|
# unlike CPython, PyPy requires Visual C++ Redistributable to be installed
|
||||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
Invoke-WebRequest -Uri 'https://aka.ms/vs/15/release/vc_redist.x64.exe' -OutFile 'vc_redist.x64.exe'
|
Invoke-WebRequest -Uri 'https://aka.ms/vs/15/release/vc_redist.x64.exe' -OutFile 'vc_redist.x64.exe'
|
||||||
C:\vc_redist.x64.exe /install /quiet /norestart | Out-Null
|
C:\vc_redist.x64.exe /install /quiet /norestart | Out-Null
|
||||||
}
|
}
|
||||||
$env:path += ";$pillow\winbuild\build\bin\"
|
$env:path += ";$pillow\winbuild\build\bin\"
|
||||||
& "$venv\Scripts\activate.ps1"
|
& "$venv\Scripts\activate.ps1"
|
||||||
& reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\python.exe" /v "GlobalFlag" /t REG_SZ /d "0x02000000" /f
|
& reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\python.exe" /v "GlobalFlag" /t REG_SZ /d "0x02000000" /f
|
||||||
cd $pillow
|
cd $pillow
|
||||||
& python -VV
|
& python -VV
|
||||||
if (!$?) { exit $LASTEXITCODE }
|
if (!$?) { exit $LASTEXITCODE }
|
||||||
& python selftest.py
|
& python selftest.py
|
||||||
if (!$?) { exit $LASTEXITCODE }
|
if (!$?) { exit $LASTEXITCODE }
|
||||||
& python -m pytest -vx Tests\check_wheel.py
|
& python -m pytest -vx Tests\check_wheel.py
|
||||||
if (!$?) { exit $LASTEXITCODE }
|
if (!$?) { exit $LASTEXITCODE }
|
||||||
& python -m pytest -vx Tests
|
& python -m pytest -vx Tests
|
||||||
if (!$?) { exit $LASTEXITCODE }
|
if (!$?) { exit $LASTEXITCODE }
|
||||||
|
|
56
.github/workflows/wheels-test.sh
vendored
56
.github/workflows/wheels-test.sh
vendored
|
@ -1,28 +1,28 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
brew install fribidi
|
brew install fribidi
|
||||||
export PKG_CONFIG_PATH="/usr/local/opt/openblas/lib/pkgconfig"
|
export PKG_CONFIG_PATH="/usr/local/opt/openblas/lib/pkgconfig"
|
||||||
if [ -f /opt/homebrew/lib/libfribidi.dylib ]; then
|
if [ -f /opt/homebrew/lib/libfribidi.dylib ]; then
|
||||||
sudo cp /opt/homebrew/lib/libfribidi.dylib /usr/local/lib
|
sudo cp /opt/homebrew/lib/libfribidi.dylib /usr/local/lib
|
||||||
fi
|
fi
|
||||||
elif [ "${AUDITWHEEL_POLICY::9}" == "musllinux" ]; then
|
elif [ "${AUDITWHEEL_POLICY::9}" == "musllinux" ]; then
|
||||||
apk add curl fribidi
|
apk add curl fribidi
|
||||||
else
|
else
|
||||||
yum install -y fribidi
|
yum install -y fribidi
|
||||||
fi
|
fi
|
||||||
if [ "${AUDITWHEEL_POLICY::9}" != "musllinux" ] && !([[ "$OSTYPE" == "darwin"* ]] && [[ $(python3 --version) == *"3.13."* ]]); then
|
if [ "${AUDITWHEEL_POLICY::9}" != "musllinux" ] && !([[ "$OSTYPE" == "darwin"* ]] && [[ $(python3 --version) == *"3.13."* ]]); then
|
||||||
python3 -m pip install numpy
|
python3 -m pip install numpy
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -d "test-images-main" ]; then
|
if [ ! -d "test-images-main" ]; then
|
||||||
curl -fsSL -o pillow-test-images.zip https://github.com/python-pillow/test-images/archive/main.zip
|
curl -fsSL -o pillow-test-images.zip https://github.com/python-pillow/test-images/archive/main.zip
|
||||||
unzip pillow-test-images.zip
|
unzip pillow-test-images.zip
|
||||||
mv test-images-main/* Tests/images
|
mv test-images-main/* Tests/images
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Runs tests
|
# Runs tests
|
||||||
python3 selftest.py
|
python3 selftest.py
|
||||||
python3 -m pytest Tests/check_wheel.py
|
python3 -m pytest Tests/check_wheel.py
|
||||||
python3 -m pytest
|
python3 -m pytest
|
||||||
|
|
540
.github/workflows/wheels.yml
vendored
540
.github/workflows/wheels.yml
vendored
|
@ -1,270 +1,270 @@
|
||||||
name: Wheels
|
name: Wheels
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- ".ci/requirements-cibw.txt"
|
- ".ci/requirements-cibw.txt"
|
||||||
- ".github/workflows/wheel*"
|
- ".github/workflows/wheel*"
|
||||||
- "setup.py"
|
- "setup.py"
|
||||||
- "wheels/*"
|
- "wheels/*"
|
||||||
- "winbuild/build_prepare.py"
|
- "winbuild/build_prepare.py"
|
||||||
- "winbuild/fribidi.cmake"
|
- "winbuild/fribidi.cmake"
|
||||||
tags:
|
tags:
|
||||||
- "*"
|
- "*"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- ".ci/requirements-cibw.txt"
|
- ".ci/requirements-cibw.txt"
|
||||||
- ".github/workflows/wheel*"
|
- ".github/workflows/wheel*"
|
||||||
- "setup.py"
|
- "setup.py"
|
||||||
- "wheels/*"
|
- "wheels/*"
|
||||||
- "winbuild/build_prepare.py"
|
- "winbuild/build_prepare.py"
|
||||||
- "winbuild/fribidi.cmake"
|
- "winbuild/fribidi.cmake"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FORCE_COLOR: 1
|
FORCE_COLOR: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-1-QEMU-emulated-wheels:
|
build-1-QEMU-emulated-wheels:
|
||||||
name: aarch64 ${{ matrix.python-version }} ${{ matrix.spec }}
|
name: aarch64 ${{ matrix.python-version }} ${{ matrix.spec }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version:
|
python-version:
|
||||||
- pp39
|
- pp39
|
||||||
- pp310
|
- pp310
|
||||||
- cp38
|
- cp38
|
||||||
- cp39
|
- cp39
|
||||||
- cp310
|
- cp310
|
||||||
- cp311
|
- cp311
|
||||||
- cp312
|
- cp312
|
||||||
- cp313
|
- cp313
|
||||||
spec:
|
spec:
|
||||||
- manylinux2014
|
- manylinux2014
|
||||||
- manylinux_2_28
|
- manylinux_2_28
|
||||||
- musllinux
|
- musllinux
|
||||||
exclude:
|
exclude:
|
||||||
- { python-version: pp39, spec: musllinux }
|
- { python-version: pp39, spec: musllinux }
|
||||||
- { python-version: pp310, spec: musllinux }
|
- { python-version: pp310, spec: musllinux }
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
|
|
||||||
# https://github.com/docker/setup-qemu-action
|
# https://github.com/docker/setup-qemu-action
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
- name: Install cibuildwheel
|
- name: Install cibuildwheel
|
||||||
run: |
|
run: |
|
||||||
python3 -m pip install -r .ci/requirements-cibw.txt
|
python3 -m pip install -r .ci/requirements-cibw.txt
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
run: |
|
run: |
|
||||||
python3 -m cibuildwheel --output-dir wheelhouse
|
python3 -m cibuildwheel --output-dir wheelhouse
|
||||||
env:
|
env:
|
||||||
# Build only the currently selected Linux architecture (so we can
|
# Build only the currently selected Linux architecture (so we can
|
||||||
# parallelise for speed).
|
# parallelise for speed).
|
||||||
CIBW_ARCHS: "aarch64"
|
CIBW_ARCHS: "aarch64"
|
||||||
# Likewise, select only one Python version per job to speed this up.
|
# Likewise, select only one Python version per job to speed this up.
|
||||||
CIBW_BUILD: "${{ matrix.python-version }}-${{ matrix.spec == 'musllinux' && 'musllinux' || 'manylinux' }}*"
|
CIBW_BUILD: "${{ matrix.python-version }}-${{ matrix.spec == 'musllinux' && 'musllinux' || 'manylinux' }}*"
|
||||||
CIBW_PRERELEASE_PYTHONS: True
|
CIBW_PRERELEASE_PYTHONS: True
|
||||||
# Extra options for manylinux.
|
# Extra options for manylinux.
|
||||||
CIBW_MANYLINUX_AARCH64_IMAGE: ${{ matrix.spec }}
|
CIBW_MANYLINUX_AARCH64_IMAGE: ${{ matrix.spec }}
|
||||||
CIBW_MANYLINUX_PYPY_AARCH64_IMAGE: ${{ matrix.spec }}
|
CIBW_MANYLINUX_PYPY_AARCH64_IMAGE: ${{ matrix.spec }}
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: dist-qemu-${{ matrix.python-version }}-${{ matrix.spec }}
|
name: dist-qemu-${{ matrix.python-version }}-${{ matrix.spec }}
|
||||||
path: ./wheelhouse/*.whl
|
path: ./wheelhouse/*.whl
|
||||||
|
|
||||||
build-2-native-wheels:
|
build-2-native-wheels:
|
||||||
name: ${{ matrix.name }}
|
name: ${{ matrix.name }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- name: "macOS x86_64"
|
- name: "macOS x86_64"
|
||||||
os: macos-13
|
os: macos-13
|
||||||
cibw_arch: x86_64
|
cibw_arch: x86_64
|
||||||
macosx_deployment_target: "10.10"
|
macosx_deployment_target: "10.10"
|
||||||
- name: "macOS arm64"
|
- name: "macOS arm64"
|
||||||
os: macos-14
|
os: macos-14
|
||||||
cibw_arch: arm64
|
cibw_arch: arm64
|
||||||
macosx_deployment_target: "11.0"
|
macosx_deployment_target: "11.0"
|
||||||
- name: "manylinux2014 and musllinux x86_64"
|
- name: "manylinux2014 and musllinux x86_64"
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
cibw_arch: x86_64
|
cibw_arch: x86_64
|
||||||
- name: "manylinux_2_28 x86_64"
|
- name: "manylinux_2_28 x86_64"
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
cibw_arch: x86_64
|
cibw_arch: x86_64
|
||||||
build: "*manylinux*"
|
build: "*manylinux*"
|
||||||
manylinux: "manylinux_2_28"
|
manylinux: "manylinux_2_28"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
|
|
||||||
- name: Install cibuildwheel
|
- name: Install cibuildwheel
|
||||||
run: |
|
run: |
|
||||||
python3 -m pip install -r .ci/requirements-cibw.txt
|
python3 -m pip install -r .ci/requirements-cibw.txt
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
run: |
|
run: |
|
||||||
python3 -m cibuildwheel --output-dir wheelhouse
|
python3 -m cibuildwheel --output-dir wheelhouse
|
||||||
env:
|
env:
|
||||||
CIBW_ARCHS: ${{ matrix.cibw_arch }}
|
CIBW_ARCHS: ${{ matrix.cibw_arch }}
|
||||||
CIBW_BUILD: ${{ matrix.build }}
|
CIBW_BUILD: ${{ matrix.build }}
|
||||||
CIBW_MANYLINUX_PYPY_X86_64_IMAGE: ${{ matrix.manylinux }}
|
CIBW_MANYLINUX_PYPY_X86_64_IMAGE: ${{ matrix.manylinux }}
|
||||||
CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux }}
|
CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux }}
|
||||||
CIBW_PRERELEASE_PYTHONS: True
|
CIBW_PRERELEASE_PYTHONS: True
|
||||||
CIBW_SKIP: pp38-*
|
CIBW_SKIP: pp38-*
|
||||||
CIBW_TEST_SKIP: cp38-macosx_arm64
|
CIBW_TEST_SKIP: cp38-macosx_arm64
|
||||||
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
|
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: dist-${{ matrix.os }}-${{ matrix.cibw_arch }}${{ matrix.manylinux && format('-{0}', matrix.manylinux) }}
|
name: dist-${{ matrix.os }}-${{ matrix.cibw_arch }}${{ matrix.manylinux && format('-{0}', matrix.manylinux) }}
|
||||||
path: ./wheelhouse/*.whl
|
path: ./wheelhouse/*.whl
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
name: Windows ${{ matrix.cibw_arch }}
|
name: Windows ${{ matrix.cibw_arch }}
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- cibw_arch: x86
|
- cibw_arch: x86
|
||||||
- cibw_arch: AMD64
|
- cibw_arch: AMD64
|
||||||
- cibw_arch: ARM64
|
- cibw_arch: ARM64
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Checkout extra test images
|
- name: Checkout extra test images
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: python-pillow/test-images
|
repository: python-pillow/test-images
|
||||||
path: Tests\test-images
|
path: Tests\test-images
|
||||||
|
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
|
|
||||||
- name: Install cibuildwheel
|
- name: Install cibuildwheel
|
||||||
run: |
|
run: |
|
||||||
python.exe -m pip install -r .ci/requirements-cibw.txt
|
python.exe -m pip install -r .ci/requirements-cibw.txt
|
||||||
|
|
||||||
- name: Prepare for build
|
- name: Prepare for build
|
||||||
run: |
|
run: |
|
||||||
choco install nasm --no-progress
|
choco install nasm --no-progress
|
||||||
echo "C:\Program Files\NASM" >> $env:GITHUB_PATH
|
echo "C:\Program Files\NASM" >> $env:GITHUB_PATH
|
||||||
|
|
||||||
# Install extra test images
|
# Install extra test images
|
||||||
xcopy /S /Y Tests\test-images\* Tests\images
|
xcopy /S /Y Tests\test-images\* Tests\images
|
||||||
|
|
||||||
& python.exe winbuild\build_prepare.py -v --no-imagequant --architecture=${{ matrix.cibw_arch }}
|
& python.exe winbuild\build_prepare.py -v --no-imagequant --architecture=${{ matrix.cibw_arch }}
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
run: |
|
run: |
|
||||||
setlocal EnableDelayedExpansion
|
setlocal EnableDelayedExpansion
|
||||||
for %%f in (winbuild\build\license\*) do (
|
for %%f in (winbuild\build\license\*) do (
|
||||||
set x=%%~nf
|
set x=%%~nf
|
||||||
rem Skip FriBiDi license, it is not included in the wheel.
|
rem Skip FriBiDi license, it is not included in the wheel.
|
||||||
set fribidi=!x:~0,7!
|
set fribidi=!x:~0,7!
|
||||||
if NOT !fribidi!==fribidi (
|
if NOT !fribidi!==fribidi (
|
||||||
rem Skip imagequant license, it is not included in the wheel.
|
rem Skip imagequant license, it is not included in the wheel.
|
||||||
set libimagequant=!x:~0,13!
|
set libimagequant=!x:~0,13!
|
||||||
if NOT !libimagequant!==libimagequant (
|
if NOT !libimagequant!==libimagequant (
|
||||||
echo. >> LICENSE
|
echo. >> LICENSE
|
||||||
echo ===== %%~nf ===== >> LICENSE
|
echo ===== %%~nf ===== >> LICENSE
|
||||||
echo. >> LICENSE
|
echo. >> LICENSE
|
||||||
type %%f >> LICENSE
|
type %%f >> LICENSE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
call winbuild\\build\\build_env.cmd
|
call winbuild\\build\\build_env.cmd
|
||||||
%pythonLocation%\python.exe -m cibuildwheel . --output-dir wheelhouse
|
%pythonLocation%\python.exe -m cibuildwheel . --output-dir wheelhouse
|
||||||
env:
|
env:
|
||||||
CIBW_ARCHS: ${{ matrix.cibw_arch }}
|
CIBW_ARCHS: ${{ matrix.cibw_arch }}
|
||||||
CIBW_BEFORE_ALL: "{package}\\winbuild\\build\\build_dep_all.cmd"
|
CIBW_BEFORE_ALL: "{package}\\winbuild\\build\\build_dep_all.cmd"
|
||||||
CIBW_CACHE_PATH: "C:\\cibw"
|
CIBW_CACHE_PATH: "C:\\cibw"
|
||||||
CIBW_PRERELEASE_PYTHONS: True
|
CIBW_PRERELEASE_PYTHONS: True
|
||||||
CIBW_SKIP: pp38-*
|
CIBW_SKIP: pp38-*
|
||||||
CIBW_TEST_SKIP: "*-win_arm64"
|
CIBW_TEST_SKIP: "*-win_arm64"
|
||||||
CIBW_TEST_COMMAND: 'docker run --rm
|
CIBW_TEST_COMMAND: 'docker run --rm
|
||||||
-v {project}:C:\pillow
|
-v {project}:C:\pillow
|
||||||
-v C:\cibw:C:\cibw
|
-v C:\cibw:C:\cibw
|
||||||
-v %CD%\..\venv-test:%CD%\..\venv-test
|
-v %CD%\..\venv-test:%CD%\..\venv-test
|
||||||
-e CI -e GITHUB_ACTIONS
|
-e CI -e GITHUB_ACTIONS
|
||||||
mcr.microsoft.com/windows/servercore:ltsc2022
|
mcr.microsoft.com/windows/servercore:ltsc2022
|
||||||
powershell C:\pillow\.github\workflows\wheels-test.ps1 %CD%\..\venv-test'
|
powershell C:\pillow\.github\workflows\wheels-test.ps1 %CD%\..\venv-test'
|
||||||
shell: cmd
|
shell: cmd
|
||||||
|
|
||||||
- name: Upload wheels
|
- name: Upload wheels
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: dist-windows-${{ matrix.cibw_arch }}
|
name: dist-windows-${{ matrix.cibw_arch }}
|
||||||
path: ./wheelhouse/*.whl
|
path: ./wheelhouse/*.whl
|
||||||
|
|
||||||
- name: Upload fribidi.dll
|
- name: Upload fribidi.dll
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: fribidi-windows-${{ matrix.cibw_arch }}
|
name: fribidi-windows-${{ matrix.cibw_arch }}
|
||||||
path: winbuild\build\bin\fribidi*
|
path: winbuild\build\bin\fribidi*
|
||||||
|
|
||||||
sdist:
|
sdist:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
cache: pip
|
cache: pip
|
||||||
cache-dependency-path: "Makefile"
|
cache-dependency-path: "Makefile"
|
||||||
|
|
||||||
- run: make sdist
|
- run: make sdist
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: dist-sdist
|
name: dist-sdist
|
||||||
path: dist/*.tar.gz
|
path: dist/*.tar.gz
|
||||||
|
|
||||||
pypi-publish:
|
pypi-publish:
|
||||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
|
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
|
||||||
needs: [build-1-QEMU-emulated-wheels, build-2-native-wheels, windows, sdist]
|
needs: [build-1-QEMU-emulated-wheels, build-2-native-wheels, windows, sdist]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Upload release to PyPI
|
name: Upload release to PyPI
|
||||||
environment:
|
environment:
|
||||||
name: release-pypi
|
name: release-pypi
|
||||||
url: https://pypi.org/p/Pillow
|
url: https://pypi.org/p/Pillow
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
pattern: dist-*
|
pattern: dist-*
|
||||||
path: dist
|
path: dist
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
- name: Publish to PyPI
|
- name: Publish to PyPI
|
||||||
uses: pypa/gh-action-pypi-publish@release/v1
|
uses: pypa/gh-action-pypi-publish@release/v1
|
||||||
|
|
188
.gitignore
vendored
188
.gitignore
vendored
|
@ -1,94 +1,94 @@
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
|
||||||
# C extensions
|
# C extensions
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
# Distribution / packaging
|
# Distribution / packaging
|
||||||
.eggs/
|
.eggs/
|
||||||
.Python
|
.Python
|
||||||
env/
|
env/
|
||||||
bin/
|
bin/
|
||||||
build/
|
build/
|
||||||
develop-eggs/
|
develop-eggs/
|
||||||
dist/
|
dist/
|
||||||
eggs/
|
eggs/
|
||||||
lib/
|
lib/
|
||||||
lib64/
|
lib64/
|
||||||
parts/
|
parts/
|
||||||
sdist/
|
sdist/
|
||||||
var/
|
var/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
.installed.cfg
|
.installed.cfg
|
||||||
*.egg
|
*.egg
|
||||||
|
|
||||||
# Installer logs
|
# Installer logs
|
||||||
pip-log.txt
|
pip-log.txt
|
||||||
pip-delete-this-directory.txt
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
# Unit test / coverage reports
|
# Unit test / coverage reports
|
||||||
htmlcov/
|
htmlcov/
|
||||||
.tox/
|
.tox/
|
||||||
.coverage
|
.coverage
|
||||||
.cache
|
.cache
|
||||||
.pytest_cache
|
.pytest_cache
|
||||||
coverage.xml
|
coverage.xml
|
||||||
|
|
||||||
# Test files
|
# Test files
|
||||||
test_images
|
test_images
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
*.mo
|
*.mo
|
||||||
|
|
||||||
# Mr Developer
|
# Mr Developer
|
||||||
.mr.developer.cfg
|
.mr.developer.cfg
|
||||||
.project
|
.project
|
||||||
.pydevproject
|
.pydevproject
|
||||||
|
|
||||||
# Rope
|
# Rope
|
||||||
.ropeproject
|
.ropeproject
|
||||||
|
|
||||||
# Django stuff:
|
# Django stuff:
|
||||||
*.log
|
*.log
|
||||||
*.pot
|
*.pot
|
||||||
|
|
||||||
# Sphinx documentation
|
# Sphinx documentation
|
||||||
docs/_build/
|
docs/_build/
|
||||||
|
|
||||||
# viewdoc output
|
# viewdoc output
|
||||||
.long-description.html
|
.long-description.html
|
||||||
|
|
||||||
# Vim cruft
|
# Vim cruft
|
||||||
.*.swp
|
.*.swp
|
||||||
|
|
||||||
#emacs
|
#emacs
|
||||||
*~
|
*~
|
||||||
\#*#
|
\#*#
|
||||||
.#*
|
.#*
|
||||||
|
|
||||||
#VS Code
|
#VS Code
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
#Komodo
|
#Komodo
|
||||||
*.komodoproject
|
*.komodoproject
|
||||||
|
|
||||||
#OS
|
#OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
# JetBrains
|
# JetBrains
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
# Extra test images installed from python-pillow/test-images
|
# Extra test images installed from python-pillow/test-images
|
||||||
Tests/images/README.md
|
Tests/images/README.md
|
||||||
Tests/images/crash_1.tif
|
Tests/images/crash_1.tif
|
||||||
Tests/images/crash_2.tif
|
Tests/images/crash_2.tif
|
||||||
Tests/images/crash-81154a65438ba5aaeca73fd502fa4850fbde60f8.tif
|
Tests/images/crash-81154a65438ba5aaeca73fd502fa4850fbde60f8.tif
|
||||||
Tests/images/string_dimension.tiff
|
Tests/images/string_dimension.tiff
|
||||||
Tests/images/jpeg2000
|
Tests/images/jpeg2000
|
||||||
Tests/images/msp
|
Tests/images/msp
|
||||||
Tests/images/picins
|
Tests/images/picins
|
||||||
Tests/images/sunraster
|
Tests/images/sunraster
|
||||||
|
|
||||||
# pyinstaller
|
# pyinstaller
|
||||||
*.spec
|
*.spec
|
||||||
|
|
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -1,3 +1,3 @@
|
||||||
[submodule "multibuild"]
|
[submodule "multibuild"]
|
||||||
path = wheels/multibuild
|
path = wheels/multibuild
|
||||||
url = https://github.com/multi-build/multibuild.git
|
url = https://github.com/multi-build/multibuild.git
|
||||||
|
|
|
@ -1,85 +1,85 @@
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.4.7
|
rev: v0.4.7
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
args: [--exit-non-zero-on-fix]
|
args: [--exit-non-zero-on-fix]
|
||||||
|
|
||||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||||
rev: 24.4.2
|
rev: 24.4.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
- repo: https://github.com/PyCQA/bandit
|
- repo: https://github.com/PyCQA/bandit
|
||||||
rev: 1.7.8
|
rev: 1.7.8
|
||||||
hooks:
|
hooks:
|
||||||
- id: bandit
|
- id: bandit
|
||||||
args: [--severity-level=high]
|
args: [--severity-level=high]
|
||||||
files: ^src/
|
files: ^src/
|
||||||
|
|
||||||
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
||||||
rev: v1.5.5
|
rev: v1.5.5
|
||||||
hooks:
|
hooks:
|
||||||
- id: remove-tabs
|
- id: remove-tabs
|
||||||
exclude: (Makefile$|\.bat$|\.cmake$|\.eps$|\.fits$|\.gd$|\.opt$)
|
exclude: (Makefile$|\.bat$|\.cmake$|\.eps$|\.fits$|\.gd$|\.opt$)
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
rev: v18.1.5
|
rev: v18.1.5
|
||||||
hooks:
|
hooks:
|
||||||
- id: clang-format
|
- id: clang-format
|
||||||
types: [c]
|
types: [c]
|
||||||
exclude: ^src/thirdparty/
|
exclude: ^src/thirdparty/
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||||
rev: v1.10.0
|
rev: v1.10.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: rst-backticks
|
- id: rst-backticks
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.6.0
|
rev: v4.6.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-executables-have-shebangs
|
- id: check-executables-have-shebangs
|
||||||
- id: check-shebang-scripts-are-executable
|
- id: check-shebang-scripts-are-executable
|
||||||
- id: check-merge-conflict
|
- id: check-merge-conflict
|
||||||
- id: check-json
|
- id: check-json
|
||||||
- id: check-toml
|
- id: check-toml
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
exclude: ^Tests/images/
|
exclude: ^Tests/images/
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
exclude: ^.github/.*TEMPLATE|^Tests/(fonts|images)/
|
exclude: ^.github/.*TEMPLATE|^Tests/(fonts|images)/
|
||||||
|
|
||||||
- repo: https://github.com/python-jsonschema/check-jsonschema
|
- repo: https://github.com/python-jsonschema/check-jsonschema
|
||||||
rev: 0.28.4
|
rev: 0.28.4
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-github-workflows
|
- id: check-github-workflows
|
||||||
- id: check-readthedocs
|
- id: check-readthedocs
|
||||||
- id: check-renovate
|
- id: check-renovate
|
||||||
|
|
||||||
- repo: https://github.com/sphinx-contrib/sphinx-lint
|
- repo: https://github.com/sphinx-contrib/sphinx-lint
|
||||||
rev: v0.9.1
|
rev: v0.9.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: sphinx-lint
|
- id: sphinx-lint
|
||||||
|
|
||||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||||
rev: 1.8.0
|
rev: 1.8.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyproject-fmt
|
- id: pyproject-fmt
|
||||||
|
|
||||||
- repo: https://github.com/abravalheri/validate-pyproject
|
- repo: https://github.com/abravalheri/validate-pyproject
|
||||||
rev: v0.18
|
rev: v0.18
|
||||||
hooks:
|
hooks:
|
||||||
- id: validate-pyproject
|
- id: validate-pyproject
|
||||||
|
|
||||||
- repo: https://github.com/tox-dev/tox-ini-fmt
|
- repo: https://github.com/tox-dev/tox-ini-fmt
|
||||||
rev: 1.3.1
|
rev: 1.3.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: tox-ini-fmt
|
- id: tox-ini-fmt
|
||||||
|
|
||||||
- repo: meta
|
- repo: meta
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-hooks-apply
|
- id: check-hooks-apply
|
||||||
- id: check-useless-excludes
|
- id: check-useless-excludes
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
autoupdate_schedule: monthly
|
autoupdate_schedule: monthly
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
version: 2
|
version: 2
|
||||||
|
|
||||||
formats: [pdf]
|
formats: [pdf]
|
||||||
|
|
||||||
build:
|
build:
|
||||||
os: ubuntu-lts-latest
|
os: ubuntu-lts-latest
|
||||||
tools:
|
tools:
|
||||||
python: "3"
|
python: "3"
|
||||||
jobs:
|
jobs:
|
||||||
post_checkout:
|
post_checkout:
|
||||||
- git remote add upstream https://github.com/python-pillow/Pillow.git # For forks
|
- git remote add upstream https://github.com/python-pillow/Pillow.git # For forks
|
||||||
- git fetch upstream --tags
|
- git fetch upstream --tags
|
||||||
|
|
||||||
python:
|
python:
|
||||||
install:
|
install:
|
||||||
- method: pip
|
- method: pip
|
||||||
path: .
|
path: .
|
||||||
extra_requirements:
|
extra_requirements:
|
||||||
- docs
|
- docs
|
||||||
|
|
15296
CHANGES.rst
15296
CHANGES.rst
File diff suppressed because it is too large
Load Diff
60
LICENSE
60
LICENSE
|
@ -1,30 +1,30 @@
|
||||||
The Python Imaging Library (PIL) is
|
The Python Imaging Library (PIL) is
|
||||||
|
|
||||||
Copyright © 1997-2011 by Secret Labs AB
|
Copyright © 1997-2011 by Secret Labs AB
|
||||||
Copyright © 1995-2011 by Fredrik Lundh and contributors
|
Copyright © 1995-2011 by Fredrik Lundh and contributors
|
||||||
|
|
||||||
Pillow is the friendly PIL fork. It is
|
Pillow is the friendly PIL fork. It is
|
||||||
|
|
||||||
Copyright © 2010-2024 by Jeffrey A. Clark and contributors
|
Copyright © 2010-2024 by Jeffrey A. Clark and contributors
|
||||||
|
|
||||||
Like PIL, Pillow is licensed under the open source HPND License:
|
Like PIL, Pillow is licensed under the open source HPND License:
|
||||||
|
|
||||||
By obtaining, using, and/or copying this software and/or its associated
|
By obtaining, using, and/or copying this software and/or its associated
|
||||||
documentation, you agree that you have read, understood, and will comply
|
documentation, you agree that you have read, understood, and will comply
|
||||||
with the following terms and conditions:
|
with the following terms and conditions:
|
||||||
|
|
||||||
Permission to use, copy, modify and distribute this software and its
|
Permission to use, copy, modify and distribute this software and its
|
||||||
documentation for any purpose and without fee is hereby granted,
|
documentation for any purpose and without fee is hereby granted,
|
||||||
provided that the above copyright notice appears in all copies, and that
|
provided that the above copyright notice appears in all copies, and that
|
||||||
both that copyright notice and this permission notice appear in supporting
|
both that copyright notice and this permission notice appear in supporting
|
||||||
documentation, and that the name of Secret Labs AB or the author not be
|
documentation, and that the name of Secret Labs AB or the author not be
|
||||||
used in advertising or publicity pertaining to distribution of the software
|
used in advertising or publicity pertaining to distribution of the software
|
||||||
without specific, written prior permission.
|
without specific, written prior permission.
|
||||||
|
|
||||||
SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||||
IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR ANY SPECIAL,
|
IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR ANY SPECIAL,
|
||||||
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
PERFORMANCE OF THIS SOFTWARE.
|
PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
68
MANIFEST.in
68
MANIFEST.in
|
@ -1,34 +1,34 @@
|
||||||
include *.c
|
include *.c
|
||||||
include *.h
|
include *.h
|
||||||
include *.in
|
include *.in
|
||||||
include *.md
|
include *.md
|
||||||
include *.py
|
include *.py
|
||||||
include *.rst
|
include *.rst
|
||||||
include *.sh
|
include *.sh
|
||||||
include *.toml
|
include *.toml
|
||||||
include *.txt
|
include *.txt
|
||||||
include *.yaml
|
include *.yaml
|
||||||
include .flake8
|
include .flake8
|
||||||
include LICENSE
|
include LICENSE
|
||||||
include Makefile
|
include Makefile
|
||||||
include tox.ini
|
include tox.ini
|
||||||
graft Tests
|
graft Tests
|
||||||
graft src
|
graft src
|
||||||
graft depends
|
graft depends
|
||||||
graft winbuild
|
graft winbuild
|
||||||
graft docs
|
graft docs
|
||||||
graft _custom_build
|
graft _custom_build
|
||||||
|
|
||||||
# build/src control detritus
|
# build/src control detritus
|
||||||
exclude .appveyor.yml
|
exclude .appveyor.yml
|
||||||
exclude .clang-format
|
exclude .clang-format
|
||||||
exclude .coveragerc
|
exclude .coveragerc
|
||||||
exclude .editorconfig
|
exclude .editorconfig
|
||||||
exclude .readthedocs.yml
|
exclude .readthedocs.yml
|
||||||
exclude codecov.yml
|
exclude codecov.yml
|
||||||
exclude renovate.json
|
exclude renovate.json
|
||||||
global-exclude .git*
|
global-exclude .git*
|
||||||
global-exclude *.pyc
|
global-exclude *.pyc
|
||||||
global-exclude *.so
|
global-exclude *.so
|
||||||
prune .ci
|
prune .ci
|
||||||
prune wheels
|
prune wheels
|
||||||
|
|
250
Makefile
250
Makefile
|
@ -1,125 +1,125 @@
|
||||||
.DEFAULT_GOAL := help
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm src/PIL/*.so || true
|
rm src/PIL/*.so || true
|
||||||
rm -r build || true
|
rm -r build || true
|
||||||
find . -name __pycache__ | xargs rm -r || true
|
find . -name __pycache__ | xargs rm -r || true
|
||||||
|
|
||||||
.PHONY: coverage
|
.PHONY: coverage
|
||||||
coverage:
|
coverage:
|
||||||
python3 -c "import pytest" > /dev/null 2>&1 || python3 -m pip install pytest
|
python3 -c "import pytest" > /dev/null 2>&1 || python3 -m pip install pytest
|
||||||
python3 -m pytest -qq
|
python3 -m pytest -qq
|
||||||
rm -r htmlcov || true
|
rm -r htmlcov || true
|
||||||
python3 -c "import coverage" > /dev/null 2>&1 || python3 -m pip install coverage
|
python3 -c "import coverage" > /dev/null 2>&1 || python3 -m pip install coverage
|
||||||
python3 -m coverage report
|
python3 -m coverage report
|
||||||
|
|
||||||
.PHONY: doc
|
.PHONY: doc
|
||||||
.PHONY: html
|
.PHONY: html
|
||||||
doc html:
|
doc html:
|
||||||
python3 -c "import PIL" > /dev/null 2>&1 || python3 -m pip install .
|
python3 -c "import PIL" > /dev/null 2>&1 || python3 -m pip install .
|
||||||
$(MAKE) -C docs html
|
$(MAKE) -C docs html
|
||||||
|
|
||||||
.PHONY: htmlview
|
.PHONY: htmlview
|
||||||
htmlview:
|
htmlview:
|
||||||
python3 -c "import PIL" > /dev/null 2>&1 || python3 -m pip install .
|
python3 -c "import PIL" > /dev/null 2>&1 || python3 -m pip install .
|
||||||
$(MAKE) -C docs htmlview
|
$(MAKE) -C docs htmlview
|
||||||
|
|
||||||
.PHONY: doccheck
|
.PHONY: doccheck
|
||||||
doccheck:
|
doccheck:
|
||||||
$(MAKE) doc
|
$(MAKE) doc
|
||||||
# Don't make our tests rely on the links in the docs being up every single build.
|
# Don't make our tests rely on the links in the docs being up every single build.
|
||||||
# We don't control them. But do check, and update them to the target of their redirects.
|
# We don't control them. But do check, and update them to the target of their redirects.
|
||||||
$(MAKE) -C docs linkcheck || true
|
$(MAKE) -C docs linkcheck || true
|
||||||
|
|
||||||
.PHONY: docserve
|
.PHONY: docserve
|
||||||
docserve:
|
docserve:
|
||||||
cd docs/_build/html && python3 -m http.server 2> /dev/null&
|
cd docs/_build/html && python3 -m http.server 2> /dev/null&
|
||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
help:
|
help:
|
||||||
@echo "Welcome to Pillow development. Please use \`make <target>\` where <target> is one of"
|
@echo "Welcome to Pillow development. Please use \`make <target>\` where <target> is one of"
|
||||||
@echo " clean remove build products"
|
@echo " clean remove build products"
|
||||||
@echo " coverage run coverage test (in progress)"
|
@echo " coverage run coverage test (in progress)"
|
||||||
@echo " doc make HTML docs"
|
@echo " doc make HTML docs"
|
||||||
@echo " docserve run an HTTP server on the docs directory"
|
@echo " docserve run an HTTP server on the docs directory"
|
||||||
@echo " html make HTML docs"
|
@echo " html make HTML docs"
|
||||||
@echo " htmlview open the index page built by the html target in your browser"
|
@echo " htmlview open the index page built by the html target in your browser"
|
||||||
@echo " install make and install"
|
@echo " install make and install"
|
||||||
@echo " install-coverage make and install with C coverage"
|
@echo " install-coverage make and install with C coverage"
|
||||||
@echo " lint run the lint checks"
|
@echo " lint run the lint checks"
|
||||||
@echo " lint-fix run Ruff to (mostly) fix lint issues"
|
@echo " lint-fix run Ruff to (mostly) fix lint issues"
|
||||||
@echo " release-test run code and package tests before release"
|
@echo " release-test run code and package tests before release"
|
||||||
@echo " test run tests on installed Pillow"
|
@echo " test run tests on installed Pillow"
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install:
|
install:
|
||||||
python3 -m pip -v install .
|
python3 -m pip -v install .
|
||||||
python3 selftest.py
|
python3 selftest.py
|
||||||
|
|
||||||
.PHONY: install-coverage
|
.PHONY: install-coverage
|
||||||
install-coverage:
|
install-coverage:
|
||||||
CFLAGS="-coverage -Werror=implicit-function-declaration" python3 -m pip -v install .
|
CFLAGS="-coverage -Werror=implicit-function-declaration" python3 -m pip -v install .
|
||||||
python3 selftest.py
|
python3 selftest.py
|
||||||
|
|
||||||
.PHONY: debug
|
.PHONY: debug
|
||||||
debug:
|
debug:
|
||||||
# make a debug version if we don't have a -dbg python. Leaves in symbols
|
# make a debug version if we don't have a -dbg python. Leaves in symbols
|
||||||
# for our stuff, kills optimization, and redirects to dev null so we
|
# for our stuff, kills optimization, and redirects to dev null so we
|
||||||
# see any build failures.
|
# see any build failures.
|
||||||
make clean > /dev/null
|
make clean > /dev/null
|
||||||
CFLAGS='-g -O0' python3 -m pip -v install . > /dev/null
|
CFLAGS='-g -O0' python3 -m pip -v install . > /dev/null
|
||||||
|
|
||||||
.PHONY: release-test
|
.PHONY: release-test
|
||||||
release-test:
|
release-test:
|
||||||
python3 Tests/check_release_notes.py
|
python3 Tests/check_release_notes.py
|
||||||
python3 -m pip install -e .[tests]
|
python3 -m pip install -e .[tests]
|
||||||
python3 selftest.py
|
python3 selftest.py
|
||||||
python3 -m pytest Tests
|
python3 -m pytest Tests
|
||||||
python3 -m pip install .
|
python3 -m pip install .
|
||||||
python3 -m pytest -qq
|
python3 -m pytest -qq
|
||||||
python3 -m check_manifest
|
python3 -m check_manifest
|
||||||
python3 -m pyroma .
|
python3 -m pyroma .
|
||||||
$(MAKE) readme
|
$(MAKE) readme
|
||||||
|
|
||||||
.PHONY: sdist
|
.PHONY: sdist
|
||||||
sdist:
|
sdist:
|
||||||
python3 -m build --help > /dev/null 2>&1 || python3 -m pip install build
|
python3 -m build --help > /dev/null 2>&1 || python3 -m pip install build
|
||||||
python3 -m build --sdist
|
python3 -m build --sdist
|
||||||
python3 -m twine --help > /dev/null 2>&1 || python3 -m pip install twine
|
python3 -m twine --help > /dev/null 2>&1 || python3 -m pip install twine
|
||||||
python3 -m twine check --strict dist/*
|
python3 -m twine check --strict dist/*
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
python3 -c "import pytest" > /dev/null 2>&1 || python3 -m pip install pytest
|
python3 -c "import pytest" > /dev/null 2>&1 || python3 -m pip install pytest
|
||||||
python3 -m pytest -qq
|
python3 -m pytest -qq
|
||||||
|
|
||||||
.PHONY: valgrind
|
.PHONY: valgrind
|
||||||
valgrind:
|
valgrind:
|
||||||
python3 -c "import pytest_valgrind" > /dev/null 2>&1 || python3 -m pip install pytest-valgrind
|
python3 -c "import pytest_valgrind" > /dev/null 2>&1 || python3 -m pip install pytest-valgrind
|
||||||
PYTHONMALLOC=malloc valgrind --suppressions=Tests/oss-fuzz/python.supp --leak-check=no \
|
PYTHONMALLOC=malloc valgrind --suppressions=Tests/oss-fuzz/python.supp --leak-check=no \
|
||||||
--log-file=/tmp/valgrind-output \
|
--log-file=/tmp/valgrind-output \
|
||||||
python3 -m pytest --no-memcheck -vv --valgrind --valgrind-log=/tmp/valgrind-output
|
python3 -m pytest --no-memcheck -vv --valgrind --valgrind-log=/tmp/valgrind-output
|
||||||
|
|
||||||
.PHONY: readme
|
.PHONY: readme
|
||||||
readme:
|
readme:
|
||||||
python3 -c "import markdown2" > /dev/null 2>&1 || python3 -m pip install markdown2
|
python3 -c "import markdown2" > /dev/null 2>&1 || python3 -m pip install markdown2
|
||||||
python3 -m markdown2 README.md > .long-description.html && open .long-description.html
|
python3 -m markdown2 README.md > .long-description.html && open .long-description.html
|
||||||
|
|
||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint:
|
lint:
|
||||||
python3 -c "import tox" > /dev/null 2>&1 || python3 -m pip install tox
|
python3 -c "import tox" > /dev/null 2>&1 || python3 -m pip install tox
|
||||||
python3 -m tox -e lint
|
python3 -m tox -e lint
|
||||||
|
|
||||||
.PHONY: lint-fix
|
.PHONY: lint-fix
|
||||||
lint-fix:
|
lint-fix:
|
||||||
python3 -c "import black" > /dev/null 2>&1 || python3 -m pip install black
|
python3 -c "import black" > /dev/null 2>&1 || python3 -m pip install black
|
||||||
python3 -m black .
|
python3 -m black .
|
||||||
python3 -c "import ruff" > /dev/null 2>&1 || python3 -m pip install ruff
|
python3 -c "import ruff" > /dev/null 2>&1 || python3 -m pip install ruff
|
||||||
python3 -m ruff --fix .
|
python3 -m ruff --fix .
|
||||||
|
|
||||||
.PHONY: mypy
|
.PHONY: mypy
|
||||||
mypy:
|
mypy:
|
||||||
python3 -c "import tox" > /dev/null 2>&1 || python3 -m pip install tox
|
python3 -c "import tox" > /dev/null 2>&1 || python3 -m pip install tox
|
||||||
python3 -m tox -e mypy
|
python3 -m tox -e mypy
|
||||||
|
|
230
README.md
230
README.md
|
@ -1,115 +1,115 @@
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img width="248" height="250" src="https://raw.githubusercontent.com/python-pillow/pillow-logo/main/pillow-logo-248x250.png" alt="Pillow logo">
|
<img width="248" height="250" src="https://raw.githubusercontent.com/python-pillow/pillow-logo/main/pillow-logo-248x250.png" alt="Pillow logo">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# Pillow
|
# Pillow
|
||||||
|
|
||||||
## Python Imaging Library (Fork)
|
## Python Imaging Library (Fork)
|
||||||
|
|
||||||
Pillow is the friendly PIL fork by [Jeffrey A. Clark and
|
Pillow is the friendly PIL fork by [Jeffrey A. Clark and
|
||||||
contributors](https://github.com/python-pillow/Pillow/graphs/contributors).
|
contributors](https://github.com/python-pillow/Pillow/graphs/contributors).
|
||||||
PIL is the Python Imaging Library by Fredrik Lundh and contributors.
|
PIL is the Python Imaging Library by Fredrik Lundh and contributors.
|
||||||
As of 2019, Pillow development is
|
As of 2019, Pillow development is
|
||||||
[supported by Tidelift](https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=readme&utm_campaign=enterprise).
|
[supported by Tidelift](https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=readme&utm_campaign=enterprise).
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>docs</th>
|
<th>docs</th>
|
||||||
<td>
|
<td>
|
||||||
<a href="https://pillow.readthedocs.io/?badge=latest"><img
|
<a href="https://pillow.readthedocs.io/?badge=latest"><img
|
||||||
alt="Documentation Status"
|
alt="Documentation Status"
|
||||||
src="https://readthedocs.org/projects/pillow/badge/?version=latest"></a>
|
src="https://readthedocs.org/projects/pillow/badge/?version=latest"></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>tests</th>
|
<th>tests</th>
|
||||||
<td>
|
<td>
|
||||||
<a href="https://github.com/python-pillow/Pillow/actions/workflows/lint.yml"><img
|
<a href="https://github.com/python-pillow/Pillow/actions/workflows/lint.yml"><img
|
||||||
alt="GitHub Actions build status (Lint)"
|
alt="GitHub Actions build status (Lint)"
|
||||||
src="https://github.com/python-pillow/Pillow/workflows/Lint/badge.svg"></a>
|
src="https://github.com/python-pillow/Pillow/workflows/Lint/badge.svg"></a>
|
||||||
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test.yml"><img
|
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test.yml"><img
|
||||||
alt="GitHub Actions build status (Test Linux and macOS)"
|
alt="GitHub Actions build status (Test Linux and macOS)"
|
||||||
src="https://github.com/python-pillow/Pillow/workflows/Test/badge.svg"></a>
|
src="https://github.com/python-pillow/Pillow/workflows/Test/badge.svg"></a>
|
||||||
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-windows.yml"><img
|
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-windows.yml"><img
|
||||||
alt="GitHub Actions build status (Test Windows)"
|
alt="GitHub Actions build status (Test Windows)"
|
||||||
src="https://github.com/python-pillow/Pillow/workflows/Test%20Windows/badge.svg"></a>
|
src="https://github.com/python-pillow/Pillow/workflows/Test%20Windows/badge.svg"></a>
|
||||||
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-mingw.yml"><img
|
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-mingw.yml"><img
|
||||||
alt="GitHub Actions build status (Test MinGW)"
|
alt="GitHub Actions build status (Test MinGW)"
|
||||||
src="https://github.com/python-pillow/Pillow/workflows/Test%20MinGW/badge.svg"></a>
|
src="https://github.com/python-pillow/Pillow/workflows/Test%20MinGW/badge.svg"></a>
|
||||||
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-cygwin.yml"><img
|
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-cygwin.yml"><img
|
||||||
alt="GitHub Actions build status (Test Cygwin)"
|
alt="GitHub Actions build status (Test Cygwin)"
|
||||||
src="https://github.com/python-pillow/Pillow/workflows/Test%20Cygwin/badge.svg"></a>
|
src="https://github.com/python-pillow/Pillow/workflows/Test%20Cygwin/badge.svg"></a>
|
||||||
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-docker.yml"><img
|
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-docker.yml"><img
|
||||||
alt="GitHub Actions build status (Test Docker)"
|
alt="GitHub Actions build status (Test Docker)"
|
||||||
src="https://github.com/python-pillow/Pillow/workflows/Test%20Docker/badge.svg"></a>
|
src="https://github.com/python-pillow/Pillow/workflows/Test%20Docker/badge.svg"></a>
|
||||||
<a href="https://ci.appveyor.com/project/python-pillow/Pillow"><img
|
<a href="https://ci.appveyor.com/project/python-pillow/Pillow"><img
|
||||||
alt="AppVeyor CI build status (Windows)"
|
alt="AppVeyor CI build status (Windows)"
|
||||||
src="https://img.shields.io/appveyor/build/python-pillow/Pillow/main.svg?label=Windows%20build"></a>
|
src="https://img.shields.io/appveyor/build/python-pillow/Pillow/main.svg?label=Windows%20build"></a>
|
||||||
<a href="https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml"><img
|
<a href="https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml"><img
|
||||||
alt="GitHub Actions build status (Wheels)"
|
alt="GitHub Actions build status (Wheels)"
|
||||||
src="https://github.com/python-pillow/Pillow/workflows/Wheels/badge.svg"></a>
|
src="https://github.com/python-pillow/Pillow/workflows/Wheels/badge.svg"></a>
|
||||||
<a href="https://app.codecov.io/gh/python-pillow/Pillow"><img
|
<a href="https://app.codecov.io/gh/python-pillow/Pillow"><img
|
||||||
alt="Code coverage"
|
alt="Code coverage"
|
||||||
src="https://codecov.io/gh/python-pillow/Pillow/branch/main/graph/badge.svg"></a>
|
src="https://codecov.io/gh/python-pillow/Pillow/branch/main/graph/badge.svg"></a>
|
||||||
<a href="https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:pillow"><img
|
<a href="https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:pillow"><img
|
||||||
alt="Fuzzing Status"
|
alt="Fuzzing Status"
|
||||||
src="https://oss-fuzz-build-logs.storage.googleapis.com/badges/pillow.svg"></a>
|
src="https://oss-fuzz-build-logs.storage.googleapis.com/badges/pillow.svg"></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>package</th>
|
<th>package</th>
|
||||||
<td>
|
<td>
|
||||||
<a href="https://zenodo.org/badge/latestdoi/17549/python-pillow/Pillow"><img
|
<a href="https://zenodo.org/badge/latestdoi/17549/python-pillow/Pillow"><img
|
||||||
alt="Zenodo"
|
alt="Zenodo"
|
||||||
src="https://zenodo.org/badge/17549/python-pillow/Pillow.svg"></a>
|
src="https://zenodo.org/badge/17549/python-pillow/Pillow.svg"></a>
|
||||||
<a href="https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=badge"><img
|
<a href="https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=badge"><img
|
||||||
alt="Tidelift"
|
alt="Tidelift"
|
||||||
src="https://tidelift.com/badges/package/pypi/pillow?style=flat"></a>
|
src="https://tidelift.com/badges/package/pypi/pillow?style=flat"></a>
|
||||||
<a href="https://pypi.org/project/pillow/"><img
|
<a href="https://pypi.org/project/pillow/"><img
|
||||||
alt="Newest PyPI version"
|
alt="Newest PyPI version"
|
||||||
src="https://img.shields.io/pypi/v/pillow.svg"></a>
|
src="https://img.shields.io/pypi/v/pillow.svg"></a>
|
||||||
<a href="https://pypi.org/project/pillow/"><img
|
<a href="https://pypi.org/project/pillow/"><img
|
||||||
alt="Number of PyPI downloads"
|
alt="Number of PyPI downloads"
|
||||||
src="https://img.shields.io/pypi/dm/pillow.svg"></a>
|
src="https://img.shields.io/pypi/dm/pillow.svg"></a>
|
||||||
<a href="https://www.bestpractices.dev/projects/6331"><img
|
<a href="https://www.bestpractices.dev/projects/6331"><img
|
||||||
alt="OpenSSF Best Practices"
|
alt="OpenSSF Best Practices"
|
||||||
src="https://www.bestpractices.dev/projects/6331/badge"></a>
|
src="https://www.bestpractices.dev/projects/6331/badge"></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>social</th>
|
<th>social</th>
|
||||||
<td>
|
<td>
|
||||||
<a href="https://gitter.im/python-pillow/Pillow?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img
|
<a href="https://gitter.im/python-pillow/Pillow?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img
|
||||||
alt="Join the chat at https://gitter.im/python-pillow/Pillow"
|
alt="Join the chat at https://gitter.im/python-pillow/Pillow"
|
||||||
src="https://badges.gitter.im/python-pillow/Pillow.svg"></a>
|
src="https://badges.gitter.im/python-pillow/Pillow.svg"></a>
|
||||||
<a href="https://fosstodon.org/@pillow"><img
|
<a href="https://fosstodon.org/@pillow"><img
|
||||||
alt="Follow on https://fosstodon.org/@pillow"
|
alt="Follow on https://fosstodon.org/@pillow"
|
||||||
src="https://img.shields.io/badge/publish-on%20Mastodon-595aff.svg"
|
src="https://img.shields.io/badge/publish-on%20Mastodon-595aff.svg"
|
||||||
rel="me"></a>
|
rel="me"></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The Python Imaging Library adds image processing capabilities to your Python interpreter.
|
The Python Imaging Library adds image processing capabilities to your Python interpreter.
|
||||||
|
|
||||||
This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities.
|
This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities.
|
||||||
|
|
||||||
The core image library is designed for fast access to data stored in a few basic pixel formats. It should provide a solid foundation for a general image processing tool.
|
The core image library is designed for fast access to data stored in a few basic pixel formats. It should provide a solid foundation for a general image processing tool.
|
||||||
|
|
||||||
## More Information
|
## More Information
|
||||||
|
|
||||||
- [Documentation](https://pillow.readthedocs.io/)
|
- [Documentation](https://pillow.readthedocs.io/)
|
||||||
- [Installation](https://pillow.readthedocs.io/en/latest/installation/basic-installation.html)
|
- [Installation](https://pillow.readthedocs.io/en/latest/installation/basic-installation.html)
|
||||||
- [Handbook](https://pillow.readthedocs.io/en/latest/handbook/index.html)
|
- [Handbook](https://pillow.readthedocs.io/en/latest/handbook/index.html)
|
||||||
- [Contribute](https://github.com/python-pillow/Pillow/blob/main/.github/CONTRIBUTING.md)
|
- [Contribute](https://github.com/python-pillow/Pillow/blob/main/.github/CONTRIBUTING.md)
|
||||||
- [Issues](https://github.com/python-pillow/Pillow/issues)
|
- [Issues](https://github.com/python-pillow/Pillow/issues)
|
||||||
- [Pull requests](https://github.com/python-pillow/Pillow/pulls)
|
- [Pull requests](https://github.com/python-pillow/Pillow/pulls)
|
||||||
- [Release notes](https://pillow.readthedocs.io/en/stable/releasenotes/index.html)
|
- [Release notes](https://pillow.readthedocs.io/en/stable/releasenotes/index.html)
|
||||||
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
|
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
|
||||||
- [Pre-fork](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst#pre-fork)
|
- [Pre-fork](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst#pre-fork)
|
||||||
|
|
||||||
## Report a Vulnerability
|
## Report a Vulnerability
|
||||||
|
|
||||||
To report a security vulnerability, please follow the procedure described in the [Tidelift security policy](https://tidelift.com/docs/security).
|
To report a security vulnerability, please follow the procedure described in the [Tidelift security policy](https://tidelift.com/docs/security).
|
||||||
|
|
204
RELEASING.md
204
RELEASING.md
|
@ -1,102 +1,102 @@
|
||||||
# Release Checklist
|
# Release Checklist
|
||||||
|
|
||||||
See https://pillow.readthedocs.io/en/stable/releasenotes/versioning.html for
|
See https://pillow.readthedocs.io/en/stable/releasenotes/versioning.html for
|
||||||
information about how the version numbers line up with releases.
|
information about how the version numbers line up with releases.
|
||||||
|
|
||||||
## Main Release
|
## Main Release
|
||||||
|
|
||||||
Released quarterly on January 2nd, April 1st, July 1st and October 15th.
|
Released quarterly on January 2nd, April 1st, July 1st and October 15th.
|
||||||
|
|
||||||
* [ ] Open a release ticket e.g. https://github.com/python-pillow/Pillow/issues/3154
|
* [ ] Open a release ticket e.g. https://github.com/python-pillow/Pillow/issues/3154
|
||||||
* [ ] Develop and prepare release in `main` branch.
|
* [ ] Develop and prepare release in `main` branch.
|
||||||
* [ ] Check [GitHub Actions](https://github.com/python-pillow/Pillow/actions) and [AppVeyor](https://ci.appveyor.com/project/python-pillow/Pillow) to confirm passing tests in `main` branch.
|
* [ ] Check [GitHub Actions](https://github.com/python-pillow/Pillow/actions) and [AppVeyor](https://ci.appveyor.com/project/python-pillow/Pillow) to confirm passing tests in `main` branch.
|
||||||
* [ ] Check that all the wheel builds pass the tests in the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml) jobs by manually triggering them.
|
* [ ] Check that all the wheel builds pass the tests in the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml) jobs by manually triggering them.
|
||||||
* [ ] In compliance with [PEP 440](https://peps.python.org/pep-0440/), update version identifier in `src/PIL/_version.py`
|
* [ ] In compliance with [PEP 440](https://peps.python.org/pep-0440/), update version identifier in `src/PIL/_version.py`
|
||||||
* [ ] Update `CHANGES.rst`.
|
* [ ] Update `CHANGES.rst`.
|
||||||
* [ ] Run pre-release check via `make release-test` in a freshly cloned repo.
|
* [ ] Run pre-release check via `make release-test` in a freshly cloned repo.
|
||||||
* [ ] Create branch and tag for release e.g.:
|
* [ ] Create branch and tag for release e.g.:
|
||||||
```bash
|
```bash
|
||||||
git branch 5.2.x
|
git branch 5.2.x
|
||||||
git tag 5.2.0
|
git tag 5.2.0
|
||||||
git push --tags
|
git push --tags
|
||||||
```
|
```
|
||||||
* [ ] Check the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml)
|
* [ ] Check the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml)
|
||||||
has passed, including the "Upload release to PyPI" job. This will have been triggered
|
has passed, including the "Upload release to PyPI" job. This will have been triggered
|
||||||
by the new tag.
|
by the new tag.
|
||||||
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases).
|
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases).
|
||||||
* [ ] In compliance with [PEP 440](https://peps.python.org/pep-0440/),
|
* [ ] In compliance with [PEP 440](https://peps.python.org/pep-0440/),
|
||||||
increment and append `.dev0` to version identifier in `src/PIL/_version.py` and then:
|
increment and append `.dev0` to version identifier in `src/PIL/_version.py` and then:
|
||||||
```bash
|
```bash
|
||||||
git push --all
|
git push --all
|
||||||
```
|
```
|
||||||
## Point Release
|
## Point Release
|
||||||
|
|
||||||
Released as needed for security, installation or critical bug fixes.
|
Released as needed for security, installation or critical bug fixes.
|
||||||
|
|
||||||
* [ ] Make necessary changes in `main` branch.
|
* [ ] Make necessary changes in `main` branch.
|
||||||
* [ ] Update `CHANGES.rst`.
|
* [ ] Update `CHANGES.rst`.
|
||||||
* [ ] Check out release branch e.g.:
|
* [ ] Check out release branch e.g.:
|
||||||
```bash
|
```bash
|
||||||
git checkout -t remotes/origin/5.2.x
|
git checkout -t remotes/origin/5.2.x
|
||||||
```
|
```
|
||||||
* [ ] Cherry pick individual commits from `main` branch to release branch e.g. `5.2.x`, then `git push`.
|
* [ ] Cherry pick individual commits from `main` branch to release branch e.g. `5.2.x`, then `git push`.
|
||||||
* [ ] Check [GitHub Actions](https://github.com/python-pillow/Pillow/actions) and [AppVeyor](https://ci.appveyor.com/project/python-pillow/Pillow) to confirm passing tests in release branch e.g. `5.2.x`.
|
* [ ] Check [GitHub Actions](https://github.com/python-pillow/Pillow/actions) and [AppVeyor](https://ci.appveyor.com/project/python-pillow/Pillow) to confirm passing tests in release branch e.g. `5.2.x`.
|
||||||
* [ ] In compliance with [PEP 440](https://peps.python.org/pep-0440/), update version identifier in `src/PIL/_version.py`
|
* [ ] In compliance with [PEP 440](https://peps.python.org/pep-0440/), update version identifier in `src/PIL/_version.py`
|
||||||
* [ ] Run pre-release check via `make release-test`.
|
* [ ] Run pre-release check via `make release-test`.
|
||||||
* [ ] Create tag for release e.g.:
|
* [ ] Create tag for release e.g.:
|
||||||
```bash
|
```bash
|
||||||
git tag 5.2.1
|
git tag 5.2.1
|
||||||
git push --tags
|
git push --tags
|
||||||
```
|
```
|
||||||
* [ ] Create and check source distribution:
|
* [ ] Create and check source distribution:
|
||||||
```bash
|
```bash
|
||||||
make sdist
|
make sdist
|
||||||
```
|
```
|
||||||
* [ ] Check the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml)
|
* [ ] Check the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml)
|
||||||
has passed, including the "Upload release to PyPI" job. This will have been triggered
|
has passed, including the "Upload release to PyPI" job. This will have been triggered
|
||||||
by the new tag.
|
by the new tag.
|
||||||
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases) and then:
|
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases) and then:
|
||||||
```bash
|
```bash
|
||||||
git push
|
git push
|
||||||
```
|
```
|
||||||
|
|
||||||
## Embargoed Release
|
## Embargoed Release
|
||||||
|
|
||||||
Released as needed privately to individual vendors for critical security-related bug fixes.
|
Released as needed privately to individual vendors for critical security-related bug fixes.
|
||||||
|
|
||||||
* [ ] Prepare patch for all versions that will get a fix. Test against local installations.
|
* [ ] Prepare patch for all versions that will get a fix. Test against local installations.
|
||||||
* [ ] Commit against `main`, cherry pick to affected release branches.
|
* [ ] Commit against `main`, cherry pick to affected release branches.
|
||||||
* [ ] Run local test matrix on each release & Python version.
|
* [ ] Run local test matrix on each release & Python version.
|
||||||
* [ ] Privately send to distros.
|
* [ ] Privately send to distros.
|
||||||
* [ ] Run pre-release check via `make release-test`
|
* [ ] Run pre-release check via `make release-test`
|
||||||
* [ ] Amend any commits with the CVE #
|
* [ ] Amend any commits with the CVE #
|
||||||
* [ ] On release date, tag and push to GitHub.
|
* [ ] On release date, tag and push to GitHub.
|
||||||
```bash
|
```bash
|
||||||
git checkout 2.5.x
|
git checkout 2.5.x
|
||||||
git tag 2.5.3
|
git tag 2.5.3
|
||||||
git push origin --tags
|
git push origin --tags
|
||||||
```
|
```
|
||||||
* [ ] Check the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml)
|
* [ ] Check the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml)
|
||||||
has passed, including the "Upload release to PyPI" job. This will have been triggered
|
has passed, including the "Upload release to PyPI" job. This will have been triggered
|
||||||
by the new tag.
|
by the new tag.
|
||||||
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases) and then:
|
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases) and then:
|
||||||
```bash
|
```bash
|
||||||
git push origin 2.5.x
|
git push origin 2.5.x
|
||||||
```
|
```
|
||||||
|
|
||||||
## Publicize Release
|
## Publicize Release
|
||||||
|
|
||||||
* [ ] Announce release availability via [Mastodon](https://fosstodon.org/@pillow) e.g. https://fosstodon.org/@pillow/110639450470725321
|
* [ ] Announce release availability via [Mastodon](https://fosstodon.org/@pillow) e.g. https://fosstodon.org/@pillow/110639450470725321
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
* [ ] Make sure the [default version for Read the Docs](https://pillow.readthedocs.io/en/stable/) is up-to-date with the release changes
|
* [ ] Make sure the [default version for Read the Docs](https://pillow.readthedocs.io/en/stable/) is up-to-date with the release changes
|
||||||
|
|
||||||
## Docker Images
|
## Docker Images
|
||||||
|
|
||||||
* [ ] Update Pillow in the Docker Images repository
|
* [ ] Update Pillow in the Docker Images repository
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/python-pillow/docker-images
|
git clone https://github.com/python-pillow/docker-images
|
||||||
cd docker-images
|
cd docker-images
|
||||||
./update-pillow-tag.sh [[release tag]]
|
./update-pillow-tag.sh [[release tag]]
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
if sys.maxsize < 2**32:
|
if sys.maxsize < 2**32:
|
||||||
im = Image.new("L", (999999, 999999), 0)
|
im = Image.new("L", (999999, 999999), 0)
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
Pillow Tests
|
Pillow Tests
|
||||||
============
|
============
|
||||||
|
|
||||||
Test scripts are named ``test_xxx.py``. Helper classes and functions can be found in ``helper.py``.
|
Test scripts are named ``test_xxx.py``. Helper classes and functions can be found in ``helper.py``.
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Install::
|
Install::
|
||||||
|
|
||||||
python3 -m pip install pytest pytest-cov pytest-timeout
|
python3 -m pip install pytest pytest-cov pytest-timeout
|
||||||
|
|
||||||
Execution
|
Execution
|
||||||
---------
|
---------
|
||||||
|
|
||||||
To run an individual test::
|
To run an individual test::
|
||||||
|
|
||||||
pytest Tests/test_image.py
|
pytest Tests/test_image.py
|
||||||
|
|
||||||
Or::
|
Or::
|
||||||
|
|
||||||
pytest -k test_image.py
|
pytest -k test_image.py
|
||||||
|
|
||||||
Run all the tests from the root of the Pillow source distribution::
|
Run all the tests from the root of the Pillow source distribution::
|
||||||
|
|
||||||
pytest
|
pytest
|
||||||
|
|
||||||
Or with coverage::
|
Or with coverage::
|
||||||
|
|
||||||
pytest --cov PIL --cov Tests --cov-report term
|
pytest --cov PIL --cov Tests --cov-report term
|
||||||
coverage html
|
coverage html
|
||||||
open htmlcov/index.html
|
open htmlcov/index.html
|
||||||
|
|
|
@ -1,54 +1,54 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from PIL import PyAccess
|
from PIL import PyAccess
|
||||||
|
|
||||||
from .helper import hopper
|
from .helper import hopper
|
||||||
|
|
||||||
# Not running this test by default. No DOS against CI.
|
# Not running this test by default. No DOS against CI.
|
||||||
|
|
||||||
|
|
||||||
def iterate_get(size, access) -> None:
|
def iterate_get(size, access) -> None:
|
||||||
(w, h) = size
|
(w, h) = size
|
||||||
for x in range(w):
|
for x in range(w):
|
||||||
for y in range(h):
|
for y in range(h):
|
||||||
access[(x, y)]
|
access[(x, y)]
|
||||||
|
|
||||||
|
|
||||||
def iterate_set(size, access) -> None:
|
def iterate_set(size, access) -> None:
|
||||||
(w, h) = size
|
(w, h) = size
|
||||||
for x in range(w):
|
for x in range(w):
|
||||||
for y in range(h):
|
for y in range(h):
|
||||||
access[(x, y)] = (x % 256, y % 256, 0)
|
access[(x, y)] = (x % 256, y % 256, 0)
|
||||||
|
|
||||||
|
|
||||||
def timer(func, label, *args) -> None:
|
def timer(func, label, *args) -> None:
|
||||||
iterations = 5000
|
iterations = 5000
|
||||||
starttime = time.time()
|
starttime = time.time()
|
||||||
for x in range(iterations):
|
for x in range(iterations):
|
||||||
func(*args)
|
func(*args)
|
||||||
if time.time() - starttime > 10:
|
if time.time() - starttime > 10:
|
||||||
break
|
break
|
||||||
endtime = time.time()
|
endtime = time.time()
|
||||||
print(
|
print(
|
||||||
f"{label}: completed {x + 1} iterations in {endtime - starttime:.4f}s, "
|
f"{label}: completed {x + 1} iterations in {endtime - starttime:.4f}s, "
|
||||||
f"{(endtime - starttime) / (x + 1.0):.6f}s per iteration"
|
f"{(endtime - starttime) / (x + 1.0):.6f}s per iteration"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_direct() -> None:
|
def test_direct() -> None:
|
||||||
im = hopper()
|
im = hopper()
|
||||||
im.load()
|
im.load()
|
||||||
# im = Image.new("RGB", (2000, 2000), (1, 3, 2))
|
# im = Image.new("RGB", (2000, 2000), (1, 3, 2))
|
||||||
caccess = im.im.pixel_access(False)
|
caccess = im.im.pixel_access(False)
|
||||||
access = PyAccess.new(im, False)
|
access = PyAccess.new(im, False)
|
||||||
|
|
||||||
assert access is not None
|
assert access is not None
|
||||||
assert caccess[(0, 0)] == access[(0, 0)]
|
assert caccess[(0, 0)] == access[(0, 0)]
|
||||||
|
|
||||||
print(f"Size: {im.width}x{im.height}")
|
print(f"Size: {im.width}x{im.height}")
|
||||||
timer(iterate_get, "PyAccess - get", im.size, access)
|
timer(iterate_get, "PyAccess - get", im.size, access)
|
||||||
timer(iterate_set, "PyAccess - set", im.size, access)
|
timer(iterate_set, "PyAccess - set", im.size, access)
|
||||||
timer(iterate_get, "C-api - get", im.size, caccess)
|
timer(iterate_get, "C-api - get", im.size, caccess)
|
||||||
timer(iterate_set, "C-api - set", im.size, caccess)
|
timer(iterate_set, "C-api - set", im.size, caccess)
|
||||||
|
|
|
@ -1,68 +1,68 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
repro_ss2 = (
|
repro_ss2 = (
|
||||||
"images/fli_oob/06r/06r00.fli",
|
"images/fli_oob/06r/06r00.fli",
|
||||||
"images/fli_oob/06r/others/06r01.fli",
|
"images/fli_oob/06r/others/06r01.fli",
|
||||||
"images/fli_oob/06r/others/06r02.fli",
|
"images/fli_oob/06r/others/06r02.fli",
|
||||||
"images/fli_oob/06r/others/06r03.fli",
|
"images/fli_oob/06r/others/06r03.fli",
|
||||||
"images/fli_oob/06r/others/06r04.fli",
|
"images/fli_oob/06r/others/06r04.fli",
|
||||||
)
|
)
|
||||||
|
|
||||||
repro_lc = (
|
repro_lc = (
|
||||||
"images/fli_oob/05r/05r00.fli",
|
"images/fli_oob/05r/05r00.fli",
|
||||||
"images/fli_oob/05r/others/05r03.fli",
|
"images/fli_oob/05r/others/05r03.fli",
|
||||||
"images/fli_oob/05r/others/05r06.fli",
|
"images/fli_oob/05r/others/05r06.fli",
|
||||||
"images/fli_oob/05r/others/05r05.fli",
|
"images/fli_oob/05r/others/05r05.fli",
|
||||||
"images/fli_oob/05r/others/05r01.fli",
|
"images/fli_oob/05r/others/05r01.fli",
|
||||||
"images/fli_oob/05r/others/05r04.fli",
|
"images/fli_oob/05r/others/05r04.fli",
|
||||||
"images/fli_oob/05r/others/05r02.fli",
|
"images/fli_oob/05r/others/05r02.fli",
|
||||||
"images/fli_oob/05r/others/05r07.fli",
|
"images/fli_oob/05r/others/05r07.fli",
|
||||||
"images/fli_oob/patch0/000000",
|
"images/fli_oob/patch0/000000",
|
||||||
"images/fli_oob/patch0/000001",
|
"images/fli_oob/patch0/000001",
|
||||||
"images/fli_oob/patch0/000002",
|
"images/fli_oob/patch0/000002",
|
||||||
"images/fli_oob/patch0/000003",
|
"images/fli_oob/patch0/000003",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
repro_advance = (
|
repro_advance = (
|
||||||
"images/fli_oob/03r/03r00.fli",
|
"images/fli_oob/03r/03r00.fli",
|
||||||
"images/fli_oob/03r/others/03r01.fli",
|
"images/fli_oob/03r/others/03r01.fli",
|
||||||
"images/fli_oob/03r/others/03r09.fli",
|
"images/fli_oob/03r/others/03r09.fli",
|
||||||
"images/fli_oob/03r/others/03r11.fli",
|
"images/fli_oob/03r/others/03r11.fli",
|
||||||
"images/fli_oob/03r/others/03r05.fli",
|
"images/fli_oob/03r/others/03r05.fli",
|
||||||
"images/fli_oob/03r/others/03r10.fli",
|
"images/fli_oob/03r/others/03r10.fli",
|
||||||
"images/fli_oob/03r/others/03r06.fli",
|
"images/fli_oob/03r/others/03r06.fli",
|
||||||
"images/fli_oob/03r/others/03r08.fli",
|
"images/fli_oob/03r/others/03r08.fli",
|
||||||
"images/fli_oob/03r/others/03r03.fli",
|
"images/fli_oob/03r/others/03r03.fli",
|
||||||
"images/fli_oob/03r/others/03r07.fli",
|
"images/fli_oob/03r/others/03r07.fli",
|
||||||
"images/fli_oob/03r/others/03r02.fli",
|
"images/fli_oob/03r/others/03r02.fli",
|
||||||
"images/fli_oob/03r/others/03r04.fli",
|
"images/fli_oob/03r/others/03r04.fli",
|
||||||
)
|
)
|
||||||
|
|
||||||
repro_brun = (
|
repro_brun = (
|
||||||
"images/fli_oob/04r/initial.fli",
|
"images/fli_oob/04r/initial.fli",
|
||||||
"images/fli_oob/04r/others/04r02.fli",
|
"images/fli_oob/04r/others/04r02.fli",
|
||||||
"images/fli_oob/04r/others/04r05.fli",
|
"images/fli_oob/04r/others/04r05.fli",
|
||||||
"images/fli_oob/04r/others/04r04.fli",
|
"images/fli_oob/04r/others/04r04.fli",
|
||||||
"images/fli_oob/04r/others/04r03.fli",
|
"images/fli_oob/04r/others/04r03.fli",
|
||||||
"images/fli_oob/04r/others/04r01.fli",
|
"images/fli_oob/04r/others/04r01.fli",
|
||||||
"images/fli_oob/04r/04r00.fli",
|
"images/fli_oob/04r/04r00.fli",
|
||||||
)
|
)
|
||||||
|
|
||||||
repro_copy = (
|
repro_copy = (
|
||||||
"images/fli_oob/02r/others/02r02.fli",
|
"images/fli_oob/02r/others/02r02.fli",
|
||||||
"images/fli_oob/02r/others/02r04.fli",
|
"images/fli_oob/02r/others/02r04.fli",
|
||||||
"images/fli_oob/02r/others/02r03.fli",
|
"images/fli_oob/02r/others/02r03.fli",
|
||||||
"images/fli_oob/02r/others/02r01.fli",
|
"images/fli_oob/02r/others/02r01.fli",
|
||||||
"images/fli_oob/02r/02r00.fli",
|
"images/fli_oob/02r/02r00.fli",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
for path in repro_ss2 + repro_lc + repro_advance + repro_brun + repro_copy:
|
for path in repro_ss2 + repro_lc + repro_advance + repro_brun + repro_copy:
|
||||||
with Image.open(path) as im:
|
with Image.open(path) as im:
|
||||||
try:
|
try:
|
||||||
im.load()
|
im.load()
|
||||||
except Exception as msg:
|
except Exception as msg:
|
||||||
print(msg)
|
print(msg)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
TEST_FILE = "Tests/images/fli_overflow.fli"
|
TEST_FILE = "Tests/images/fli_overflow.fli"
|
||||||
|
|
||||||
|
|
||||||
def test_fli_overflow() -> None:
|
def test_fli_overflow() -> None:
|
||||||
# this should not crash with a malloc error or access violation
|
# this should not crash with a malloc error or access violation
|
||||||
with Image.open(TEST_FILE) as im:
|
with Image.open(TEST_FILE) as im:
|
||||||
im.load()
|
im.load()
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Tests potential DOS of IcnsImagePlugin with 0 length block.
|
# Tests potential DOS of IcnsImagePlugin with 0 length block.
|
||||||
# Run from anywhere that PIL is importable.
|
# Run from anywhere that PIL is importable.
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
with Image.open(BytesIO(b"icns\x00\x00\x00\x10hang\x00\x00\x00\x00")):
|
with Image.open(BytesIO(b"icns\x00\x00\x00\x10hang\x00\x00\x00\x00")):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,55 +1,55 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from .helper import is_win32
|
from .helper import is_win32
|
||||||
|
|
||||||
min_iterations = 100
|
min_iterations = 100
|
||||||
max_iterations = 10000
|
max_iterations = 10000
|
||||||
|
|
||||||
pytestmark = pytest.mark.skipif(is_win32(), reason="requires Unix or macOS")
|
pytestmark = pytest.mark.skipif(is_win32(), reason="requires Unix or macOS")
|
||||||
|
|
||||||
|
|
||||||
def _get_mem_usage() -> float:
|
def _get_mem_usage() -> float:
|
||||||
from resource import RUSAGE_SELF, getpagesize, getrusage
|
from resource import RUSAGE_SELF, getpagesize, getrusage
|
||||||
|
|
||||||
mem = getrusage(RUSAGE_SELF).ru_maxrss
|
mem = getrusage(RUSAGE_SELF).ru_maxrss
|
||||||
return mem * getpagesize() / 1024 / 1024
|
return mem * getpagesize() / 1024 / 1024
|
||||||
|
|
||||||
|
|
||||||
def _test_leak(
|
def _test_leak(
|
||||||
min_iterations: int,
|
min_iterations: int,
|
||||||
max_iterations: int,
|
max_iterations: int,
|
||||||
fn: Callable[..., Image.Image | None],
|
fn: Callable[..., Image.Image | None],
|
||||||
*args: Any,
|
*args: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
mem_limit = None
|
mem_limit = None
|
||||||
for i in range(max_iterations):
|
for i in range(max_iterations):
|
||||||
fn(*args)
|
fn(*args)
|
||||||
mem = _get_mem_usage()
|
mem = _get_mem_usage()
|
||||||
if i < min_iterations:
|
if i < min_iterations:
|
||||||
mem_limit = mem + 1
|
mem_limit = mem + 1
|
||||||
continue
|
continue
|
||||||
msg = f"memory usage limit exceeded after {i + 1} iterations"
|
msg = f"memory usage limit exceeded after {i + 1} iterations"
|
||||||
assert mem_limit is not None
|
assert mem_limit is not None
|
||||||
assert mem <= mem_limit, msg
|
assert mem <= mem_limit, msg
|
||||||
|
|
||||||
|
|
||||||
def test_leak_putdata() -> None:
|
def test_leak_putdata() -> None:
|
||||||
im = Image.new("RGB", (25, 25))
|
im = Image.new("RGB", (25, 25))
|
||||||
_test_leak(min_iterations, max_iterations, im.putdata, im.getdata())
|
_test_leak(min_iterations, max_iterations, im.putdata, im.getdata())
|
||||||
|
|
||||||
|
|
||||||
def test_leak_getlist() -> None:
|
def test_leak_getlist() -> None:
|
||||||
im = Image.new("P", (25, 25))
|
im = Image.new("P", (25, 25))
|
||||||
_test_leak(
|
_test_leak(
|
||||||
min_iterations,
|
min_iterations,
|
||||||
max_iterations,
|
max_iterations,
|
||||||
# Pass a new list at each iteration.
|
# Pass a new list at each iteration.
|
||||||
lambda: im.point(range(256)),
|
lambda: im.point(range(256)),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# Tests potential DOS of Jpeg2kImagePlugin with 0 length block.
|
# Tests potential DOS of Jpeg2kImagePlugin with 0 length block.
|
||||||
# Run from anywhere that PIL is importable.
|
# Run from anywhere that PIL is importable.
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
with Image.open(
|
with Image.open(
|
||||||
BytesIO(b"\x00\x00\x00\x0cjP\x20\x20\x0d\x0a\x87\x0a\x00\x00\x00\x00hang")
|
BytesIO(b"\x00\x00\x00\x0cjP\x20\x20\x0d\x0a\x87\x0a\x00\x00\x00\x00hang")
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,44 +1,44 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from .helper import is_win32, skip_unless_feature
|
from .helper import is_win32, skip_unless_feature
|
||||||
|
|
||||||
# Limits for testing the leak
|
# Limits for testing the leak
|
||||||
mem_limit = 1024 * 1048576
|
mem_limit = 1024 * 1048576
|
||||||
stack_size = 8 * 1048576
|
stack_size = 8 * 1048576
|
||||||
iterations = int((mem_limit / stack_size) * 2)
|
iterations = int((mem_limit / stack_size) * 2)
|
||||||
test_file = "Tests/images/rgb_trns_ycbc.jp2"
|
test_file = "Tests/images/rgb_trns_ycbc.jp2"
|
||||||
|
|
||||||
pytestmark = [
|
pytestmark = [
|
||||||
pytest.mark.skipif(is_win32(), reason="requires Unix or macOS"),
|
pytest.mark.skipif(is_win32(), reason="requires Unix or macOS"),
|
||||||
skip_unless_feature("jpg_2000"),
|
skip_unless_feature("jpg_2000"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_leak_load() -> None:
|
def test_leak_load() -> None:
|
||||||
from resource import RLIMIT_AS, RLIMIT_STACK, setrlimit
|
from resource import RLIMIT_AS, RLIMIT_STACK, setrlimit
|
||||||
|
|
||||||
setrlimit(RLIMIT_STACK, (stack_size, stack_size))
|
setrlimit(RLIMIT_STACK, (stack_size, stack_size))
|
||||||
setrlimit(RLIMIT_AS, (mem_limit, mem_limit))
|
setrlimit(RLIMIT_AS, (mem_limit, mem_limit))
|
||||||
for _ in range(iterations):
|
for _ in range(iterations):
|
||||||
with Image.open(test_file) as im:
|
with Image.open(test_file) as im:
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
|
|
||||||
def test_leak_save() -> None:
|
def test_leak_save() -> None:
|
||||||
from resource import RLIMIT_AS, RLIMIT_STACK, setrlimit
|
from resource import RLIMIT_AS, RLIMIT_STACK, setrlimit
|
||||||
|
|
||||||
setrlimit(RLIMIT_STACK, (stack_size, stack_size))
|
setrlimit(RLIMIT_STACK, (stack_size, stack_size))
|
||||||
setrlimit(RLIMIT_AS, (mem_limit, mem_limit))
|
setrlimit(RLIMIT_AS, (mem_limit, mem_limit))
|
||||||
for _ in range(iterations):
|
for _ in range(iterations):
|
||||||
with Image.open(test_file) as im:
|
with Image.open(test_file) as im:
|
||||||
im.load()
|
im.load()
|
||||||
test_output = BytesIO()
|
test_output = BytesIO()
|
||||||
im.save(test_output, "JPEG2000")
|
im.save(test_output, "JPEG2000")
|
||||||
test_output.seek(0)
|
test_output.seek(0)
|
||||||
test_output.read()
|
test_output.read()
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
def test_j2k_overflow(tmp_path: Path) -> None:
|
def test_j2k_overflow(tmp_path: Path) -> None:
|
||||||
im = Image.new("RGBA", (1024, 131584))
|
im = Image.new("RGBA", (1024, 131584))
|
||||||
target = str(tmp_path / "temp.jpc")
|
target = str(tmp_path / "temp.jpc")
|
||||||
with pytest.raises(OSError):
|
with pytest.raises(OSError):
|
||||||
im.save(target)
|
im.save(target)
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
# Reproductions/tests for OOB read errors in FliDecode.c
|
# Reproductions/tests for OOB read errors in FliDecode.c
|
||||||
|
|
||||||
# When run in python, all of these images should fail for
|
# When run in python, all of these images should fail for
|
||||||
# one reason or another, either as a buffer overrun,
|
# one reason or another, either as a buffer overrun,
|
||||||
# unrecognized datastream, or truncated image file.
|
# unrecognized datastream, or truncated image file.
|
||||||
# There shouldn't be any segfaults.
|
# There shouldn't be any segfaults.
|
||||||
#
|
#
|
||||||
# if run like
|
# if run like
|
||||||
# `valgrind --tool=memcheck python check_jp2_overflow.py 2>&1 | grep Decode.c`
|
# `valgrind --tool=memcheck python check_jp2_overflow.py 2>&1 | grep Decode.c`
|
||||||
# the output should be empty. There may be python issues
|
# the output should be empty. There may be python issues
|
||||||
# in the valgrind especially if run in a debug python
|
# in the valgrind especially if run in a debug python
|
||||||
# version.
|
# version.
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
repro = ("00r0_gray_l.jp2", "00r1_graya_la.jp2")
|
repro = ("00r0_gray_l.jp2", "00r1_graya_la.jp2")
|
||||||
|
|
||||||
for path in repro:
|
for path in repro:
|
||||||
with Image.open(path) as im:
|
with Image.open(path) as im:
|
||||||
try:
|
try:
|
||||||
im.load()
|
im.load()
|
||||||
except Exception as msg:
|
except Exception as msg:
|
||||||
print(msg)
|
print(msg)
|
||||||
|
|
|
@ -1,214 +1,214 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from .helper import hopper, is_win32
|
from .helper import hopper, is_win32
|
||||||
|
|
||||||
iterations = 5000
|
iterations = 5000
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
When run on a system without the jpeg leak fixes,
|
When run on a system without the jpeg leak fixes,
|
||||||
the valgrind runs look like this.
|
the valgrind runs look like this.
|
||||||
|
|
||||||
valgrind --tool=massif python test-installed.py -s -v Tests/check_jpeg_leaks.py
|
valgrind --tool=massif python test-installed.py -s -v Tests/check_jpeg_leaks.py
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.skipif(is_win32(), reason="requires Unix or macOS")
|
pytestmark = pytest.mark.skipif(is_win32(), reason="requires Unix or macOS")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pre patch:
|
pre patch:
|
||||||
|
|
||||||
MB
|
MB
|
||||||
31.62^ :
|
31.62^ :
|
||||||
| @:@:@:@#::
|
| @:@:@:@#::
|
||||||
| @:@:@@:@:@:@:@:@#::
|
| @:@:@@:@:@:@:@:@#::
|
||||||
| ::::::::@:@:@@:@:@:@:@:@#::
|
| ::::::::@:@:@@:@:@:@:@:@#::
|
||||||
| :::::@::::::: ::::@:@:@@:@:@:@:@:@#::
|
| :::::@::::::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| ::::::@::::@:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| ::::::@::::@:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| ::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| ::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| :::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| :::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| ::::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| ::::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| : ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| : ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| @: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| @: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| @@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| @@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| :@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| :@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| :@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| :@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| :@:@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| :@:@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| :@:@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| :@:@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
| :@:@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
| :@:@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#::
|
||||||
0 +----------------------------------------------------------------------->Gi
|
0 +----------------------------------------------------------------------->Gi
|
||||||
0 8.535
|
0 8.535
|
||||||
|
|
||||||
|
|
||||||
post-patch:
|
post-patch:
|
||||||
|
|
||||||
MB
|
MB
|
||||||
21.03^ :::@@:::@::::@@:::::::@@::::::::@::::::::::::@:::@:::::::@::::
|
21.03^ :::@@:::@::::@@:::::::@@::::::::@::::::::::::@:::@:::::::@::::
|
||||||
| #:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| #:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| #:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| #:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :::#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :::#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| : :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| : :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| : :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| : :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| @: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| @: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| @@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| @@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| @@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| @@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| @@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| @@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
| :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
| :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@::::
|
||||||
0 +----------------------------------------------------------------------->Gi
|
0 +----------------------------------------------------------------------->Gi
|
||||||
0 8.421
|
0 8.421
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
standard_l_qtable = (
|
standard_l_qtable = (
|
||||||
# fmt: off
|
# fmt: off
|
||||||
16, 11, 10, 16, 24, 40, 51, 61,
|
16, 11, 10, 16, 24, 40, 51, 61,
|
||||||
12, 12, 14, 19, 26, 58, 60, 55,
|
12, 12, 14, 19, 26, 58, 60, 55,
|
||||||
14, 13, 16, 24, 40, 57, 69, 56,
|
14, 13, 16, 24, 40, 57, 69, 56,
|
||||||
14, 17, 22, 29, 51, 87, 80, 62,
|
14, 17, 22, 29, 51, 87, 80, 62,
|
||||||
18, 22, 37, 56, 68, 109, 103, 77,
|
18, 22, 37, 56, 68, 109, 103, 77,
|
||||||
24, 35, 55, 64, 81, 104, 113, 92,
|
24, 35, 55, 64, 81, 104, 113, 92,
|
||||||
49, 64, 78, 87, 103, 121, 120, 101,
|
49, 64, 78, 87, 103, 121, 120, 101,
|
||||||
72, 92, 95, 98, 112, 100, 103, 99,
|
72, 92, 95, 98, 112, 100, 103, 99,
|
||||||
# fmt: on
|
# fmt: on
|
||||||
)
|
)
|
||||||
|
|
||||||
standard_chrominance_qtable = (
|
standard_chrominance_qtable = (
|
||||||
# fmt: off
|
# fmt: off
|
||||||
17, 18, 24, 47, 99, 99, 99, 99,
|
17, 18, 24, 47, 99, 99, 99, 99,
|
||||||
18, 21, 26, 66, 99, 99, 99, 99,
|
18, 21, 26, 66, 99, 99, 99, 99,
|
||||||
24, 26, 56, 99, 99, 99, 99, 99,
|
24, 26, 56, 99, 99, 99, 99, 99,
|
||||||
47, 66, 99, 99, 99, 99, 99, 99,
|
47, 66, 99, 99, 99, 99, 99, 99,
|
||||||
99, 99, 99, 99, 99, 99, 99, 99,
|
99, 99, 99, 99, 99, 99, 99, 99,
|
||||||
99, 99, 99, 99, 99, 99, 99, 99,
|
99, 99, 99, 99, 99, 99, 99, 99,
|
||||||
99, 99, 99, 99, 99, 99, 99, 99,
|
99, 99, 99, 99, 99, 99, 99, 99,
|
||||||
99, 99, 99, 99, 99, 99, 99, 99,
|
99, 99, 99, 99, 99, 99, 99, 99,
|
||||||
# fmt: on
|
# fmt: on
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"qtables",
|
"qtables",
|
||||||
(
|
(
|
||||||
(standard_l_qtable, standard_chrominance_qtable),
|
(standard_l_qtable, standard_chrominance_qtable),
|
||||||
[standard_l_qtable, standard_chrominance_qtable],
|
[standard_l_qtable, standard_chrominance_qtable],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_qtables_leak(qtables: tuple[tuple[int, ...]] | list[tuple[int, ...]]) -> None:
|
def test_qtables_leak(qtables: tuple[tuple[int, ...]] | list[tuple[int, ...]]) -> None:
|
||||||
im = hopper("RGB")
|
im = hopper("RGB")
|
||||||
for _ in range(iterations):
|
for _ in range(iterations):
|
||||||
test_output = BytesIO()
|
test_output = BytesIO()
|
||||||
im.save(test_output, "JPEG", qtables=qtables)
|
im.save(test_output, "JPEG", qtables=qtables)
|
||||||
|
|
||||||
|
|
||||||
def test_exif_leak() -> None:
|
def test_exif_leak() -> None:
|
||||||
"""
|
"""
|
||||||
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
|
||||||
|
|
||||||
for _ in range(iterations):
|
for _ in range(iterations):
|
||||||
test_output = BytesIO()
|
test_output = BytesIO()
|
||||||
im.save(test_output, "JPEG", exif=exif)
|
im.save(test_output, "JPEG", exif=exif)
|
||||||
|
|
||||||
|
|
||||||
def test_base_save() -> None:
|
def test_base_save() -> None:
|
||||||
"""
|
"""
|
||||||
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):
|
||||||
test_output = BytesIO()
|
test_output = BytesIO()
|
||||||
im.save(test_output, "JPEG")
|
im.save(test_output, "JPEG")
|
||||||
|
|
|
@ -1,54 +1,54 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
# This test is not run automatically.
|
# This test is not run automatically.
|
||||||
#
|
#
|
||||||
# It requires > 2gb memory for the >2 gigapixel image generated in the
|
# It requires > 2gb memory for the >2 gigapixel image generated in the
|
||||||
# second test. Running this automatically would amount to a denial of
|
# second test. Running this automatically would amount to a denial of
|
||||||
# service on our testing infrastructure. I expect this test to fail
|
# service on our testing infrastructure. I expect this test to fail
|
||||||
# on any 32-bit machine, as well as any smallish things (like
|
# on any 32-bit machine, as well as any smallish things (like
|
||||||
# Raspberry Pis). It does succeed on a 3gb Ubuntu 12.04x64 VM on Python
|
# Raspberry Pis). It does succeed on a 3gb Ubuntu 12.04x64 VM on Python
|
||||||
# 2.7 and 3.2.
|
# 2.7 and 3.2.
|
||||||
|
|
||||||
|
|
||||||
numpy: ModuleType | None
|
numpy: ModuleType | None
|
||||||
try:
|
try:
|
||||||
import numpy
|
import numpy
|
||||||
except ImportError:
|
except ImportError:
|
||||||
numpy = None
|
numpy = None
|
||||||
|
|
||||||
YDIM = 32769
|
YDIM = 32769
|
||||||
XDIM = 48000
|
XDIM = 48000
|
||||||
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.skipif(sys.maxsize <= 2**32, reason="requires 64-bit system")
|
pytestmark = pytest.mark.skipif(sys.maxsize <= 2**32, reason="requires 64-bit system")
|
||||||
|
|
||||||
|
|
||||||
def _write_png(tmp_path: Path, xdim: int, ydim: int) -> None:
|
def _write_png(tmp_path: Path, xdim: int, ydim: int) -> None:
|
||||||
f = str(tmp_path / "temp.png")
|
f = str(tmp_path / "temp.png")
|
||||||
im = Image.new("L", (xdim, ydim), 0)
|
im = Image.new("L", (xdim, ydim), 0)
|
||||||
im.save(f)
|
im.save(f)
|
||||||
|
|
||||||
|
|
||||||
def test_large(tmp_path: Path) -> None:
|
def test_large(tmp_path: Path) -> None:
|
||||||
"""succeeded prepatch"""
|
"""succeeded prepatch"""
|
||||||
_write_png(tmp_path, XDIM, YDIM)
|
_write_png(tmp_path, XDIM, YDIM)
|
||||||
|
|
||||||
|
|
||||||
def test_2gpx(tmp_path: Path) -> None:
|
def test_2gpx(tmp_path: Path) -> None:
|
||||||
"""failed prepatch"""
|
"""failed prepatch"""
|
||||||
_write_png(tmp_path, XDIM, XDIM)
|
_write_png(tmp_path, XDIM, XDIM)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(numpy is None, reason="Numpy is not installed")
|
@pytest.mark.skipif(numpy is None, reason="Numpy is not installed")
|
||||||
def test_size_greater_than_int() -> None:
|
def test_size_greater_than_int() -> None:
|
||||||
assert numpy is not None
|
assert numpy is not None
|
||||||
arr = numpy.ndarray(shape=(16394, 16394))
|
arr = numpy.ndarray(shape=(16394, 16394))
|
||||||
Image.fromarray(arr)
|
Image.fromarray(arr)
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
# This test is not run automatically.
|
# This test is not run automatically.
|
||||||
#
|
#
|
||||||
# It requires > 2gb memory for the >2 gigapixel image generated in the
|
# It requires > 2gb memory for the >2 gigapixel image generated in the
|
||||||
# second test. Running this automatically would amount to a denial of
|
# second test. Running this automatically would amount to a denial of
|
||||||
# service on our testing infrastructure. I expect this test to fail
|
# service on our testing infrastructure. I expect this test to fail
|
||||||
# on any 32-bit machine, as well as any smallish things (like
|
# on any 32-bit machine, as well as any smallish things (like
|
||||||
# Raspberry Pis).
|
# Raspberry Pis).
|
||||||
|
|
||||||
|
|
||||||
np = pytest.importorskip("numpy", reason="NumPy not installed")
|
np = pytest.importorskip("numpy", reason="NumPy not installed")
|
||||||
|
|
||||||
YDIM = 32769
|
YDIM = 32769
|
||||||
XDIM = 48000
|
XDIM = 48000
|
||||||
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.skipif(sys.maxsize <= 2**32, reason="requires 64-bit system")
|
pytestmark = pytest.mark.skipif(sys.maxsize <= 2**32, reason="requires 64-bit system")
|
||||||
|
|
||||||
|
|
||||||
def _write_png(tmp_path: Path, xdim: int, ydim: int) -> None:
|
def _write_png(tmp_path: Path, xdim: int, ydim: int) -> None:
|
||||||
dtype = np.uint8
|
dtype = np.uint8
|
||||||
a = np.zeros((xdim, ydim), dtype=dtype)
|
a = np.zeros((xdim, ydim), dtype=dtype)
|
||||||
f = str(tmp_path / "temp.png")
|
f = str(tmp_path / "temp.png")
|
||||||
im = Image.fromarray(a, "L")
|
im = Image.fromarray(a, "L")
|
||||||
im.save(f)
|
im.save(f)
|
||||||
|
|
||||||
|
|
||||||
def test_large(tmp_path: Path) -> None:
|
def test_large(tmp_path: Path) -> None:
|
||||||
"""succeeded prepatch"""
|
"""succeeded prepatch"""
|
||||||
_write_png(tmp_path, XDIM, YDIM)
|
_write_png(tmp_path, XDIM, YDIM)
|
||||||
|
|
||||||
|
|
||||||
def test_2gpx(tmp_path: Path) -> None:
|
def test_2gpx(tmp_path: Path) -> None:
|
||||||
"""failed prepatch"""
|
"""failed prepatch"""
|
||||||
_write_png(tmp_path, XDIM, XDIM)
|
_write_png(tmp_path, XDIM, XDIM)
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
TEST_FILE = "Tests/images/libtiff_segfault.tif"
|
TEST_FILE = "Tests/images/libtiff_segfault.tif"
|
||||||
|
|
||||||
|
|
||||||
def test_libtiff_segfault() -> None:
|
def test_libtiff_segfault() -> None:
|
||||||
"""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:
|
||||||
im.load()
|
im.load()
|
||||||
|
|
|
@ -1,65 +1,65 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import zlib
|
import zlib
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from PIL import Image, ImageFile, PngImagePlugin
|
from PIL import Image, ImageFile, PngImagePlugin
|
||||||
|
|
||||||
TEST_FILE = "Tests/images/png_decompression_dos.png"
|
TEST_FILE = "Tests/images/png_decompression_dos.png"
|
||||||
|
|
||||||
|
|
||||||
def test_ignore_dos_text() -> None:
|
def test_ignore_dos_text() -> None:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
im = Image.open(TEST_FILE)
|
im = Image.open(TEST_FILE)
|
||||||
im.load()
|
im.load()
|
||||||
finally:
|
finally:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||||
|
|
||||||
assert isinstance(im, PngImagePlugin.PngImageFile)
|
assert isinstance(im, PngImagePlugin.PngImageFile)
|
||||||
for s in im.text.values():
|
for s in im.text.values():
|
||||||
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
||||||
|
|
||||||
for s in im.info.values():
|
for s in im.info.values():
|
||||||
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
||||||
|
|
||||||
|
|
||||||
def test_dos_text() -> None:
|
def test_dos_text() -> None:
|
||||||
try:
|
try:
|
||||||
im = Image.open(TEST_FILE)
|
im = Image.open(TEST_FILE)
|
||||||
im.load()
|
im.load()
|
||||||
except ValueError as msg:
|
except ValueError as msg:
|
||||||
assert msg, "Decompressed Data Too Large"
|
assert msg, "Decompressed Data Too Large"
|
||||||
return
|
return
|
||||||
|
|
||||||
assert isinstance(im, PngImagePlugin.PngImageFile)
|
assert isinstance(im, PngImagePlugin.PngImageFile)
|
||||||
for s in im.text.values():
|
for s in im.text.values():
|
||||||
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
||||||
|
|
||||||
|
|
||||||
def test_dos_total_memory() -> None:
|
def test_dos_total_memory() -> None:
|
||||||
im = Image.new("L", (1, 1))
|
im = Image.new("L", (1, 1))
|
||||||
compressed_data = zlib.compress(b"a" * 1024 * 1023)
|
compressed_data = zlib.compress(b"a" * 1024 * 1023)
|
||||||
|
|
||||||
info = PngImagePlugin.PngInfo()
|
info = PngImagePlugin.PngInfo()
|
||||||
|
|
||||||
for x in range(64):
|
for x in range(64):
|
||||||
info.add_text(f"t{x}", compressed_data, zip=True)
|
info.add_text(f"t{x}", compressed_data, zip=True)
|
||||||
info.add_itxt(f"i{x}", compressed_data, zip=True)
|
info.add_itxt(f"i{x}", compressed_data, zip=True)
|
||||||
|
|
||||||
b = BytesIO()
|
b = BytesIO()
|
||||||
im.save(b, "PNG", pnginfo=info)
|
im.save(b, "PNG", pnginfo=info)
|
||||||
b.seek(0)
|
b.seek(0)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
im2 = Image.open(b)
|
im2 = Image.open(b)
|
||||||
except ValueError as msg:
|
except ValueError as msg:
|
||||||
assert "Too much memory" in str(msg)
|
assert "Too much memory" in str(msg)
|
||||||
return
|
return
|
||||||
|
|
||||||
total_len = 0
|
total_len = 0
|
||||||
assert isinstance(im2, PngImagePlugin.PngImageFile)
|
assert isinstance(im2, PngImagePlugin.PngImageFile)
|
||||||
for txt in im2.text.values():
|
for txt in im2.text.values():
|
||||||
total_len += len(txt)
|
total_len += len(txt)
|
||||||
assert total_len < 64 * 1024 * 1024, "Total text chunks greater than 64M"
|
assert total_len < 64 * 1024 * 1024, "Total text chunks greater than 64M"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
for rst in Path("docs/releasenotes").glob("[1-9]*.rst"):
|
for rst in Path("docs/releasenotes").glob("[1-9]*.rst"):
|
||||||
if "TODO" in open(rst).read():
|
if "TODO" in open(rst).read():
|
||||||
sys.exit(f"Error: remove TODO from {rst}")
|
sys.exit(f"Error: remove TODO from {rst}")
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from PIL import features
|
from PIL import features
|
||||||
|
|
||||||
|
|
||||||
def test_wheel_modules() -> None:
|
def test_wheel_modules() -> None:
|
||||||
expected_modules = {"pil", "tkinter", "freetype2", "littlecms2", "webp"}
|
expected_modules = {"pil", "tkinter", "freetype2", "littlecms2", "webp"}
|
||||||
|
|
||||||
# tkinter is not available in cibuildwheel installed CPython on Windows
|
# tkinter is not available in cibuildwheel installed CPython on Windows
|
||||||
try:
|
try:
|
||||||
import tkinter
|
import tkinter
|
||||||
|
|
||||||
assert tkinter
|
assert tkinter
|
||||||
except ImportError:
|
except ImportError:
|
||||||
expected_modules.remove("tkinter")
|
expected_modules.remove("tkinter")
|
||||||
|
|
||||||
assert set(features.get_supported_modules()) == expected_modules
|
assert set(features.get_supported_modules()) == expected_modules
|
||||||
|
|
||||||
|
|
||||||
def test_wheel_codecs() -> None:
|
def test_wheel_codecs() -> None:
|
||||||
expected_codecs = {"jpg", "jpg_2000", "zlib", "libtiff"}
|
expected_codecs = {"jpg", "jpg_2000", "zlib", "libtiff"}
|
||||||
|
|
||||||
assert set(features.get_supported_codecs()) == expected_codecs
|
assert set(features.get_supported_codecs()) == expected_codecs
|
||||||
|
|
||||||
|
|
||||||
def test_wheel_features() -> None:
|
def test_wheel_features() -> None:
|
||||||
expected_features = {
|
expected_features = {
|
||||||
"webp_anim",
|
"webp_anim",
|
||||||
"webp_mux",
|
"webp_mux",
|
||||||
"transp_webp",
|
"transp_webp",
|
||||||
"raqm",
|
"raqm",
|
||||||
"fribidi",
|
"fribidi",
|
||||||
"harfbuzz",
|
"harfbuzz",
|
||||||
"libjpeg_turbo",
|
"libjpeg_turbo",
|
||||||
"xcb",
|
"xcb",
|
||||||
}
|
}
|
||||||
|
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
expected_features.remove("xcb")
|
expected_features.remove("xcb")
|
||||||
|
|
||||||
assert set(features.get_supported_features()) == expected_features
|
assert set(features.get_supported_features()) == expected_features
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import io
|
import io
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
def pytest_report_header(config: pytest.Config) -> str:
|
def pytest_report_header(config: pytest.Config) -> str:
|
||||||
try:
|
try:
|
||||||
from PIL import features
|
from PIL import features
|
||||||
|
|
||||||
with io.StringIO() as out:
|
with io.StringIO() as out:
|
||||||
features.pilinfo(out=out, supported_formats=False)
|
features.pilinfo(out=out, supported_formats=False)
|
||||||
return out.getvalue()
|
return out.getvalue()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"pytest_report_header failed: {e}"
|
return f"pytest_report_header failed: {e}"
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure(config: pytest.Config) -> None:
|
def pytest_configure(config: pytest.Config) -> None:
|
||||||
config.addinivalue_line(
|
config.addinivalue_line(
|
||||||
"markers",
|
"markers",
|
||||||
"pil_noop_mark: A conditional mark where nothing special happens",
|
"pil_noop_mark: A conditional mark where nothing special happens",
|
||||||
)
|
)
|
||||||
|
|
||||||
# We're marking some tests to ignore valgrind errors and XFAIL them.
|
# We're marking some tests to ignore valgrind errors and XFAIL them.
|
||||||
# Ensure that the mark is defined
|
# Ensure that the mark is defined
|
||||||
# even in cases where pytest-valgrind isn't installed
|
# even in cases where pytest-valgrind isn't installed
|
||||||
try:
|
try:
|
||||||
config.addinivalue_line(
|
config.addinivalue_line(
|
||||||
"markers",
|
"markers",
|
||||||
"valgrind_known_error: Tests that have known issues with valgrind",
|
"valgrind_known_error: Tests that have known issues with valgrind",
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
# valgrind is already installed
|
# valgrind is already installed
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import os
|
import os
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# create font data chunk for embedding
|
# create font data chunk for embedding
|
||||||
font = "Tests/images/courB08"
|
font = "Tests/images/courB08"
|
||||||
print(" f._load_pilfont_data(")
|
print(" f._load_pilfont_data(")
|
||||||
print(f" # {os.path.basename(font)}")
|
print(f" # {os.path.basename(font)}")
|
||||||
print(" BytesIO(base64.decodestring(b'''")
|
print(" BytesIO(base64.decodestring(b'''")
|
||||||
with open(font + ".pil", "rb") as fp:
|
with open(font + ".pil", "rb") as fp:
|
||||||
print(base64.b64encode(fp.read()).decode())
|
print(base64.b64encode(fp.read()).decode())
|
||||||
print("''')), Image.open(BytesIO(base64.decodestring(b'''")
|
print("''')), Image.open(BytesIO(base64.decodestring(b'''")
|
||||||
with open(font + ".pbm", "rb") as fp:
|
with open(font + ".pbm", "rb") as fp:
|
||||||
print(base64.b64encode(fp.read()).decode())
|
print(base64.b64encode(fp.read()).decode())
|
||||||
print("'''))))")
|
print("'''))))")
|
||||||
|
|
|
@ -1,40 +1,40 @@
|
||||||
DejaVuSans-24-{1,2,4,8}-stripped.ttf are based on DejaVuSans.ttf converted using FontForge to add bitmap strikes and keep only the ASCII range.
|
DejaVuSans-24-{1,2,4,8}-stripped.ttf are based on DejaVuSans.ttf converted using FontForge to add bitmap strikes and keep only the ASCII range.
|
||||||
|
|
||||||
DejaVu Fonts — License
|
DejaVu Fonts — License
|
||||||
Fonts are © Bitstream (see below). DejaVu changes are in public domain. Explanation of copyright is on Gnome page on Bitstream Vera fonts. Glyphs imported from Arev fonts are © Tavmjung Bah (see below)
|
Fonts are © Bitstream (see below). DejaVu changes are in public domain. Explanation of copyright is on Gnome page on Bitstream Vera fonts. Glyphs imported from Arev fonts are © Tavmjung Bah (see below)
|
||||||
|
|
||||||
Bitstream Vera Fonts Copyright
|
Bitstream Vera Fonts Copyright
|
||||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc.
|
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces.
|
The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces.
|
||||||
|
|
||||||
The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera".
|
The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera".
|
||||||
|
|
||||||
This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names.
|
This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names.
|
||||||
|
|
||||||
The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself.
|
The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself.
|
||||||
|
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
|
|
||||||
Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.
|
Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.
|
||||||
|
|
||||||
Arev Fonts Copyright
|
Arev Fonts Copyright
|
||||||
Original text
|
Original text
|
||||||
|
|
||||||
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the modifications to the Bitstream Vera Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the modifications to the Bitstream Vera Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces.
|
The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces.
|
||||||
|
|
||||||
The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Tavmjong Bah" or the word "Arev".
|
The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Tavmjong Bah" or the word "Arev".
|
||||||
|
|
||||||
This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Tavmjong Bah Arev" names.
|
This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Tavmjong Bah Arev" names.
|
||||||
|
|
||||||
The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself.
|
The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself.
|
||||||
|
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
|
|
||||||
Except as contained in this notice, the name of Tavmjong Bah shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from Tavmjong Bah. For further information, contact: tavmjong @ free . fr.
|
Except as contained in this notice, the name of Tavmjong Bah shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from Tavmjong Bah. For further information, contact: tavmjong @ free . fr.
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
|
|
||||||
NotoNastaliqUrdu-Regular.ttf and NotoSansSymbols-Regular.ttf, from https://github.com/googlei18n/noto-fonts
|
NotoNastaliqUrdu-Regular.ttf and NotoSansSymbols-Regular.ttf, from https://github.com/googlei18n/noto-fonts
|
||||||
NotoSans-Regular.ttf, from https://www.google.com/get/noto/
|
NotoSans-Regular.ttf, from https://www.google.com/get/noto/
|
||||||
NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/
|
NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/
|
||||||
AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype
|
AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype
|
||||||
TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny
|
TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny
|
||||||
ArefRuqaa-Regular.ttf, from https://github.com/google/fonts/tree/master/ofl/arefruqaa
|
ArefRuqaa-Regular.ttf, from https://github.com/google/fonts/tree/master/ofl/arefruqaa
|
||||||
ter-x20b.pcf, from http://terminus-font.sourceforge.net/
|
ter-x20b.pcf, from http://terminus-font.sourceforge.net/
|
||||||
BungeeColor-Regular_colr_Windows.ttf, from https://github.com/djrrb/bungee
|
BungeeColor-Regular_colr_Windows.ttf, from https://github.com/djrrb/bungee
|
||||||
OpenSans.woff2, from https://fonts.googleapis.com/css?family=Open+Sans
|
OpenSans.woff2, from https://fonts.googleapis.com/css?family=Open+Sans
|
||||||
|
|
||||||
All of the above fonts are published under the SIL Open Font License (OFL) v1.1 (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), which allows you to copy, modify, and redistribute them if you need to.
|
All of the above fonts are published under the SIL Open Font License (OFL) v1.1 (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), which allows you to copy, modify, and redistribute them if you need to.
|
||||||
|
|
||||||
FreeMono.ttf is licensed under GPLv3, with the GPL font exception.
|
FreeMono.ttf is licensed under GPLv3, with the GPL font exception.
|
||||||
|
|
||||||
OpenSansCondensed-LightItalic.tt, from https://fonts.google.com/specimen/Open+Sans, under Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
OpenSansCondensed-LightItalic.tt, from https://fonts.google.com/specimen/Open+Sans, under Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
|
||||||
chromacheck-sbix.woff, from https://github.com/RoelN/ChromaCheck, under The MIT License (MIT), Copyright (c) 2018 Roel Nieskens, https://pixelambacht.nl Copyright (c) 2018 Google LLC
|
chromacheck-sbix.woff, from https://github.com/RoelN/ChromaCheck, under The MIT License (MIT), Copyright (c) 2018 Roel Nieskens, https://pixelambacht.nl Copyright (c) 2018 Google LLC
|
||||||
|
|
||||||
KhmerOSBattambang-Regular.ttf is licensed under LGPL-2.1 or later.
|
KhmerOSBattambang-Regular.ttf is licensed under LGPL-2.1 or later.
|
||||||
|
|
||||||
FreeMono.ttf is licensed under GPLv3.
|
FreeMono.ttf is licensed under GPLv3.
|
||||||
|
|
||||||
10x20-ISO8859-1.pcf, from https://packages.ubuntu.com/xenial/xfonts-base
|
10x20-ISO8859-1.pcf, from https://packages.ubuntu.com/xenial/xfonts-base
|
||||||
|
|
||||||
"Public domain font. Share and enjoy."
|
"Public domain font. Share and enjoy."
|
||||||
|
|
||||||
CBDTTestFont.ttf and EBDTTestFont.ttf from https://github.com/nulano/font-tests are public domain.
|
CBDTTestFont.ttf and EBDTTestFont.ttf from https://github.com/nulano/font-tests are public domain.
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
STARTFONT
|
STARTFONT
|
||||||
FONT ÿ
|
FONT ÿ
|
||||||
SIZE 10
|
SIZE 10
|
||||||
FONTBOUNDINGBOX
|
FONTBOUNDINGBOX
|
||||||
CHARS
|
CHARS
|
||||||
STARTCHAR
|
STARTCHAR
|
||||||
ENCODING
|
ENCODING
|
||||||
BBX 2 5
|
BBX 2 5
|
||||||
ENDCHAR
|
ENDCHAR
|
||||||
ENDFONT
|
ENDFONT
|
||||||
|
|
744
Tests/helper.py
744
Tests/helper.py
|
@ -1,372 +1,372 @@
|
||||||
"""
|
"""
|
||||||
Helper functions.
|
Helper functions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import tempfile
|
import tempfile
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Any, Callable, Sequence
|
from typing import Any, Callable, Sequence
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from packaging.version import parse as parse_version
|
from packaging.version import parse as parse_version
|
||||||
|
|
||||||
from PIL import Image, ImageMath, features
|
from PIL import Image, ImageMath, features
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
uploader = None
|
uploader = None
|
||||||
if os.environ.get("SHOW_ERRORS"):
|
if os.environ.get("SHOW_ERRORS"):
|
||||||
uploader = "show"
|
uploader = "show"
|
||||||
elif "GITHUB_ACTIONS" in os.environ:
|
elif "GITHUB_ACTIONS" in os.environ:
|
||||||
uploader = "github_actions"
|
uploader = "github_actions"
|
||||||
|
|
||||||
|
|
||||||
def upload(a: Image.Image, b: Image.Image) -> str | None:
|
def upload(a: Image.Image, b: Image.Image) -> str | None:
|
||||||
if uploader == "show":
|
if uploader == "show":
|
||||||
# local img.show for errors.
|
# local img.show for errors.
|
||||||
a.show()
|
a.show()
|
||||||
b.show()
|
b.show()
|
||||||
elif uploader == "github_actions":
|
elif uploader == "github_actions":
|
||||||
dir_errors = os.path.join(os.path.dirname(__file__), "errors")
|
dir_errors = os.path.join(os.path.dirname(__file__), "errors")
|
||||||
os.makedirs(dir_errors, exist_ok=True)
|
os.makedirs(dir_errors, exist_ok=True)
|
||||||
tmpdir = tempfile.mkdtemp(dir=dir_errors)
|
tmpdir = tempfile.mkdtemp(dir=dir_errors)
|
||||||
a.save(os.path.join(tmpdir, "a.png"))
|
a.save(os.path.join(tmpdir, "a.png"))
|
||||||
b.save(os.path.join(tmpdir, "b.png"))
|
b.save(os.path.join(tmpdir, "b.png"))
|
||||||
return tmpdir
|
return tmpdir
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def convert_to_comparable(
|
def convert_to_comparable(
|
||||||
a: Image.Image, b: Image.Image
|
a: Image.Image, b: Image.Image
|
||||||
) -> tuple[Image.Image, Image.Image]:
|
) -> tuple[Image.Image, Image.Image]:
|
||||||
new_a, new_b = a, b
|
new_a, new_b = a, b
|
||||||
if a.mode == "P":
|
if a.mode == "P":
|
||||||
new_a = Image.new("L", a.size)
|
new_a = Image.new("L", a.size)
|
||||||
new_b = Image.new("L", b.size)
|
new_b = Image.new("L", b.size)
|
||||||
new_a.putdata(a.getdata())
|
new_a.putdata(a.getdata())
|
||||||
new_b.putdata(b.getdata())
|
new_b.putdata(b.getdata())
|
||||||
elif a.mode == "I;16":
|
elif a.mode == "I;16":
|
||||||
new_a = a.convert("I")
|
new_a = a.convert("I")
|
||||||
new_b = b.convert("I")
|
new_b = b.convert("I")
|
||||||
return new_a, new_b
|
return new_a, new_b
|
||||||
|
|
||||||
|
|
||||||
def assert_deep_equal(
|
def assert_deep_equal(
|
||||||
a: Sequence[Any], b: Sequence[Any], msg: str | None = None
|
a: Sequence[Any], b: Sequence[Any], msg: str | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
try:
|
try:
|
||||||
assert len(a) == len(b), msg or f"got length {len(a)}, expected {len(b)}"
|
assert len(a) == len(b), msg or f"got length {len(a)}, expected {len(b)}"
|
||||||
except Exception:
|
except Exception:
|
||||||
assert a == b, msg
|
assert a == b, msg
|
||||||
|
|
||||||
|
|
||||||
def assert_image(
|
def assert_image(
|
||||||
im: Image.Image, mode: str, size: tuple[int, int], msg: str | None = None
|
im: Image.Image, mode: str, size: tuple[int, int], msg: str | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
if mode is not None:
|
if mode is not None:
|
||||||
assert im.mode == mode, (
|
assert im.mode == mode, (
|
||||||
msg or f"got mode {repr(im.mode)}, expected {repr(mode)}"
|
msg or f"got mode {repr(im.mode)}, expected {repr(mode)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if size is not None:
|
if size is not None:
|
||||||
assert im.size == size, (
|
assert im.size == size, (
|
||||||
msg or f"got size {repr(im.size)}, expected {repr(size)}"
|
msg or f"got size {repr(im.size)}, expected {repr(size)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def assert_image_equal(a: Image.Image, b: Image.Image, msg: str | None = None) -> None:
|
def assert_image_equal(a: Image.Image, b: Image.Image, msg: str | None = None) -> None:
|
||||||
assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
|
assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
|
||||||
assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
|
assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
|
||||||
if a.tobytes() != b.tobytes():
|
if a.tobytes() != b.tobytes():
|
||||||
try:
|
try:
|
||||||
url = upload(a, b)
|
url = upload(a, b)
|
||||||
if url:
|
if url:
|
||||||
logger.error("URL for test images: %s", url)
|
logger.error("URL for test images: %s", url)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
pytest.fail(msg or "got different content")
|
pytest.fail(msg or "got different content")
|
||||||
|
|
||||||
|
|
||||||
def assert_image_equal_tofile(
|
def assert_image_equal_tofile(
|
||||||
a: Image.Image, filename: str, msg: str | None = None, mode: str | None = None
|
a: Image.Image, filename: str, msg: str | None = None, mode: str | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
with Image.open(filename) as img:
|
with Image.open(filename) as img:
|
||||||
if mode:
|
if mode:
|
||||||
img = img.convert(mode)
|
img = img.convert(mode)
|
||||||
assert_image_equal(a, img, msg)
|
assert_image_equal(a, img, msg)
|
||||||
|
|
||||||
|
|
||||||
def assert_image_similar(
|
def assert_image_similar(
|
||||||
a: Image.Image, b: Image.Image, epsilon: float, msg: str | None = None
|
a: Image.Image, b: Image.Image, epsilon: float, msg: str | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
|
assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
|
||||||
assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
|
assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
|
||||||
|
|
||||||
a, b = convert_to_comparable(a, b)
|
a, b = convert_to_comparable(a, b)
|
||||||
|
|
||||||
diff = 0
|
diff = 0
|
||||||
for ach, bch in zip(a.split(), b.split()):
|
for ach, bch in zip(a.split(), b.split()):
|
||||||
chdiff = ImageMath.lambda_eval(
|
chdiff = ImageMath.lambda_eval(
|
||||||
lambda args: abs(args["a"] - args["b"]), a=ach, b=bch
|
lambda args: abs(args["a"] - args["b"]), a=ach, b=bch
|
||||||
).convert("L")
|
).convert("L")
|
||||||
diff += sum(i * num for i, num in enumerate(chdiff.histogram()))
|
diff += sum(i * num for i, num in enumerate(chdiff.histogram()))
|
||||||
|
|
||||||
ave_diff = diff / (a.size[0] * a.size[1])
|
ave_diff = diff / (a.size[0] * a.size[1])
|
||||||
try:
|
try:
|
||||||
assert epsilon >= ave_diff, (
|
assert epsilon >= ave_diff, (
|
||||||
(msg or "")
|
(msg or "")
|
||||||
+ f" average pixel value difference {ave_diff:.4f} > epsilon {epsilon:.4f}"
|
+ f" average pixel value difference {ave_diff:.4f} > epsilon {epsilon:.4f}"
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
try:
|
try:
|
||||||
url = upload(a, b)
|
url = upload(a, b)
|
||||||
if url:
|
if url:
|
||||||
logger.exception("URL for test images: %s", url)
|
logger.exception("URL for test images: %s", url)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
def assert_image_similar_tofile(
|
def assert_image_similar_tofile(
|
||||||
a: Image.Image,
|
a: Image.Image,
|
||||||
filename: str,
|
filename: str,
|
||||||
epsilon: float,
|
epsilon: float,
|
||||||
msg: str | None = None,
|
msg: str | None = None,
|
||||||
mode: str | None = None,
|
mode: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
with Image.open(filename) as img:
|
with Image.open(filename) as img:
|
||||||
if mode:
|
if mode:
|
||||||
img = img.convert(mode)
|
img = img.convert(mode)
|
||||||
assert_image_similar(a, img, epsilon, msg)
|
assert_image_similar(a, img, epsilon, msg)
|
||||||
|
|
||||||
|
|
||||||
def assert_all_same(items: Sequence[Any], msg: str | None = None) -> None:
|
def assert_all_same(items: Sequence[Any], msg: str | None = None) -> None:
|
||||||
assert items.count(items[0]) == len(items), msg
|
assert items.count(items[0]) == len(items), msg
|
||||||
|
|
||||||
|
|
||||||
def assert_not_all_same(items: Sequence[Any], msg: str | None = None) -> None:
|
def assert_not_all_same(items: Sequence[Any], msg: str | None = None) -> None:
|
||||||
assert items.count(items[0]) != len(items), msg
|
assert items.count(items[0]) != len(items), msg
|
||||||
|
|
||||||
|
|
||||||
def assert_tuple_approx_equal(
|
def assert_tuple_approx_equal(
|
||||||
actuals: Sequence[int], targets: tuple[int, ...], threshold: int, msg: str
|
actuals: Sequence[int], targets: tuple[int, ...], threshold: int, msg: str
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Tests if actuals has values within threshold from targets"""
|
"""Tests if actuals has values within threshold from targets"""
|
||||||
for i, target in enumerate(targets):
|
for i, target in enumerate(targets):
|
||||||
if not (target - threshold <= actuals[i] <= target + threshold):
|
if not (target - threshold <= actuals[i] <= target + threshold):
|
||||||
pytest.fail(msg + ": " + repr(actuals) + " != " + repr(targets))
|
pytest.fail(msg + ": " + repr(actuals) + " != " + repr(targets))
|
||||||
|
|
||||||
|
|
||||||
def skip_unless_feature(feature: str) -> pytest.MarkDecorator:
|
def skip_unless_feature(feature: str) -> pytest.MarkDecorator:
|
||||||
reason = f"{feature} not available"
|
reason = f"{feature} not available"
|
||||||
return pytest.mark.skipif(not features.check(feature), reason=reason)
|
return pytest.mark.skipif(not features.check(feature), reason=reason)
|
||||||
|
|
||||||
|
|
||||||
def skip_unless_feature_version(
|
def skip_unless_feature_version(
|
||||||
feature: str, required: str, reason: str | None = None
|
feature: str, required: str, reason: str | None = None
|
||||||
) -> pytest.MarkDecorator:
|
) -> pytest.MarkDecorator:
|
||||||
version = features.version(feature)
|
version = features.version(feature)
|
||||||
if version is None:
|
if version is None:
|
||||||
return pytest.mark.skip(f"{feature} not available")
|
return pytest.mark.skip(f"{feature} not available")
|
||||||
if reason is None:
|
if reason is None:
|
||||||
reason = f"{feature} is older than {required}"
|
reason = f"{feature} is older than {required}"
|
||||||
version_required = parse_version(required)
|
version_required = parse_version(required)
|
||||||
version_available = parse_version(version)
|
version_available = parse_version(version)
|
||||||
return pytest.mark.skipif(version_available < version_required, reason=reason)
|
return pytest.mark.skipif(version_available < version_required, reason=reason)
|
||||||
|
|
||||||
|
|
||||||
def mark_if_feature_version(
|
def mark_if_feature_version(
|
||||||
mark: pytest.MarkDecorator,
|
mark: pytest.MarkDecorator,
|
||||||
feature: str,
|
feature: str,
|
||||||
version_blacklist: str,
|
version_blacklist: str,
|
||||||
reason: str | None = None,
|
reason: str | None = None,
|
||||||
) -> pytest.MarkDecorator:
|
) -> pytest.MarkDecorator:
|
||||||
version = features.version(feature)
|
version = features.version(feature)
|
||||||
if version is None:
|
if version is None:
|
||||||
return pytest.mark.pil_noop_mark()
|
return pytest.mark.pil_noop_mark()
|
||||||
if reason is None:
|
if reason is None:
|
||||||
reason = f"{feature} is {version_blacklist}"
|
reason = f"{feature} is {version_blacklist}"
|
||||||
version_required = parse_version(version_blacklist)
|
version_required = parse_version(version_blacklist)
|
||||||
version_available = parse_version(version)
|
version_available = parse_version(version)
|
||||||
if (
|
if (
|
||||||
version_available.major == version_required.major
|
version_available.major == version_required.major
|
||||||
and version_available.minor == version_required.minor
|
and version_available.minor == version_required.minor
|
||||||
):
|
):
|
||||||
return mark(reason=reason)
|
return mark(reason=reason)
|
||||||
return pytest.mark.pil_noop_mark()
|
return pytest.mark.pil_noop_mark()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.platform.startswith("win32"), reason="Requires Unix or macOS")
|
@pytest.mark.skipif(sys.platform.startswith("win32"), reason="Requires Unix or macOS")
|
||||||
class PillowLeakTestCase:
|
class PillowLeakTestCase:
|
||||||
# requires unix/macOS
|
# requires unix/macOS
|
||||||
iterations = 100 # count
|
iterations = 100 # count
|
||||||
mem_limit = 512 # k
|
mem_limit = 512 # k
|
||||||
|
|
||||||
def _get_mem_usage(self) -> float:
|
def _get_mem_usage(self) -> float:
|
||||||
"""
|
"""
|
||||||
Gets the RUSAGE memory usage, returns in K. Encapsulates the difference
|
Gets the RUSAGE memory usage, returns in K. Encapsulates the difference
|
||||||
between macOS and Linux rss reporting
|
between macOS and Linux rss reporting
|
||||||
|
|
||||||
:returns: memory usage in kilobytes
|
:returns: memory usage in kilobytes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from resource import RUSAGE_SELF, getrusage
|
from resource import RUSAGE_SELF, getrusage
|
||||||
|
|
||||||
mem = getrusage(RUSAGE_SELF).ru_maxrss
|
mem = getrusage(RUSAGE_SELF).ru_maxrss
|
||||||
# man 2 getrusage:
|
# man 2 getrusage:
|
||||||
# ru_maxrss
|
# ru_maxrss
|
||||||
# This is the maximum resident set size utilized
|
# This is the maximum resident set size utilized
|
||||||
# in bytes on macOS, in kilobytes on Linux
|
# in bytes on macOS, in kilobytes on Linux
|
||||||
return mem / 1024 if sys.platform == "darwin" else mem
|
return mem / 1024 if sys.platform == "darwin" else mem
|
||||||
|
|
||||||
def _test_leak(self, core: Callable[[], None]) -> None:
|
def _test_leak(self, core: Callable[[], None]) -> None:
|
||||||
start_mem = self._get_mem_usage()
|
start_mem = self._get_mem_usage()
|
||||||
for cycle in range(self.iterations):
|
for cycle in range(self.iterations):
|
||||||
core()
|
core()
|
||||||
mem = self._get_mem_usage() - start_mem
|
mem = self._get_mem_usage() - start_mem
|
||||||
msg = f"memory usage limit exceeded in iteration {cycle}"
|
msg = f"memory usage limit exceeded in iteration {cycle}"
|
||||||
assert mem < self.mem_limit, msg
|
assert mem < self.mem_limit, msg
|
||||||
|
|
||||||
|
|
||||||
# helpers
|
# helpers
|
||||||
|
|
||||||
|
|
||||||
def fromstring(data: bytes) -> Image.Image:
|
def fromstring(data: bytes) -> Image.Image:
|
||||||
return Image.open(BytesIO(data))
|
return Image.open(BytesIO(data))
|
||||||
|
|
||||||
|
|
||||||
def tostring(im: Image.Image, string_format: str, **options: Any) -> bytes:
|
def tostring(im: Image.Image, string_format: str, **options: Any) -> bytes:
|
||||||
out = BytesIO()
|
out = BytesIO()
|
||||||
im.save(out, string_format, **options)
|
im.save(out, string_format, **options)
|
||||||
return out.getvalue()
|
return out.getvalue()
|
||||||
|
|
||||||
|
|
||||||
def hopper(mode: str | None = None) -> Image.Image:
|
def hopper(mode: str | None = None) -> Image.Image:
|
||||||
# Use caching to reduce reading from disk, but return a copy
|
# Use caching to reduce reading from disk, but return a copy
|
||||||
# so that the cached image isn't modified by the tests
|
# so that the cached image isn't modified by the tests
|
||||||
# (for fast, isolated, repeatable tests).
|
# (for fast, isolated, repeatable tests).
|
||||||
|
|
||||||
if mode is None:
|
if mode is None:
|
||||||
# Always return fresh not-yet-loaded version of image.
|
# Always return fresh not-yet-loaded version of image.
|
||||||
# Operations on not-yet-loaded images are a separate class of errors
|
# Operations on not-yet-loaded images are a separate class of errors
|
||||||
# that we should catch.
|
# that we should catch.
|
||||||
return Image.open("Tests/images/hopper.ppm")
|
return Image.open("Tests/images/hopper.ppm")
|
||||||
|
|
||||||
return _cached_hopper(mode).copy()
|
return _cached_hopper(mode).copy()
|
||||||
|
|
||||||
|
|
||||||
@lru_cache
|
@lru_cache
|
||||||
def _cached_hopper(mode: str) -> Image.Image:
|
def _cached_hopper(mode: str) -> Image.Image:
|
||||||
if mode == "F":
|
if mode == "F":
|
||||||
im = hopper("L")
|
im = hopper("L")
|
||||||
else:
|
else:
|
||||||
im = hopper()
|
im = hopper()
|
||||||
if mode.startswith("BGR;"):
|
if mode.startswith("BGR;"):
|
||||||
with pytest.warns(DeprecationWarning):
|
with pytest.warns(DeprecationWarning):
|
||||||
im = im.convert(mode)
|
im = im.convert(mode)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
im = im.convert(mode)
|
im = im.convert(mode)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
if mode == "LAB":
|
if mode == "LAB":
|
||||||
im = Image.open("Tests/images/hopper.Lab.tif")
|
im = Image.open("Tests/images/hopper.Lab.tif")
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
return im
|
return im
|
||||||
|
|
||||||
|
|
||||||
def djpeg_available() -> bool:
|
def djpeg_available() -> bool:
|
||||||
if shutil.which("djpeg"):
|
if shutil.which("djpeg"):
|
||||||
try:
|
try:
|
||||||
subprocess.check_call(["djpeg", "-version"])
|
subprocess.check_call(["djpeg", "-version"])
|
||||||
return True
|
return True
|
||||||
except subprocess.CalledProcessError: # pragma: no cover
|
except subprocess.CalledProcessError: # pragma: no cover
|
||||||
return False
|
return False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def cjpeg_available() -> bool:
|
def cjpeg_available() -> bool:
|
||||||
if shutil.which("cjpeg"):
|
if shutil.which("cjpeg"):
|
||||||
try:
|
try:
|
||||||
subprocess.check_call(["cjpeg", "-version"])
|
subprocess.check_call(["cjpeg", "-version"])
|
||||||
return True
|
return True
|
||||||
except subprocess.CalledProcessError: # pragma: no cover
|
except subprocess.CalledProcessError: # pragma: no cover
|
||||||
return False
|
return False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def netpbm_available() -> bool:
|
def netpbm_available() -> bool:
|
||||||
return bool(shutil.which("ppmquant") and shutil.which("ppmtogif"))
|
return bool(shutil.which("ppmquant") and shutil.which("ppmtogif"))
|
||||||
|
|
||||||
|
|
||||||
def magick_command() -> list[str] | None:
|
def magick_command() -> list[str] | None:
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
magickhome = os.environ.get("MAGICK_HOME")
|
magickhome = os.environ.get("MAGICK_HOME")
|
||||||
if magickhome:
|
if magickhome:
|
||||||
imagemagick = [os.path.join(magickhome, "convert.exe")]
|
imagemagick = [os.path.join(magickhome, "convert.exe")]
|
||||||
graphicsmagick = [os.path.join(magickhome, "gm.exe"), "convert"]
|
graphicsmagick = [os.path.join(magickhome, "gm.exe"), "convert"]
|
||||||
else:
|
else:
|
||||||
imagemagick = None
|
imagemagick = None
|
||||||
graphicsmagick = None
|
graphicsmagick = None
|
||||||
else:
|
else:
|
||||||
imagemagick = ["convert"]
|
imagemagick = ["convert"]
|
||||||
graphicsmagick = ["gm", "convert"]
|
graphicsmagick = ["gm", "convert"]
|
||||||
|
|
||||||
if imagemagick and shutil.which(imagemagick[0]):
|
if imagemagick and shutil.which(imagemagick[0]):
|
||||||
return imagemagick
|
return imagemagick
|
||||||
if graphicsmagick and shutil.which(graphicsmagick[0]):
|
if graphicsmagick and shutil.which(graphicsmagick[0]):
|
||||||
return graphicsmagick
|
return graphicsmagick
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def on_appveyor() -> bool:
|
def on_appveyor() -> bool:
|
||||||
return "APPVEYOR" in os.environ
|
return "APPVEYOR" in os.environ
|
||||||
|
|
||||||
|
|
||||||
def on_github_actions() -> bool:
|
def on_github_actions() -> bool:
|
||||||
return "GITHUB_ACTIONS" in os.environ
|
return "GITHUB_ACTIONS" in os.environ
|
||||||
|
|
||||||
|
|
||||||
def on_ci() -> bool:
|
def on_ci() -> bool:
|
||||||
# GitHub Actions and AppVeyor have "CI"
|
# GitHub Actions and AppVeyor have "CI"
|
||||||
return "CI" in os.environ
|
return "CI" in os.environ
|
||||||
|
|
||||||
|
|
||||||
def is_big_endian() -> bool:
|
def is_big_endian() -> bool:
|
||||||
return sys.byteorder == "big"
|
return sys.byteorder == "big"
|
||||||
|
|
||||||
|
|
||||||
def is_ppc64le() -> bool:
|
def is_ppc64le() -> bool:
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
return platform.machine() == "ppc64le"
|
return platform.machine() == "ppc64le"
|
||||||
|
|
||||||
|
|
||||||
def is_win32() -> bool:
|
def is_win32() -> bool:
|
||||||
return sys.platform.startswith("win32")
|
return sys.platform.startswith("win32")
|
||||||
|
|
||||||
|
|
||||||
def is_pypy() -> bool:
|
def is_pypy() -> bool:
|
||||||
return hasattr(sys, "pypy_translation_info")
|
return hasattr(sys, "pypy_translation_info")
|
||||||
|
|
||||||
|
|
||||||
def is_mingw() -> bool:
|
def is_mingw() -> bool:
|
||||||
return sysconfig.get_platform() == "mingw"
|
return sysconfig.get_platform() == "mingw"
|
||||||
|
|
||||||
|
|
||||||
class CachedProperty:
|
class CachedProperty:
|
||||||
def __init__(self, func: Callable[[Any], Any]) -> None:
|
def __init__(self, func: Callable[[Any], Any]) -> None:
|
||||||
self.func = func
|
self.func = func
|
||||||
|
|
||||||
def __get__(self, instance: Any, cls: type[Any] | None = None) -> Any:
|
def __get__(self, instance: Any, cls: type[Any] | None = None) -> Any:
|
||||||
result = instance.__dict__[self.func.__name__] = self.func(instance)
|
result = instance.__dict__[self.func.__name__] = self.func(instance)
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
from http://www.color.org/srgbprofiles.xalter
|
from http://www.color.org/srgbprofiles.xalter
|
||||||
|
|
||||||
Terms of use
|
Terms of use
|
||||||
|
|
||||||
To anyone who acknowledges that the file "sRGB_v4_ICC_preference.icc"
|
To anyone who acknowledges that the file "sRGB_v4_ICC_preference.icc"
|
||||||
is provided "AS IS" WITH NO EXPRESS OR IMPLIED WARRANTY, permission
|
is provided "AS IS" WITH NO EXPRESS OR IMPLIED WARRANTY, permission
|
||||||
to use, copy and distribute this file for any purpose is hereby
|
to use, copy and distribute this file for any purpose is hereby
|
||||||
granted without fee, provided that the file is not changed including
|
granted without fee, provided that the file is not changed including
|
||||||
the ICC copyright notice tag, and that the name of ICC shall not be
|
the ICC copyright notice tag, and that the name of ICC shall not be
|
||||||
used in advertising or publicity pertaining to distribution of the
|
used in advertising or publicity pertaining to distribution of the
|
||||||
software without specific, written prior permission. ICC makes no
|
software without specific, written prior permission. ICC makes no
|
||||||
representations about the suitability of this software for any
|
representations about the suitability of this software for any
|
||||||
purpose.
|
purpose.
|
||||||
|
|
||||||
|
|
||||||
To anyone who acknowledges that the file
|
To anyone who acknowledges that the file
|
||||||
"sRGB_IEC61966-2-1_black_scaled.icc" is provided "AS IS" WITH NO
|
"sRGB_IEC61966-2-1_black_scaled.icc" is provided "AS IS" WITH NO
|
||||||
EXPRESS OR IMPLIED WARRANTY, permission to use, copy and distribute
|
EXPRESS OR IMPLIED WARRANTY, permission to use, copy and distribute
|
||||||
these file for any purpose is hereby granted without fee, provided
|
these file for any purpose is hereby granted without fee, provided
|
||||||
that the file is not changed including the ICC copyright notice tag,
|
that the file is not changed including the ICC copyright notice tag,
|
||||||
and that the name of ICC shall not be used in advertising or publicity
|
and that the name of ICC shall not be used in advertising or publicity
|
||||||
pertaining to distribution of the software without specific, written
|
pertaining to distribution of the software without specific, written
|
||||||
prior permission. ICC makes no representations about the suitability
|
prior permission. ICC makes no representations about the suitability
|
||||||
of this software for any purpose.
|
of this software for any purpose.
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
GIMP Palette
|
GIMP Palette
|
||||||
Name: badpaletteentry
|
Name: badpaletteentry
|
||||||
Columns: 4
|
Columns: 4
|
||||||
#
|
#
|
||||||
0 0 0 Index 3
|
0 0 0 Index 3
|
||||||
65 38
|
65 38
|
||||||
103 62 49 Index 6
|
103 62 49 Index 6
|
||||||
79 73 72 Index 7
|
79 73 72 Index 7
|
||||||
114 101 97 Index 8
|
114 101 97 Index 8
|
||||||
208 127 100 Index 9
|
208 127 100 Index 9
|
||||||
151 144 142 Index 10
|
151 144 142 Index 10
|
||||||
221 207 199 Index 11
|
221 207 199 Index 11
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
GIMP Palette
|
GIMP Palette
|
||||||
Name: badpalettefile
|
Name: badpalettefile
|
||||||
Columns: 4
|
Columns: 4
|
||||||
#
|
#
|
||||||
0 0 0 Index 3
|
0 0 0 Index 3
|
||||||
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
|
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||||
103 62 49 Index 6
|
103 62 49 Index 6
|
||||||
79 73 72 Index 7
|
79 73 72 Index 7
|
||||||
114 101 97 Index 8
|
114 101 97 Index 8
|
||||||
208 127 100 Index 9
|
208 127 100 Index 9
|
||||||
151 144 142 Index 10
|
151 144 142 Index 10
|
||||||
221 207 199 Index 11
|
221 207 199 Index 11
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
These images are from the bmpsuite:
|
These images are from the bmpsuite:
|
||||||
https://github.com/jsummers/bmpsuite and are in the public domain
|
https://github.com/jsummers/bmpsuite and are in the public domain
|
||||||
according to the readme in the project.
|
according to the readme in the project.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,28 +1,28 @@
|
||||||
#This is the script that was used to create our sample EPS files
|
#This is the script that was used to create our sample EPS files
|
||||||
#We used the following version of the gnuplot program
|
#We used the following version of the gnuplot program
|
||||||
#G N U P L O T
|
#G N U P L O T
|
||||||
#Version 4.6 patchlevel 3 last modified 2013-04-12
|
#Version 4.6 patchlevel 3 last modified 2013-04-12
|
||||||
#Build System: Darwin x86_64
|
#Build System: Darwin x86_64
|
||||||
|
|
||||||
#This file will generate the non_zero_bb.eps variant, in order to get the
|
#This file will generate the non_zero_bb.eps variant, in order to get the
|
||||||
#zero_bb.eps variant you will need to edit line6 in the result file to
|
#zero_bb.eps variant you will need to edit line6 in the result file to
|
||||||
#be "%%BoundingBox: 0 0 460 352" instead of "%%BoundingBox: 50 50 410 302"
|
#be "%%BoundingBox: 0 0 460 352" instead of "%%BoundingBox: 50 50 410 302"
|
||||||
|
|
||||||
set t postscript eps color
|
set t postscript eps color
|
||||||
set o "sample.eps"
|
set o "sample.eps"
|
||||||
set dummy u,v
|
set dummy u,v
|
||||||
set key bmargin center horizontal Right noreverse enhanced autotitles nobox
|
set key bmargin center horizontal Right noreverse enhanced autotitles nobox
|
||||||
set parametric
|
set parametric
|
||||||
set view 50, 30, 1, 1
|
set view 50, 30, 1, 1
|
||||||
set isosamples 10, 10
|
set isosamples 10, 10
|
||||||
set hidden3d back offset 1 trianglepattern 3 undefined 1 altdiagonal bentover
|
set hidden3d back offset 1 trianglepattern 3 undefined 1 altdiagonal bentover
|
||||||
set ticslevel 0
|
set ticslevel 0
|
||||||
set title "Interlocking Tori"
|
set title "Interlocking Tori"
|
||||||
|
|
||||||
set style line 1 lt 1 lw 1 pt 3 lc rgb "red"
|
set style line 1 lt 1 lw 1 pt 3 lc rgb "red"
|
||||||
set style line 2 lt 1 lw 1 pt 3 lc rgb "blue"
|
set style line 2 lt 1 lw 1 pt 3 lc rgb "blue"
|
||||||
|
|
||||||
set urange [ -3.14159 : 3.14159 ] noreverse nowriteback
|
set urange [ -3.14159 : 3.14159 ] noreverse nowriteback
|
||||||
set vrange [ -3.14159 : 3.14159 ] noreverse nowriteback
|
set vrange [ -3.14159 : 3.14159 ] noreverse nowriteback
|
||||||
splot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) ls 1,\
|
splot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) ls 1,\
|
||||||
1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) ls 2
|
1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) ls 2
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
GIMP Palette
|
GIMP Palette
|
||||||
Name: custompalette
|
Name: custompalette
|
||||||
Columns: 4
|
Columns: 4
|
||||||
#
|
#
|
||||||
0 0 0 Index 3
|
0 0 0 Index 3
|
||||||
65 38 30 Index 4
|
65 38 30 Index 4
|
||||||
103 62 49 Index 6
|
103 62 49 Index 6
|
||||||
79 73 72 Index 7
|
79 73 72 Index 7
|
||||||
114 101 97 Index 8
|
114 101 97 Index 8
|
||||||
208 127 100 Index 9
|
208 127 100 Index 9
|
||||||
151 144 142 Index 10
|
151 144 142 Index 10
|
||||||
221 207 199 Index 11
|
221 207 199 Index 11
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Is this because a file-originating field is being interpreted as a *signed* int32, allowing it to provide negative values for 'advance'?
|
Is this because a file-originating field is being interpreted as a *signed* int32, allowing it to provide negative values for 'advance'?
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Image.open(...).seek(212)
|
Image.open(...).seek(212)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
ridiculous bytes value passed to ImagingFliDecode
|
ridiculous bytes value passed to ImagingFliDecode
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
im = Image.open(d); im.seek(0); im.getdata()
|
im = Image.open(d); im.seek(0); im.getdata()
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
failure to check input buffer (`data`) boundaries in BRUN chunk
|
failure to check input buffer (`data`) boundaries in BRUN chunk
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
im = Image.open(d); im.seek(0); im.getdata()
|
im = Image.open(d); im.seek(0); im.getdata()
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
failure to check input buffer (`data`) boundaries in LC chunk
|
failure to check input buffer (`data`) boundaries in LC chunk
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
im = Image.open(d); im.seek(0); im.getdata()
|
im = Image.open(d); im.seek(0); im.getdata()
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
failure to check input buffer (`data`) boundaries in SS2 chunk
|
failure to check input buffer (`data`) boundaries in SS2 chunk
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
im = Image.open(d); im.seek(0); im.getdata()
|
im = Image.open(d); im.seek(0); im.getdata()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
GIMP Gradient
|
GIMP Gradient
|
||||||
4
|
4
|
||||||
0.000000 0.351923 0.534893 1.000000 1.000000 1.000000 0.910000 0.730303 0.510606 1.000000 0.480000 1 0
|
0.000000 0.351923 0.534893 1.000000 1.000000 1.000000 0.910000 0.730303 0.510606 1.000000 0.480000 1 0
|
||||||
0.501504 0.611002 0.637730 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1 0
|
0.501504 0.611002 0.637730 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1 0
|
||||||
0.931891 0.951264 1.000000 0.531255 0.316078 1.031173 1.000000 0.000000 0.000000 0.000000 1.000000 0 0
|
0.931891 0.951264 1.000000 0.531255 0.316078 1.031173 1.000000 0.000000 0.000000 0.000000 1.000000 0 0
|
||||||
0.810551 0.881217 0.921883 0.717576 0.441331 0.081217 1.000000 0.751576 0.410331 0.081217 1.000000 0 0
|
0.810551 0.881217 0.921883 0.717576 0.441331 0.081217 1.000000 0.751576 0.410331 0.081217 1.000000 0 0
|
|
@ -1,7 +1,7 @@
|
||||||
GIMP Gradient
|
GIMP Gradient
|
||||||
Name: A GIMP 1.3 gradient file
|
Name: A GIMP 1.3 gradient file
|
||||||
4
|
4
|
||||||
0.000000 0.351923 0.534893 1.000000 1.000000 1.000000 0.910000 0.730303 0.510606 1.000000 0.480000 1 0
|
0.000000 0.351923 0.534893 1.000000 1.000000 1.000000 0.910000 0.730303 0.510606 1.000000 0.480000 1 0
|
||||||
0.501504 0.611002 0.637730 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1 0
|
0.501504 0.611002 0.637730 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1 0
|
||||||
0.931891 0.951264 1.000000 0.531255 0.316078 1.031173 1.000000 0.000000 0.000000 0.000000 1.000000 0 0
|
0.931891 0.951264 1.000000 0.531255 0.316078 1.031173 1.000000 0.000000 0.000000 0.000000 1.000000 0 0
|
||||||
0.810551 0.881217 0.921883 0.717576 0.441331 0.081217 1.000000 0.751576 0.410331 0.081217 1.000000 0 0
|
0.810551 0.881217 0.921883 0.717576 0.441331 0.081217 1.000000 0.751576 0.410331 0.081217 1.000000 0 0
|
|
@ -1,174 +1,174 @@
|
||||||
#define hopper_width 128
|
#define hopper_width 128
|
||||||
#define hopper_height 128
|
#define hopper_height 128
|
||||||
static char hopper_bits[] = {
|
static char hopper_bits[] = {
|
||||||
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0x3D, 0x80, 0x96, 0xDA, 0xB6, 0xD6, 0x2A,
|
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0x3D, 0x80, 0x96, 0xDA, 0xB6, 0xD6, 0x2A,
|
||||||
0xA9, 0x6D, 0x25, 0x29, 0xFF, 0xFF, 0xFF, 0xBF, 0xFE, 0x7D, 0xC0, 0xFB,
|
0xA9, 0x6D, 0x25, 0x29, 0xFF, 0xFF, 0xFF, 0xBF, 0xFE, 0x7D, 0xC0, 0xFB,
|
||||||
0x69, 0x69, 0xA9, 0xD5, 0x96, 0x96, 0x5E, 0x9A, 0xFF, 0xFF, 0xFF, 0x9F,
|
0x69, 0x69, 0xA9, 0xD5, 0x96, 0x96, 0x5E, 0x9A, 0xFF, 0xFF, 0xFF, 0x9F,
|
||||||
0xFE, 0xFD, 0x80, 0xFF, 0x97, 0xB6, 0x5A, 0x6A, 0x5D, 0x6D, 0x5A, 0x62,
|
0xFE, 0xFD, 0x80, 0xFF, 0x97, 0xB6, 0x5A, 0x6A, 0x5D, 0x6D, 0x5A, 0x62,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xC1, 0xCF, 0x5F, 0x89, 0xA5, 0xD5,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xC1, 0xCF, 0x5F, 0x89, 0xA5, 0xD5,
|
||||||
0xAA, 0x92, 0xA5, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xF8, 0x00,
|
0xAA, 0x92, 0xA5, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xF8, 0x00,
|
||||||
0xB8, 0x59, 0xAA, 0x56, 0xDA, 0x5A, 0x56, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xB8, 0x59, 0xAA, 0x56, 0xDA, 0x5A, 0x56, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFE, 0xFC, 0xF9, 0x00, 0xF0, 0xA6, 0x55, 0xA9, 0x65, 0xA5, 0xA9, 0xA2,
|
0xFE, 0xFC, 0xF9, 0x00, 0xF0, 0xA6, 0x55, 0xA9, 0x65, 0xA5, 0xA9, 0xA2,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0x71, 0x00, 0x60, 0x70, 0xAA, 0x54,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0x71, 0x00, 0x60, 0x70, 0xAA, 0x54,
|
||||||
0xAA, 0x5A, 0x54, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0x38, 0x00,
|
0xAA, 0x5A, 0x54, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0x38, 0x00,
|
||||||
0xE0, 0x80, 0x55, 0xAB, 0x55, 0x75, 0xAB, 0x56, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xE0, 0x80, 0x55, 0xAB, 0x55, 0x75, 0xAB, 0x56, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFE, 0x1D, 0x70, 0x00, 0xF0, 0x00, 0xAE, 0xAA, 0xAA, 0xA6, 0x95, 0x55,
|
0xFE, 0x1D, 0x70, 0x00, 0xF0, 0x00, 0xAE, 0xAA, 0xAA, 0xA6, 0x95, 0x55,
|
||||||
0xFB, 0xFF, 0xFF, 0xFF, 0xFE, 0x1D, 0xF0, 0x00, 0xF0, 0x00, 0x50, 0x55,
|
0xFB, 0xFF, 0xFF, 0xFF, 0xFE, 0x1D, 0xF0, 0x00, 0xF0, 0x00, 0x50, 0x55,
|
||||||
0x55, 0x59, 0x6A, 0xAA, 0xF3, 0xFF, 0xFF, 0xFF, 0xFE, 0x04, 0xF0, 0x00,
|
0x55, 0x59, 0x6A, 0xAA, 0xF3, 0xFF, 0xFF, 0xFF, 0xFE, 0x04, 0xF0, 0x00,
|
||||||
0xF0, 0x00, 0xA4, 0xAA, 0xA9, 0xA5, 0x95, 0x55, 0x21, 0xFF, 0xFF, 0xFF,
|
0xF0, 0x00, 0xA4, 0xAA, 0xA9, 0xA5, 0x95, 0x55, 0x21, 0xFF, 0xFF, 0xFF,
|
||||||
0xFE, 0x01, 0xF8, 0x00, 0xF0, 0x00, 0x50, 0x55, 0x56, 0x5A, 0x6A, 0xAA,
|
0xFE, 0x01, 0xF8, 0x00, 0xF0, 0x00, 0x50, 0x55, 0x56, 0x5A, 0x6A, 0xAA,
|
||||||
0x83, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0xFC, 0x00, 0xF0, 0x01, 0x50, 0xD5,
|
0x83, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0xFC, 0x00, 0xF0, 0x01, 0x50, 0xD5,
|
||||||
0x95, 0x95, 0xA5, 0x5A, 0x83, 0x9F, 0xFF, 0xFF, 0xFE, 0x81, 0xFF, 0x00,
|
0x95, 0x95, 0xA5, 0x5A, 0x83, 0x9F, 0xFF, 0xFF, 0xFE, 0x81, 0xFF, 0x00,
|
||||||
0xE0, 0x0B, 0xA0, 0xAA, 0x7A, 0x6A, 0x5A, 0x65, 0x80, 0x1F, 0xF0, 0xFF,
|
0xE0, 0x0B, 0xA0, 0xAA, 0x7A, 0x6A, 0x5A, 0x65, 0x80, 0x1F, 0xF0, 0xFF,
|
||||||
0xFE, 0xF0, 0xFF, 0x00, 0xF0, 0x3F, 0x50, 0x55, 0xA5, 0xB5, 0xA5, 0xAA,
|
0xFE, 0xF0, 0xFF, 0x00, 0xF0, 0x3F, 0x50, 0x55, 0xA5, 0xB5, 0xA5, 0xAA,
|
||||||
0x00, 0x1F, 0xF8, 0xFD, 0xFE, 0xF0, 0xF7, 0x00, 0xF0, 0x6D, 0xA0, 0xAA,
|
0x00, 0x1F, 0xF8, 0xFD, 0xFE, 0xF0, 0xF7, 0x00, 0xF0, 0x6D, 0xA0, 0xAA,
|
||||||
0x5A, 0x6A, 0x5A, 0x55, 0x83, 0x0F, 0xF8, 0xC9, 0xFE, 0x79, 0x00, 0xF8,
|
0x5A, 0x6A, 0x5A, 0x55, 0x83, 0x0F, 0xF8, 0xC9, 0xFE, 0x79, 0x00, 0xF8,
|
||||||
0x02, 0xC0, 0x81, 0x55, 0xAD, 0xD5, 0xA5, 0xA6, 0xE3, 0x03, 0xFC, 0xC0,
|
0x02, 0xC0, 0x81, 0x55, 0xAD, 0xD5, 0xA5, 0xA6, 0xE3, 0x03, 0xFC, 0xC0,
|
||||||
0xFE, 0xFF, 0x04, 0xF0, 0x00, 0x80, 0x63, 0xAA, 0x52, 0x2A, 0x5A, 0x58,
|
0xFE, 0xFF, 0x04, 0xF0, 0x00, 0x80, 0x63, 0xAA, 0x52, 0x2A, 0x5A, 0x58,
|
||||||
0xE7, 0x03, 0xFC, 0xE1, 0xFE, 0xFF, 0x2F, 0xFC, 0x03, 0x0C, 0xFE, 0x55,
|
0xE7, 0x03, 0xFC, 0xE1, 0xFE, 0xFF, 0x2F, 0xFC, 0x03, 0x0C, 0xFE, 0x55,
|
||||||
0xA9, 0x55, 0x66, 0x15, 0xF3, 0x0F, 0x7C, 0xF0, 0xFE, 0xFF, 0xFF, 0xFD,
|
0xA9, 0x55, 0x66, 0x15, 0xF3, 0x0F, 0x7C, 0xF0, 0xFE, 0xFF, 0xFF, 0xFD,
|
||||||
0xEF, 0x38, 0xFF, 0xAA, 0x56, 0xAA, 0x99, 0xAA, 0xF7, 0x1F, 0x78, 0xF0,
|
0xEF, 0x38, 0xFF, 0xAA, 0x56, 0xAA, 0x99, 0xAA, 0xF7, 0x1F, 0x78, 0xF0,
|
||||||
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0x55, 0xAA, 0x5B, 0x66, 0xA4,
|
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0x55, 0xAA, 0x5B, 0x66, 0xA4,
|
||||||
0xFF, 0x9F, 0xFD, 0xF0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB,
|
0xFF, 0x9F, 0xFD, 0xF0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB,
|
||||||
0x65, 0xA4, 0x99, 0x1B, 0xFF, 0xDF, 0xFF, 0xE0, 0xFE, 0xFF, 0xFF, 0xFF,
|
0x65, 0xA4, 0x99, 0x1B, 0xFF, 0xDF, 0xFF, 0xE0, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x69, 0x51, 0x5A, 0x24, 0x62, 0xFF, 0xDF, 0xFF, 0xEC,
|
0xFF, 0xFF, 0xFF, 0x69, 0x51, 0x5A, 0x24, 0x62, 0xFF, 0xDF, 0xFF, 0xEC,
|
||||||
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0xAA, 0x24, 0x59, 0x55,
|
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0xAA, 0x24, 0x59, 0x55,
|
||||||
0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x25,
|
0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x25,
|
||||||
0x49, 0xAD, 0x55, 0x2A, 0xFF, 0xFF, 0xFF, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF,
|
0x49, 0xAD, 0x55, 0x2A, 0xFF, 0xFF, 0xFF, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x9B, 0xA5, 0x52, 0x2A, 0x94, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0x9B, 0xA5, 0x52, 0x2A, 0x94, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x67, 0x64, 0xC1, 0x92, 0x6D,
|
0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x67, 0x64, 0xC1, 0x92, 0x6D,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95,
|
||||||
0x49, 0x2C, 0x55, 0x92, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF,
|
0x49, 0x2C, 0x55, 0x92, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||||
0x7F, 0xFF, 0xFF, 0x15, 0xB4, 0x62, 0x44, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x7F, 0xFF, 0xFF, 0x15, 0xB4, 0x62, 0x44, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFD, 0xFF, 0x51, 0x30, 0x03, 0xE0, 0xFF, 0x53, 0x03, 0x89, 0x96, 0x92,
|
0xFD, 0xFF, 0x51, 0x30, 0x03, 0xE0, 0xFF, 0x53, 0x03, 0x89, 0x96, 0x92,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x7F, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xCD,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x7F, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xCD,
|
||||||
0x68, 0x19, 0x68, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0x00, 0x00,
|
0x68, 0x19, 0x68, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0x00, 0x00,
|
||||||
0x00, 0x00, 0xFF, 0x13, 0x4A, 0x64, 0x23, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x00, 0x00, 0xFF, 0x13, 0x4A, 0x64, 0x23, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x47, 0x8A, 0xA4, 0xD8, 0x30,
|
0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x47, 0x8A, 0xA4, 0xD8, 0x30,
|
||||||
0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x39,
|
0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x39,
|
||||||
0x29, 0x49, 0x06, 0x86, 0xCC, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0x00, 0x00,
|
0x29, 0x49, 0x06, 0x86, 0xCC, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0x00, 0x00,
|
||||||
0x80, 0x00, 0xF2, 0x81, 0x50, 0x31, 0xA2, 0x8C, 0xE4, 0xFF, 0xFF, 0xFF,
|
0x80, 0x00, 0xF2, 0x81, 0x50, 0x31, 0xA2, 0x8C, 0xE4, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0x0A, 0x08, 0x00, 0x00, 0x00, 0xF0, 0xA7, 0x46, 0x8C, 0x28, 0x31,
|
0xFF, 0x0A, 0x08, 0x00, 0x00, 0x00, 0xF0, 0xA7, 0x46, 0x8C, 0x28, 0x31,
|
||||||
0xC0, 0xFC, 0xFF, 0xFF, 0xFC, 0x03, 0x10, 0x00, 0xE0, 0x01, 0xE0, 0x19,
|
0xC0, 0xFC, 0xFF, 0xFF, 0xFC, 0x03, 0x10, 0x00, 0xE0, 0x01, 0xE0, 0x19,
|
||||||
0x41, 0x61, 0x66, 0x05, 0xE0, 0xB8, 0xFF, 0xFF, 0x7E, 0x0C, 0x44, 0x00,
|
0x41, 0x61, 0x66, 0x05, 0xE0, 0xB8, 0xFF, 0xFF, 0x7E, 0x0C, 0x44, 0x00,
|
||||||
0x40, 0xBF, 0xEF, 0x41, 0x5C, 0x04, 0x00, 0xA8, 0xF0, 0xC1, 0xFF, 0xFF,
|
0x40, 0xBF, 0xEF, 0x41, 0x5C, 0x04, 0x00, 0xA8, 0xF0, 0xC1, 0xFF, 0xFF,
|
||||||
0xFE, 0x21, 0x9E, 0x00, 0xE0, 0xFF, 0xED, 0xA5, 0x12, 0x92, 0xDB, 0xA2,
|
0xFE, 0x21, 0x9E, 0x00, 0xE0, 0xFF, 0xED, 0xA5, 0x12, 0x92, 0xDB, 0xA2,
|
||||||
0xE0, 0xC0, 0xFF, 0xFF, 0x7D, 0xFA, 0xFF, 0x00, 0x70, 0x00, 0xFF, 0x42,
|
0xE0, 0xC0, 0xFF, 0xFF, 0x7D, 0xFA, 0xFF, 0x00, 0x70, 0x00, 0xFF, 0x42,
|
||||||
0x84, 0x0C, 0x00, 0x08, 0xC0, 0xC0, 0xFF, 0xFC, 0x7D, 0xFF, 0x90, 0x07,
|
0x84, 0x0C, 0x00, 0x08, 0xC0, 0xC0, 0xFF, 0xFC, 0x7D, 0xFF, 0x90, 0x07,
|
||||||
0xC0, 0x1F, 0xDB, 0x0A, 0x24, 0xC8, 0x68, 0x09, 0xCC, 0xC0, 0x7F, 0xFE,
|
0xC0, 0x1F, 0xDB, 0x0A, 0x24, 0xC8, 0x68, 0x09, 0xCC, 0xC0, 0x7F, 0xFE,
|
||||||
0x1E, 0x7F, 0x3E, 0x00, 0xD4, 0xFF, 0x3E, 0x60, 0x81, 0x21, 0x02, 0xA0,
|
0x1E, 0x7F, 0x3E, 0x00, 0xD4, 0xFF, 0x3E, 0x60, 0x81, 0x21, 0x02, 0xA0,
|
||||||
0xFC, 0xE0, 0x7F, 0xFF, 0xCE, 0x9F, 0xFF, 0x05, 0xFA, 0xFF, 0xBF, 0x04,
|
0xFC, 0xE0, 0x7F, 0xFF, 0xCE, 0x9F, 0xFF, 0x05, 0xFA, 0xFF, 0xBF, 0x04,
|
||||||
0x24, 0x0A, 0x61, 0x1B, 0xFC, 0xC0, 0xBF, 0xFF, 0xAC, 0x7D, 0xFF, 0x03,
|
0x24, 0x0A, 0x61, 0x1B, 0xFC, 0xC0, 0xBF, 0xFF, 0xAC, 0x7D, 0xFF, 0x03,
|
||||||
0x40, 0x1F, 0x80, 0x91, 0xC2, 0xA0, 0x05, 0x80, 0xFF, 0x8D, 0x7F, 0xFF,
|
0x40, 0x1F, 0x80, 0x91, 0xC2, 0xA0, 0x05, 0x80, 0xFF, 0x8D, 0x7F, 0xFF,
|
||||||
0xEF, 0xF5, 0xDF, 0x00, 0x00, 0x94, 0x42, 0x81, 0x01, 0x10, 0x92, 0x85,
|
0xEF, 0xF5, 0xDF, 0x00, 0x00, 0x94, 0x42, 0x81, 0x01, 0x10, 0x92, 0x85,
|
||||||
0xFF, 0xFD, 0xFF, 0xFE, 0x2C, 0x62, 0x03, 0x00, 0x20, 0x00, 0x10, 0x2B,
|
0xFF, 0xFD, 0xFF, 0xFE, 0x2C, 0x62, 0x03, 0x00, 0x20, 0x00, 0x10, 0x2B,
|
||||||
0x24, 0x82, 0x00, 0x20, 0xFF, 0xFD, 0xFF, 0xFF, 0xBD, 0x55, 0x01, 0x00,
|
0x24, 0x82, 0x00, 0x20, 0xFF, 0xFD, 0xFF, 0xFF, 0xBD, 0x55, 0x01, 0x00,
|
||||||
0x40, 0x00, 0x08, 0x19, 0x81, 0x58, 0x54, 0x14, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x40, 0x00, 0x08, 0x19, 0x81, 0x58, 0x54, 0x14, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0x3C, 0x82, 0x05, 0x08, 0x00, 0x24, 0x20, 0x81, 0x24, 0x02, 0x02, 0x82,
|
0x3C, 0x82, 0x05, 0x08, 0x00, 0x24, 0x20, 0x81, 0x24, 0x02, 0x02, 0x82,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x82, 0x01, 0x00, 0x00, 0x00, 0x69, 0x22,
|
0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x82, 0x01, 0x00, 0x00, 0x00, 0x69, 0x22,
|
||||||
0x90, 0xA0, 0x49, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x2D, 0x26, 0x00, 0x00,
|
0x90, 0xA0, 0x49, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x2D, 0x26, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x20, 0x20, 0x0A, 0x02, 0x20, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x00, 0x00, 0x20, 0x20, 0x0A, 0x02, 0x20, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0x04, 0x81, 0x01, 0x00, 0x10, 0x00, 0xA0, 0x04, 0x02, 0x0A, 0x09, 0x00,
|
0x04, 0x81, 0x01, 0x00, 0x10, 0x00, 0xA0, 0x04, 0x02, 0x0A, 0x09, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0x19, 0x02, 0x02, 0x00, 0x00, 0x02, 0x42,
|
0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0x19, 0x02, 0x02, 0x00, 0x00, 0x02, 0x42,
|
||||||
0x50, 0xA0, 0x20, 0x95, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x00, 0x01,
|
0x50, 0xA0, 0x20, 0x95, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x00, 0x01,
|
||||||
0x80, 0x02, 0x42, 0x52, 0x40, 0x20, 0xA0, 0x20, 0xFF, 0xFF, 0xFF, 0x7F,
|
0x80, 0x02, 0x42, 0x52, 0x40, 0x20, 0xA0, 0x20, 0xFF, 0xFF, 0xFF, 0x7F,
|
||||||
0x00, 0x00, 0x8C, 0x01, 0x40, 0x00, 0x00, 0x00, 0x06, 0x06, 0x09, 0x05,
|
0x00, 0x00, 0x8C, 0x01, 0x40, 0x00, 0x00, 0x00, 0x06, 0x06, 0x09, 0x05,
|
||||||
0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x50, 0x00, 0x00, 0x40, 0x00, 0x02, 0x18,
|
0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x50, 0x00, 0x00, 0x40, 0x00, 0x02, 0x18,
|
||||||
0xA0, 0x90, 0x84, 0x64, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x10, 0x81, 0x07,
|
0xA0, 0x90, 0x84, 0x64, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x10, 0x81, 0x07,
|
||||||
0xD0, 0x00, 0x48, 0x82, 0x02, 0x02, 0x20, 0x00, 0xFF, 0xFF, 0xFF, 0x0F,
|
0xD0, 0x00, 0x48, 0x82, 0x02, 0x02, 0x20, 0x00, 0xFF, 0xFF, 0xFF, 0x0F,
|
||||||
0x00, 0x04, 0xC0, 0x7E, 0x9F, 0x01, 0x10, 0x04, 0x00, 0x00, 0x24, 0x25,
|
0x00, 0x04, 0xC0, 0x7E, 0x9F, 0x01, 0x10, 0x04, 0x00, 0x00, 0x24, 0x25,
|
||||||
0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x60, 0x48, 0xC0, 0xC1, 0x13, 0x00, 0x41,
|
0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x60, 0x48, 0xC0, 0xC1, 0x13, 0x00, 0x41,
|
||||||
0x9A, 0x99, 0x81, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x40, 0x40, 0x60, 0x00,
|
0x9A, 0x99, 0x81, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x40, 0x40, 0x60, 0x00,
|
||||||
0x84, 0x0B, 0x00, 0x50, 0x02, 0x40, 0x24, 0x90, 0xFF, 0xFF, 0xFF, 0x01,
|
0x84, 0x0B, 0x00, 0x50, 0x02, 0x40, 0x24, 0x90, 0xFF, 0xFF, 0xFF, 0x01,
|
||||||
0x00, 0x00, 0x32, 0x00, 0x00, 0x57, 0x00, 0x04, 0x40, 0x02, 0x01, 0x05,
|
0x00, 0x00, 0x32, 0x00, 0x00, 0x57, 0x00, 0x04, 0x40, 0x02, 0x01, 0x05,
|
||||||
0xF8, 0xFF, 0xFF, 0x01, 0x40, 0x00, 0x38, 0x00, 0x00, 0x0E, 0x10, 0x05,
|
0xF8, 0xFF, 0xFF, 0x01, 0x40, 0x00, 0x38, 0x00, 0x00, 0x0E, 0x10, 0x05,
|
||||||
0x99, 0x0A, 0xA4, 0x0A, 0xFC, 0xFF, 0x7F, 0x00, 0x80, 0x30, 0x10, 0x00,
|
0x99, 0x0A, 0xA4, 0x0A, 0xFC, 0xFF, 0x7F, 0x00, 0x80, 0x30, 0x10, 0x00,
|
||||||
0x00, 0x84, 0x04, 0x60, 0x00, 0x50, 0x00, 0x60, 0xFC, 0xFF, 0xFF, 0x00,
|
0x00, 0x84, 0x04, 0x60, 0x00, 0x50, 0x00, 0x60, 0xFC, 0xFF, 0xFF, 0x00,
|
||||||
0x00, 0x3A, 0x08, 0x00, 0x00, 0x04, 0x8E, 0x06, 0x00, 0x41, 0x56, 0x00,
|
0x00, 0x3A, 0x08, 0x00, 0x00, 0x04, 0x8E, 0x06, 0x00, 0x41, 0x56, 0x00,
|
||||||
0xF8, 0xFE, 0xFF, 0x01, 0x80, 0x79, 0xA0, 0x7F, 0xFF, 0x01, 0x06, 0x20,
|
0xF8, 0xFE, 0xFF, 0x01, 0x80, 0x79, 0xA0, 0x7F, 0xFF, 0x01, 0x06, 0x20,
|
||||||
0x51, 0x08, 0x00, 0x2A, 0xF8, 0xFF, 0xFF, 0x00, 0xE0, 0x3F, 0xE0, 0xAF,
|
0x51, 0x08, 0x00, 0x2A, 0xF8, 0xFF, 0xFF, 0x00, 0xE0, 0x3F, 0xE0, 0xAF,
|
||||||
0x00, 0x00, 0x06, 0x11, 0x91, 0x52, 0x02, 0x92, 0xF8, 0xFF, 0xFF, 0x00,
|
0x00, 0x00, 0x06, 0x11, 0x91, 0x52, 0x02, 0x92, 0xF8, 0xFF, 0xFF, 0x00,
|
||||||
0x00, 0x7F, 0x00, 0x00, 0x80, 0x02, 0x02, 0x08, 0x00, 0x00, 0x50, 0x00,
|
0x00, 0x7F, 0x00, 0x00, 0x80, 0x02, 0x02, 0x08, 0x00, 0x00, 0x50, 0x00,
|
||||||
0x7E, 0xFF, 0xFF, 0x01, 0x40, 0x7F, 0x00, 0x00, 0x10, 0x80, 0x86, 0x00,
|
0x7E, 0xFF, 0xFF, 0x01, 0x40, 0x7F, 0x00, 0x00, 0x10, 0x80, 0x86, 0x00,
|
||||||
0x08, 0x09, 0x06, 0x08, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0xFC, 0x20, 0x51,
|
0x08, 0x09, 0x06, 0x08, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0xFC, 0x20, 0x51,
|
||||||
0x0D, 0x20, 0x23, 0x94, 0x91, 0x50, 0x20, 0x92, 0xFF, 0xFE, 0xFF, 0x03,
|
0x0D, 0x20, 0x23, 0x94, 0x91, 0x50, 0x20, 0x92, 0xFF, 0xFE, 0xFF, 0x03,
|
||||||
0x20, 0x70, 0x05, 0x88, 0x01, 0x80, 0x21, 0x06, 0x84, 0x44, 0x80, 0x25,
|
0x20, 0x70, 0x05, 0x88, 0x01, 0x80, 0x21, 0x06, 0x84, 0x44, 0x80, 0x25,
|
||||||
0xFF, 0xFF, 0xFF, 0x03, 0x40, 0xEA, 0x90, 0x00, 0x20, 0xA4, 0x05, 0x00,
|
0xFF, 0xFF, 0xFF, 0x03, 0x40, 0xEA, 0x90, 0x00, 0x20, 0xA4, 0x05, 0x00,
|
||||||
0x00, 0x10, 0x26, 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0x40, 0xD8, 0x08, 0x00,
|
0x00, 0x10, 0x26, 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0x40, 0xD8, 0x08, 0x00,
|
||||||
0x00, 0xA0, 0x81, 0x92, 0x01, 0x01, 0x84, 0x40, 0xFF, 0xFF, 0xFF, 0x0F,
|
0x00, 0xA0, 0x81, 0x92, 0x01, 0x01, 0x84, 0x40, 0xFF, 0xFF, 0xFF, 0x0F,
|
||||||
0x20, 0xC3, 0x42, 0x00, 0x00, 0x0A, 0x24, 0x00, 0x44, 0x48, 0x20, 0x25,
|
0x20, 0xC3, 0x42, 0x00, 0x00, 0x0A, 0x24, 0x00, 0x44, 0x48, 0x20, 0x25,
|
||||||
0xFF, 0xFF, 0xFF, 0x0F, 0x20, 0xD5, 0x05, 0x02, 0x00, 0x46, 0x12, 0x40,
|
0xFF, 0xFF, 0xFF, 0x0F, 0x20, 0xD5, 0x05, 0x02, 0x00, 0x46, 0x12, 0x40,
|
||||||
0x02, 0x22, 0x44, 0x00, 0xFF, 0xFF, 0xFF, 0x1F, 0x90, 0x50, 0x90, 0x00,
|
0x02, 0x22, 0x44, 0x00, 0xFF, 0xFF, 0xFF, 0x1F, 0x90, 0x50, 0x90, 0x00,
|
||||||
0x00, 0x9A, 0x40, 0x02, 0x40, 0x00, 0x10, 0x64, 0xFF, 0xFF, 0xFF, 0x1F,
|
0x00, 0x9A, 0x40, 0x02, 0x40, 0x00, 0x10, 0x64, 0xFF, 0xFF, 0xFF, 0x1F,
|
||||||
0x98, 0x62, 0x7C, 0x10, 0x11, 0xDF, 0x07, 0x14, 0x28, 0x08, 0x01, 0x05,
|
0x98, 0x62, 0x7C, 0x10, 0x11, 0xDF, 0x07, 0x14, 0x28, 0x08, 0x01, 0x05,
|
||||||
0xFF, 0xFF, 0xFF, 0x1F, 0x20, 0x74, 0xF8, 0xE5, 0xEA, 0x87, 0x23, 0x01,
|
0xFF, 0xFF, 0xFF, 0x1F, 0x20, 0x74, 0xF8, 0xE5, 0xEA, 0x87, 0x23, 0x01,
|
||||||
0x81, 0x11, 0x48, 0x20, 0xFF, 0xFF, 0xFF, 0x1F, 0x50, 0x38, 0xF2, 0xFF,
|
0x81, 0x11, 0x48, 0x20, 0xFF, 0xFF, 0xFF, 0x1F, 0x50, 0x38, 0xF2, 0xFF,
|
||||||
0xFF, 0xC7, 0x8F, 0x80, 0x00, 0x84, 0x40, 0x04, 0xFF, 0xFF, 0xFF, 0xBF,
|
0xFF, 0xC7, 0x8F, 0x80, 0x00, 0x84, 0x40, 0x04, 0xFF, 0xFF, 0xFF, 0xBF,
|
||||||
0x68, 0x3D, 0xE9, 0xFF, 0x7F, 0xC1, 0x1F, 0x28, 0x14, 0x10, 0x06, 0x50,
|
0x68, 0x3D, 0xE9, 0xFF, 0x7F, 0xC1, 0x1F, 0x28, 0x14, 0x10, 0x06, 0x50,
|
||||||
0xFF, 0xFF, 0xFF, 0x3F, 0x90, 0x3F, 0x81, 0xFE, 0x5F, 0x89, 0x3F, 0x82,
|
0xFF, 0xFF, 0xFF, 0x3F, 0x90, 0x3F, 0x81, 0xFE, 0x5F, 0x89, 0x3F, 0x82,
|
||||||
0x00, 0x02, 0xA2, 0x01, 0xFF, 0xFF, 0xFF, 0xBF, 0xB0, 0x3F, 0xB1, 0xFF,
|
0x00, 0x02, 0xA2, 0x01, 0xFF, 0xFF, 0xFF, 0xBF, 0xB0, 0x3F, 0xB1, 0xFF,
|
||||||
0xBF, 0xC1, 0xFF, 0x00, 0x82, 0x80, 0x00, 0x24, 0xFF, 0xFB, 0xFF, 0x7F,
|
0xBF, 0xC1, 0xFF, 0x00, 0x82, 0x80, 0x00, 0x24, 0xFF, 0xFB, 0xFF, 0x7F,
|
||||||
0xF8, 0x3F, 0xA9, 0xFC, 0x5F, 0x81, 0xFF, 0x0F, 0x08, 0x00, 0x04, 0x48,
|
0xF8, 0x3F, 0xA9, 0xFC, 0x5F, 0x81, 0xFF, 0x0F, 0x08, 0x00, 0x04, 0x48,
|
||||||
0xFF, 0xF0, 0xFF, 0xBF, 0xFC, 0x3F, 0x41, 0xEB, 0xE7, 0xC0, 0xFF, 0x1F,
|
0xFF, 0xF0, 0xFF, 0xBF, 0xFC, 0x3F, 0x41, 0xEB, 0xE7, 0xC0, 0xFF, 0x1F,
|
||||||
0x40, 0x24, 0x40, 0x01, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0x3F, 0xB3, 0x7D,
|
0x40, 0x24, 0x40, 0x01, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0x3F, 0xB3, 0x7D,
|
||||||
0xAD, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0xA0, 0x90, 0x7F, 0xC0, 0xFF, 0xFF,
|
0xAD, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0xA0, 0x90, 0x7F, 0xC0, 0xFF, 0xFF,
|
||||||
0xFF, 0x3F, 0x43, 0xFA, 0x27, 0xC0, 0xFF, 0xFF, 0x93, 0x51, 0x04, 0x04,
|
0xFF, 0x3F, 0x43, 0xFA, 0x27, 0xC0, 0xFF, 0xFF, 0x93, 0x51, 0x04, 0x04,
|
||||||
0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x60, 0x6D, 0x56, 0xC0, 0xFF, 0xFF,
|
0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x60, 0x6D, 0x56, 0xC0, 0xFF, 0xFF,
|
||||||
0x1F, 0x20, 0x0A, 0x40, 0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x84, 0x6A,
|
0x1F, 0x20, 0x0A, 0x40, 0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x84, 0x6A,
|
||||||
0x6D, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x02, 0x7F, 0x00, 0xFF, 0xFF,
|
0x6D, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x02, 0x7F, 0x00, 0xFF, 0xFF,
|
||||||
0xFF, 0x3F, 0x2C, 0xBA, 0x22, 0xC0, 0xFF, 0xFF, 0xFF, 0x87, 0x04, 0x98,
|
0xFF, 0x3F, 0x2C, 0xBA, 0x22, 0xC0, 0xFF, 0xFF, 0xFF, 0x87, 0x04, 0x98,
|
||||||
0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x48, 0x66, 0xD5, 0xC0, 0xFF, 0xFF,
|
0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x48, 0x66, 0xD5, 0xC0, 0xFF, 0xFF,
|
||||||
0xFF, 0x3F, 0x90, 0x02, 0x7F, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F, 0x80, 0xA6,
|
0xFF, 0x3F, 0x90, 0x02, 0x7F, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F, 0x80, 0xA6,
|
||||||
0x63, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x24, 0x7F, 0xF8, 0xFF, 0xFF,
|
0x63, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x24, 0x7F, 0xF8, 0xFF, 0xFF,
|
||||||
0xFF, 0x7F, 0x90, 0x78, 0x3A, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x27, 0x00,
|
0xFF, 0x7F, 0x90, 0x78, 0x3A, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x27, 0x00,
|
||||||
0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xF9, 0x06, 0xF0, 0xFF, 0xFF,
|
0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xF9, 0x06, 0xF0, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x8F, 0x61, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xA4,
|
0xFF, 0xFF, 0x8F, 0x61, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xA4,
|
||||||
0x0B, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x04, 0x7F, 0xFE, 0xFF, 0xFF,
|
0x0B, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x04, 0x7F, 0xFE, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x00, 0xD0, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x08,
|
0xFF, 0xFF, 0x00, 0xD0, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x08,
|
||||||
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0xF8, 0xFF, 0xFF,
|
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0xF8, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x61, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x88,
|
0xFF, 0xFF, 0xFF, 0x61, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x88,
|
||||||
0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFE, 0xFF, 0xFF, 0xFF,
|
0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x48,
|
0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x48,
|
||||||
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x07, 0xFC, 0xFF, 0xFF,
|
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x07, 0xFC, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x01, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xD0,
|
0xFF, 0xFF, 0xFF, 0x01, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xD0,
|
||||||
0x0F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x69, 0xF8, 0xFF, 0xFF, 0xFF,
|
0x0F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x69, 0xF8, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x03, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05,
|
0xFF, 0xFF, 0x03, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0x3F, 0xFE, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0x3F, 0xFE, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x21, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF,
|
0xFF, 0xFF, 0xFF, 0x21, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF,
|
||||||
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF,
|
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6B,
|
0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6B,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x23, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0x23, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xEF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x27,
|
0xFF, 0xFF, 0xFF, 0xEF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x27,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
|
0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F,
|
0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F,
|
||||||
0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF,
|
0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
|
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xF0, 0xFF, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F,
|
0xFF, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
|
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
|
||||||
0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF,
|
0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F,
|
0xFF, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F,
|
||||||
0xF8, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xF8, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0x03, 0x00, 0xF1, 0xFF, 0x7F, 0x80,
|
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0x03, 0x00, 0xF1, 0xFF, 0x7F, 0x80,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0x03, 0x00,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0x03, 0x00,
|
||||||
0xF0, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x7F, 0x6F, 0xFD, 0xFF, 0xFF, 0x1F,
|
0xF0, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x7F, 0x6F, 0xFD, 0xFF, 0xFF, 0x1F,
|
||||||
0xF8, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x7F, 0x7F,
|
0xF8, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x7F, 0x7F,
|
||||||
0xFD, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0x03, 0x00, 0xC0, 0xFF, 0xFF, 0x90,
|
0xFD, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0x03, 0x00, 0xC0, 0xFF, 0xFF, 0x90,
|
||||||
0xFF, 0xFF, 0x5F, 0xA2, 0xF4, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0x03, 0x00,
|
0xFF, 0xFF, 0x5F, 0xA2, 0xF4, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0x03, 0x00,
|
||||||
0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x0F, 0xAA, 0x42, 0xF1, 0xFF, 0x3F,
|
0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x0F, 0xAA, 0x42, 0xF1, 0xFF, 0x3F,
|
||||||
0xF8, 0xFF, 0xAF, 0x00, 0x80, 0xFF, 0xFF, 0xD9, 0xFF, 0xFF, 0x0F, 0x02,
|
0xF8, 0xFF, 0xAF, 0x00, 0x80, 0xFF, 0xFF, 0xD9, 0xFF, 0xFF, 0x0F, 0x02,
|
||||||
0x64, 0xF1, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x3F, 0xC2, 0xFF, 0xFF, 0xDB,
|
0x64, 0xF1, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x3F, 0xC2, 0xFF, 0xFF, 0xDB,
|
||||||
0xFF, 0xFF, 0xCB, 0xD1, 0xDA, 0xF7, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xCB, 0xD1, 0xDA, 0xF7, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x71, 0x44, 0xFC, 0xF6, 0xFF, 0x3F,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x71, 0x44, 0xFC, 0xF6, 0xFF, 0x3F,
|
||||||
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0xC0,
|
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0xC0,
|
||||||
0xA8, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xA8, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFC, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
|
||||||
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, };
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, };
|
||||||
|
|
|
@ -1,178 +1,178 @@
|
||||||
/* XPM */
|
/* XPM */
|
||||||
static char *hopper[] = {
|
static char *hopper[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"128 128 44 1 ",
|
"128 128 44 1 ",
|
||||||
" c #110E13",
|
" c #110E13",
|
||||||
". c #2A1110",
|
". c #2A1110",
|
||||||
"X c #13122C",
|
"X c #13122C",
|
||||||
"o c #25192A",
|
"o c #25192A",
|
||||||
"O c #312831",
|
"O c #312831",
|
||||||
"+ c #302219",
|
"+ c #302219",
|
||||||
"@ c #5F241A",
|
"@ c #5F241A",
|
||||||
"# c #6F4832",
|
"# c #6F4832",
|
||||||
"$ c #17174A",
|
"$ c #17174A",
|
||||||
"% c #26264F",
|
"% c #26264F",
|
||||||
"& c #65595D",
|
"& c #65595D",
|
||||||
"* c #4B3C54",
|
"* c #4B3C54",
|
||||||
"= c #8E1F1A",
|
"= c #8E1F1A",
|
||||||
"- c #914E33",
|
"- c #914E33",
|
||||||
"; c #A75335",
|
"; c #A75335",
|
||||||
": c #AC6736",
|
": c #AC6736",
|
||||||
"> c #B26F4E",
|
"> c #B26F4E",
|
||||||
", c #9B6657",
|
", c #9B6657",
|
||||||
"< c #CA7652",
|
"< c #CA7652",
|
||||||
"1 c #CC7866",
|
"1 c #CC7866",
|
||||||
"2 c #C25135",
|
"2 c #C25135",
|
||||||
"3 c #B0896D",
|
"3 c #B0896D",
|
||||||
"4 c #D28859",
|
"4 c #D28859",
|
||||||
"5 c #D28E6D",
|
"5 c #D28E6D",
|
||||||
"6 c #E79371",
|
"6 c #E79371",
|
||||||
"7 c #E5A36E",
|
"7 c #E5A36E",
|
||||||
"8 c #D58932",
|
"8 c #D58932",
|
||||||
"9 c #3E65AE",
|
"9 c #3E65AE",
|
||||||
"0 c #4970B5",
|
"0 c #4970B5",
|
||||||
"q c #606D95",
|
"q c #606D95",
|
||||||
"w c #557CC1",
|
"w c #557CC1",
|
||||||
"e c #91778A",
|
"e c #91778A",
|
||||||
"r c #6A86B9",
|
"r c #6A86B9",
|
||||||
"t c #5C83C3",
|
"t c #5C83C3",
|
||||||
"y c #6D8FCA",
|
"y c #6D8FCA",
|
||||||
"u c #7799E3",
|
"u c #7799E3",
|
||||||
"i c #A89A9D",
|
"i c #A89A9D",
|
||||||
"p c #CFAA90",
|
"p c #CFAA90",
|
||||||
"a c #F4B08F",
|
"a c #F4B08F",
|
||||||
"s c #D6A799",
|
"s c #D6A799",
|
||||||
"d c #ECCCAB",
|
"d c #ECCCAB",
|
||||||
"f c #F9F4F4",
|
"f c #F9F4F4",
|
||||||
"g c #E3D8D5",
|
"g c #E3D8D5",
|
||||||
"h c #AAAECA",
|
"h c #AAAECA",
|
||||||
/* pixels */
|
/* pixels */
|
||||||
"$XX$$XXX$%$$$$$$$$$$$$$$$$$$$egip3dr %% @p# Oqgffgfgfgo%q999q9999999999999999999099999099099990999999909909990w999000wwww00w00w0",
|
"$XX$$XXX$%$$$$$$$$$$$$$$$$$$$egip3dr %% @p# Oqgffgfgfgo%q999q9999999999999999999099999099099990999999909909990w999000wwww00w00w0",
|
||||||
"$$X$X$XX$$$$$$$$9$$$$XX$$$$$$ws&7+O&%$Xo@3#XXX&ihffggg%%9q*9*%q99qq9q99999999999999090900909909909099999999999999999000wwwwww0ww",
|
"$$X$X$XX$$$$$$$$9$$$$XX$$$$$$ws&7+O&%$Xo@3#XXX&ihffggg%%9q*9*%q99qq9q99999999999999090900909909909099999999999999999000wwwwww0ww",
|
||||||
"X$X$$XXX$$$$$$$$$$$$$$$$$$$$$eq@i#+$$$%X#pOX$%$%*dfffgiX%%OX%XO*%**990909999999009090990900999999099990999w999990990000wwwwwwwww",
|
"X$X$$XXX$$$$$$$$$$$$$$$$$$$$$eq@i#+$$$%X#pOX$%$%*dfffgiX%%OX%XO*%**990909999999009090990900999999099990999w999990990000wwwwwwwww",
|
||||||
"$XX$$$XX$$$$$$$$$$$$XX$$$$$$$*O*7#XX%$%X@p*XX$%Xohfi3hOXOoX*r3*OOO%O99099999q0q990990009090909000999090999999099909999ww0w0000w0",
|
"$XX$$$XX$$$$$$$$$$$$XX$$$$$$$*O*7#XX%$%X@p*XX$%Xohfi3hOXOoX*r3*OOO%O99099999q0q990990009090909000999090999999099909999ww0w0000w0",
|
||||||
"$XX$$XXX$$$$$$$$$9$$$$$$$$$$o$.&3++X$$$o#p+X$$%$OhgOX oo+ii*if&+ri&OO%q0990099009090090990909009990999099w999990999090w0000w0ww0",
|
"$XX$$XXX$$$$$$$$$9$$$$$$$$$$o$.&3++X$$$o#p+X$$%$OhgOX oo+ii*if&+ri&OO%q0990099009090090990909009990999099w999990999090w0000w0ww0",
|
||||||
"X$X$$XXX$$$$$$$$$$$$$$$$$$$$$oX#p#OO%$$o#7O%X$$XOg&O o.&fffgifirfffiOO*&qq990990000000009909099000990990999990999w90099000000000",
|
"X$X$$XXX$$$$$$$$$$$$$$$$$$$$$oX#p#OO%$$o#7O%X$$XOg&O o.&fffgifirfffiOO*&qq990990000000009909099000990990999990999w90099000000000",
|
||||||
"XX$$$XXX$$$$$$$$$$$$$$$$$$$$$oo*3+o$$%$.#7+X$%XOOhii+X,fgifffffffddfgOOrhi0qq000090000090099990909909009w9w9909990999099900000w0",
|
"XX$$$XXX$$$$$$$$$$$$$$$$$$$$$oo*3+o$$%$.#7+X$%XOOhii+X,fgifffffffddfgOOrhi0qq000090000090099990909909009w9w9909990999099900000w0",
|
||||||
"X$X$$$XX$$$$$%$$$$$$X$X$$$$$X$X#7@X$$$$o:3+XX$OqgffrXOe&&#*&iggi&&3&*&OOfffgrq900009000099099090000909009999990999900900000000w0",
|
"X$X$$$XX$$$$$%$$$$$$X$X$$$$$X$X#7@X$$$$o:3+XX$OqgffrXOe&&#*&iggi&&3&*&OOfffgrq900009000099099090000909009999990999900900000000w0",
|
||||||
"X$q$XXXX$$$X%$$$$$$$X$$$$$$$$$X*p+O$%$$o-3oOX%gffff&o++3pgg3fddd3fdg&+OOhffffgt0099090090009090990909990999990999000099090090000",
|
"X$q$XXXX$$$X%$$$$$$$X$$$$$$$$$X*p+O$%$$o-3oOX%gffff&o++3pgg3fddd3fdg&+OOhffffgt0099090090009090990909990999990999000099090090000",
|
||||||
"X$g&$XXX%$X$%$$$$$$$$$X$$$$$$$o*p+X%$%$X,5+ *gfffff& ++&pddffffffgdd#OOOiffffffhq9qt009w990090900999w9w9900999w90999909009900000",
|
"X$g&$XXX%$X$%$$$$$$$$$X$$$$$$$o*p+X%$%$X,5+ *gfffff& ++&pddffffffgdd#OOOiffffffhq9qt009w990090900999w9w9900999w90999909009900000",
|
||||||
"X$ggO %$$$X$%$$$$$$$$$$$$$$$Xo*3#$$%%$X,3+&ffffffg#+.+Odddgggggggpd*+OOifffffffgtqt09t909090990090909099990099w0990090909090000",
|
"X$ggO %$$$X$%$$$$$$$$$$$$$$$Xo*3#$$%%$X,3+&ffffffg#+.+Odddgggggggpd*+OOifffffffgtqt09t909090990090909099990099w0990090909090000",
|
||||||
"X%hfr&h&$$$$%q$X$$$$XXX$$$$$Xoo*p@o$$$$X:3OffffgppdO. ++,ddfffffffd3+ ++&ffffffffgq900909090900999099090w9w990990009009090009900",
|
"X%hfr&h&$$$$%q$X$$$$XXX$$$$$Xoo*p@o$$$$X:3OffffgppdO. ++,ddfffffffd3+ ++&ffffffffgq900909090900999099090w9w990990009009090009900",
|
||||||
"Xohfffh&X$o$$h&$$$$$$$X$$$$$Xo$*7# %%$$ 35dffg73&#++++ +pd3gfffffg3d,++++3ddffffffhq90009099990999909090990909w99990099900900000",
|
"Xohfffh&X$o$$h&$$$$$$$X$$$$$Xo$*7# %%$$ 35dffg73&#++++ +pd3gfffffg3d,++++3ddffffffhq90009099990999909090990909w99990099900900000",
|
||||||
"oegffgiO$$$$$gh$$%&qXXXX$%XX$X.*3# X%X$+#pgfd3&+. + ++3iddgfffddpd&+O++++#pgfffffrq9900900q99090909990099009990009990999090000",
|
"oegffgiO$$$$$gh$$%&qXXXX$%XX$X.*3# X%X$+#pgfd3&+. + ++3iddgfffddpd&+O++++#pgfffffrq9900900q99090909990099009990009990999090000",
|
||||||
"hffffg&X$%$X$gg*&hg*XXXX%i%$$Xo*5#XX$$$o,dfg&+.. .#&++ +&ddd3gfgdddd#++++&+++#3dfgghq009099090000909090990999090909000099000000w",
|
"hffffg&X$%$X$gg*&hg*XXXX%i%$$Xo*5#XX$$$o,dfg&+.. .#&++ +&ddd3gfgdddd#++++&+++#3dfgghq009099090000909090990999090909000099000000w",
|
||||||
"hgffffp*X$X%Ogggfgh$XXX$%g*XXooO5#o$%$$+&df3...&#++3 O#+#pd7di&,ppdd&+++#3+&&..#iffgqq009009009909900990090009990009999009990000",
|
"hgffffp*X$X%Ogggfgh$XXX$%g*XXooO5#o$%$$+&df3...&#++3 O#+#pd7di&,ppdd&+++#3+&&..#iffgqq009009009909900990090009990009999009990000",
|
||||||
"o%qffgh&o%o*iffgfg%%X$XX*gi OqO*p#+$%$XO&h3 . +pdpp3pdgdd3#+++++++#ppggpp3ddp+##+ifghqrq09090090090090900909999009009w900009w0w9",
|
"o%qffgh&o%o*iffgfg%%X$XX*gi OqO*p#+$%$XO&h3 . +pdpp3pdgdd3#+++++++#ppggpp3ddp+##+ifghqrq09090090090090900909999009009w900009w0w9",
|
||||||
"Xo*fh**%$%igfgfgg&%$$X$X&ggih3o+p# X%X$XX .+33+pdppdddfp,#+O&dfggdddd3pdddd+++dh&%%&q0090909009909090090000900w000w99w0900ww",
|
"Xo*fh**%$%igfgfgg&%$$X$X&ggih3o+p# X%X$XX .+33+pdppdddfp,#+O&dfggdddd3pdddd+++dh&%%&q0090909009909090090000900w000w99w0900ww",
|
||||||
"X%&fq%oX$%&hgfffgi%oXXX &fgshOoO3#+X%%XX+ . +#&++7dp3&#O&O&#&33dd3#3&.+#ppiiO#+ X%9909000909099090090900009w9w009ww9ww9w00",
|
"X%&fq%oX$%&hgfffgi%oXXX &fgshOoO3#+X%%XX+ . +#&++7dp3&#O&O&#&33dd3#3&.+#ppiiO#+ X%9909000909099090090900009w9w009ww9ww9w00",
|
||||||
"X$%g*o$XX%Xo*gffffq$X%&egfhp&oXO7# XXX + #++.+++ +..O+ ++O++#ppp+++&3++ o XXq9000900009000090009000009w909w09w00w00w",
|
"X$%g*o$XX%Xo*gffffq$X%&egfhp&oXO7# XXX + #++.+++ +..O+ ++O++#ppp+++&3++ o XXq9000900009000090009000009w909w09w00w00w",
|
||||||
"$$*i$$oX$XoX%hfeegg%$%&idggh+X$O4#+XOX + . + ..o + + ++ +&3gg#. X999909000000000000009000000000w09w0www0w",
|
"$$*i$$oX$XoX%hfeegg%$%&idggh+X$O4#+XOX + . + ..o + + ++ +&3gg#. X999909000000000000009000000000w09w0www0w",
|
||||||
"$$%%$$$X$$o$$hh*$$q&$o o3ggd,ooo3#+ ++ +++ ++*++ X%0q9q900000ww000000000000ww99w00w9w99ww0",
|
"$$%%$$$X$$o$$hh*$$q&$o o3ggd,ooo3#+ ++ +++ ++*++ X%0q9q900000ww000000000000ww99w00w9w99ww0",
|
||||||
"$$$$%%X$$$X$%g0$$%%%oX .&fshg*Xo3: X + + X*0000000000w000000000w00000ww0www90wwww0",
|
"$$$$%%X$$$X$%g0$$%%%oX .&fshg*Xo3: X + + X*0000000000w000000000w00000ww0www90wwww0",
|
||||||
"$%$$%$$XX$$X%h$%$%$$XXX qg*XiqXo3:+ %0q0000000w00000w0ww000w0ww990009w0w99ww",
|
"$%$$%$$XX$$X%h$%$%$$XXX qg*XiqXo3:+ %0q0000000w00000w0ww000w0ww990009w0w99ww",
|
||||||
"$$$%%%$$$XX$$%%$%$$$XXXXihXXX%X.,: %t000t90w0w0000090w00w00009w000wwww9www9",
|
"$$$%%%$$$XX$$%%$%$$$XXXXihXXX%X.,: %t000t90w0w0000090w00w00009w000wwww9www9",
|
||||||
"$$$$$%X$X$$$$%$$$$$$XXXXq*XXXXXo3: . %0q0000t0w0ww00ww00ww00ww0w9w0w0w99ww9ww",
|
"$$$$$%X$X$$$$%$$$$$$XXXXq*XXXXXo3: . %0q0000t0w0ww00ww00ww00ww0w9w0w0w99ww9ww",
|
||||||
"$$$$$$$XX$X$$$$$$$$$$XXX*$$XXXX :> %q0t0t00w0w0w0w00ww0w0w0w00w0w0www90w09w",
|
"$$$$$$$XX$X$$$$$$$$$$XXX*$$XXXX :> %q0t0t00w0w0w0w00ww0w0w0w00w0w0www90w09w",
|
||||||
"$$$$$$XX$$XX$$$$%$$$$XXX$$$$XXX.:3. . . .... .. . ....... X%qw000t00www0wwwwwww0ww0www0w00w00w09w9w",
|
"$$$$$$XX$$XX$$$$%$$$$XXX$$$$XXX.:3. . . .... .. . ....... X%qw000t00www0wwwwwww0ww0www0w00w00w09w9w",
|
||||||
"$$$$%%$$$XX$$$$$$$$$XXXX$$$$XXX -3 . ....+@@@@@@.@@....@@@@#####*@.. %ttt9ttt0t0tw0www0ww0ww00w9ww0w09w9www0w",
|
"$$$$%%$$$XX$$$$$$$$$XXXX$$$$XXX -3 . ....+@@@@@@.@@....@@@@#####*@.. %ttt9ttt0t0tw0www0ww0ww00w9ww0w09w9www0w",
|
||||||
"$$$%$%$$X$$$$$$$%%9$XXXX$$$$XXX :3 ...#->1>>1,>>,,--;,--,,,1531>13>#@. X09q9r00t0t0wwwww0w0wwwwwwww0wwwwww0w00w",
|
"$$$%$%$$X$$$$$$$%%9$XXXX$$$$XXX :3 ...#->1>>1,>>,,--;,--,,,1531>13>#@. X09q9r00t0t0wwwww0w0wwwwwwww0wwwwww0w00w",
|
||||||
"$$$$$$XXX$$$$$$$$$$$XX X$$$$$XX.:: .#11ss65assa56a511155557a775555p5,,. Xqttr0trt0wtwwwwww0ww0wwwwww0wwwww0ww0ww",
|
"$$$$$$XXX$$$$$$$$$$$XX X$$$$$XX.:: .#11ss65assa56a511155557a775555p5,,. Xqttr0trt0wtwwwwww0ww0wwwwww0wwwww0ww0ww",
|
||||||
"$$$$$$$X$$$$9$9$$$$$XXXXX$$$XX$ >;. ...#,pps55paaaaasadasaaaaaaaaa777a77p53,*... Xt0tq9t0ttwww0wwwwwwww0wwww0wwww0wwwwwww",
|
"$$$$$$$X$$$$9$9$$$$$XXXXX$$$XX$ >;. ...#,pps55paaaaasadasaaaaaaaaa777a77p53,*... Xt0tq9t0ttwww0wwwwwwww0wwww0wwww0wwwwwww",
|
||||||
"*o$%$%$XX$$$$$$$%$$$$XXXX$$$$XXX,> +#*-,5pp7apasaadddaaaaddadaaadddaaa6pp733,##. Xqrtttttt0t0rt0tt000t0t0t0t00t0t0ttt0ttt",
|
"*o$%$%$XX$$$$$$$%$$$$XXXX$$$$XXX,> +#*-,5pp7apasaadddaaaaddadaaadddaaa6pp733,##. Xqrtttttt0t0rt0tt000t0t0t0t00t0t0ttt0ttt",
|
||||||
"go%$$*%$XXX$$$$$$$$$$X XX$$$$XX :> .&,#,5p77p7aaaaadaaadaddaaadaaaasaapp7775534#@ Xr90tq0ttt0tt0ttt0ttttt00tttt0tt0t0tttt0",
|
"go%$$*%$XXX$$$$$$$$$$X XX$$$$XX :> .&,#,5p77p7aaaaadaaadaddaaadaaaasaapp7775534#@ Xr90tq0ttt0tt0ttt0ttttt00tttt0tt0t0tttt0",
|
||||||
"fio%whXXX%$$$$$$$$$$$XXX$$$$X$X.,8. o###-155pppadaasasaaadaaaaaaaaa51>3355455535>>#+ %t0r0r0rttt00tt0ttttttt0tttttt0ttttttttt",
|
"fio%whXXX%$$$$$$$$$$$XXX$$$$X$X.,8. o###-155pppadaasasaaadaaaaaaaaa51>3355455535>>#+ %t0r0r0rttt00tt0ttttttt0tttttt0ttttttttt",
|
||||||
"gg&gf&X *qo$$$$$$$$$$X X$$$$$XX 3: OO##,135565431>113sadaaaddsss611>1>>55s5355333,*+ %rr0r0ttt0tttttrtt0ttqttt0ttttttttt0tttt",
|
"gg&gf&X *qo$$$$$$$$$$X X$$$$$XX 3: OO##,135565431>113sadaaaddsss611>1>>55s5355333,*+ %rr0r0ttt0tttttrtt0ttqttt0ttttttttt0tttt",
|
||||||
"gffghOXX*g*$$$%$$$$$XXXX$$$$XXX -> +###,>3575p5<><355saaaaaaaap615>;;-;>5a7p335333#+ %rrtttt0t0trtttttttttttttttttttttttttttt",
|
"gffghOXX*g*$$$%$$$$$XXXX$$$$XXX -> +###,>3575p5<><355saaaaaaaap615>;;-;>5a7p335333#+ %rrtttt0t0trtttttttttttttttttttttttttttt",
|
||||||
"fgfg&oo &giO$qi%X$$$XX XX$$$XX .::+ +#,,,3355p55>>;;;,>16s777aaas61>;=--@#@@@@##&##&&+X*rrtttttttt0tttttttttttttttttttttttttttt",
|
"fgfg&oo &giO$qi%X$$$XX XX$$$XX .::+ +#,,,3355p55>>;;;,>16s777aaas61>;=--@#@@@@##&##&&+X*rrtttttttt0tttttttttttttttttttttttttttt",
|
||||||
"gggg&o &gg,sfe$X$$$$X XX$$$XXX :: +&#-,,35333>>,-,-,>>15apaadap1>>;@@@#;-##@+,&@##&O+&rttttt0ttttttt0tttttttttttttttttttttttt",
|
"gggg&o &gg,sfe$X$$$$X XX$$$XXX :: +&#-,,35333>>,-,-,>>15apaadap1>>;@@@#;-##@+,&@##&O+&rttttt0ttttttt0tttttttttttttttttttttttt",
|
||||||
"gffgg*oX&gfggh%X$X$$XX X%%XXX 3:+ ++3:-####@@.@..@++@@->6aaaaaa74>=@,3,11335d&+@+O*&##qrrttttytttttttrtttttttttttttttttttttttt",
|
"gffgg*oX&gfggh%X$X$$XX X%%XXX 3:+ ++3:-####@@.@..@++@@->6aaaaaa74>=@,3,11335d&+@+O*&##qrrttttytttttttrtttttttttttttttttttttttt",
|
||||||
"sggggho*dgggg&O$$$$$ *+Oii$X X .::+++&,-##+@+@@:ss1,1i1--=:4a77764::a1,@@@@=,,4d#+##*&,-eqyrwyrwttttttttttttttytytttytytttyttttt",
|
"sggggho*dgggg&O$$$$$ *+Oii$X X .::+++&,-##+@+@@:ss1,1i1--=:4a77764::a1,@@@@=,,4d#+##*&,-eqyrwyrwttttttttttttttytytttytytttyttttt",
|
||||||
"id**qi&Ogggdd+X$$$$$o*&eh*X XXX.::.O#,>-#@...+,,,-@@@@-5><<<76748:2<>-@#.@@@@=-@##@@+#,isiryywyyrttrttttyttytytttttytttttttttytu",
|
"id**qi&Ogggdd+X$$$$$o*&eh*X XXX.::.O#,>-#@...+,,,-@@@@-5><<<76748:2<>-@#.@@@@=-@##@@+#,isiryywyyrttrttttyttytytttttytttttttttytu",
|
||||||
",hO%X$Xo&gggg&O$$$$XoO,e&OXXXXX.3:.@33;#+@@@.-,>-@.@..@=::;<4<4<:28<2@#@.@@@@==-,-##-,1,eheywyywyttttyytytyttttttyttttttttytyttt",
|
",hO%X$Xo&gggg&O$$$$XoO,e&OXXXXX.3:.@33;#+@@@.-,>-@.@..@=::;<4<4<:28<2@#@.@@@@==-,-##-,1,eheywyywyttttyytytyttttttyttttttttytyttt",
|
||||||
"i&o$$X Ogggfg%X$$$$oO,&+ XX X :3+@3,,;##@#@##,@@@..@-;==;426a76<<<;>;--#==;;::4>4>:;:==1ryewywttyrtytttytyytyyttyttuytyttyttyt",
|
"i&o$$X Ogggfg%X$$$$oO,&+ XX X :3+@3,,;##@#@##,@@@..@-;==;426a76<<<;>;--#==;;::4>4>:;:==1ryewywttyrtytttytyytyyttyttuytyttyttyt",
|
||||||
"**%$$$XX+hiO&h&%$$$XX*,,& XXX X ::+#1-#-;,,>,#-==#=#;-;<4444;6ad7<661<<11>2;2<<<445<>:<<@,ryytytyytyyttyyttytyttytyttyttyttyuytt",
|
"**%$$$XX+hiO&h&%$$$XX*,,& XXX X ::+#1-#-;,,>,#-==#=#;-;<4444;6ad7<661<<11>2;2<<<445<>:<<@,ryytytyytyyttyyttytyttytyttyttyttyuytt",
|
||||||
"%X$$$$X Og*o%$*X$$$$X*&&i* XXXX :3.#,=;>,-35:-#===:4s51446a6;6aaa6661<66aaa6<664445>:15<-,ewyytyytytyyytyyytytytytyyytyyttuttttu",
|
"%X$$$$X Og*o%$*X$$$$X*&&i* XXXX :3.#,=;>,-35:-#===:4s51446a6;6aaa6661<66aaa6<664445>:15<-,ewyytyytytyyytyyytytytytyyytyyttuttttu",
|
||||||
"X$$$$XXXOi$$$$$X$$$XXX.o&qXo X .>>.#-@>;-:<6:<;==2<66a6<<6a<<aaaa7<a76167661<665655326a1-1ityytyyytytyyyyyyyyytyyttuyyyyytutyyyt",
|
"X$$$$XXXOi$$$$$X$$$XXX.o&qXo X .>>.#-@>;-:<6:<;==2<66a6<<6a<<aaaa7<a76167661<665655326a1-1ityytyyytytyyyyyyyyytyyttuyyyyytutyyyt",
|
||||||
"$XX$$XX %%$$$$$X$%$$X ooX$XXX -8.@,=11>-:44:<82<<11<<<aa621addad167aa4<8<2<<7545511:66;eqrryytytyyyytyyttyytytyytttyttyytyttyy",
|
"$XX$$XX %%$$$$$X$%$$X ooX$XXX -8.@,=11>-:44:<82<<11<<<aa621addad167aa4<8<2<<7545511:66;eqrryytytyyyytyyttyytytyytttyttyytyttyy",
|
||||||
"X$$$$XXXXX$$$$$$$$X$X XXXXXXXX :3.+>=54;;<<<<1<;2<<<1aada6:7adadd74aaadaa6446764444;=>s,eitryyyyyyyyyyyyttyyyyyyyytyyttyttutytu",
|
"X$$$$XXXXX$$$$$$$$X$X XXXXXXXX :3.+>=54;;<<<<1<;2<<<1aada6:7adadd74aaadaa6446764444;=>s,eitryyyyyyyyyyyyttyyyyyyyytyyttyttutytu",
|
||||||
"XX$$$XXXX$$$$XX$$$$$XXXXXX$X$X .::.@,;6<-;<<1<4::46aadddaa46aadddad66aaaaaa7a76564>4<-;51eryyttyyyttryytyyyyyryrtuyytyyyyyyttytt",
|
"XX$$$XXXX$$$$XX$$$$$XXXXXX$X$X .::.@,;6<-;<<1<4::46aadddaa46aadddad66aaaaaa7a76564>4<-;51eryyttyyyttryytyyyyyryrtuyytyyyyyyttytt",
|
||||||
"X$$$$XX XX$$$$X$$$XXXXX XXXXXXX :8+ia>44;;<<<44<;87dadddda<aaadddaaa1saadaa676444>>5a221eiiwtyyyyyyyyyyyyyyyyyyytyytytyytttytuyy",
|
"X$$$$XX XX$$$$X$$$XXXXX XXXXXXX :8+ia>44;;<<<44<;87dadddda<aaadddaaa1saadaa676444>>5a221eiiwtyyyyyyyyyyyyyyyyyyytyytytyytttytuyy",
|
||||||
"$X$X$X XX$X$$X$$$$$XX XX$XX$XX #73pda6<>56>2<44<26addaa6>:6adaaadda2;16666a7a6<4>47a1<1ieyyyyytyyytyyyyyyryyyyyyyyytutyyuyyytyy",
|
"$X$X$X XX$X$$X$$$$$XX XX$XX$XX #73pda6<>56>2<44<26addaa6>:6adaaadda2;16666a7a6<4>47a1<1ieyyyyytyyytyyyyyyryyyyyyyyytutyyuyyytyy",
|
||||||
"X$$$XX XX$$$XX$$$$XXXX XXXXXX :75ps565577>:<:46<<1aa11;;6aaadddaada<2>2;<6676<<435a1>5eiyytyyyyyyyyyyyyytyyyyyyyyyyyyyyytyyuty",
|
"X$$$XX XX$$$XX$$$$XXXX XXXXXX :75ps565577>:<:46<<1aa11;;6aaadddaada<2>2;<6676<<435a1>5eiyytyyyyyyyyyyyyytyyyyyyyyyyyyyyytyyuty",
|
||||||
"XX$$$XX XX$$$$$$$$X$XXXXXXXXX X3773sdp565p742<:<61<2;2;2=<66aaaaadaaa1>6a66a665<5>456>15ewyyyyyyyytyyyyyyyyyyyyytyytyyyyytuyyttu",
|
"XX$$$XX XX$$$$$$$$X$XXXXXXXXX X3773sdp565p742<:<61<2;2;2=<66aaaaadaaa1>6a66a665<5>456>15ewyyyyyyyytyyyyyyyyyyyyytyytyyyyytuyyttu",
|
||||||
"$$$XXX X$$$$$X$$$XXXXXXXXXX &pp73dd357577<<:>481611612;661a1saas6111;21aa664444>56<163iyyytyyyyyyyyyyyyyyyyryyutyyyyyyyyyyyyyy",
|
"$$$XXX X$$$$$X$$$XXXXXXXXXX &pp73dd357577<<:>481611612;661a1saas6111;21aa664444>56<163iyyytyyyyyyyyyyyyyyyyryyutyyyyyyyyyyyyyy",
|
||||||
"$X$$XX XX$$X$$$$XXXXXXXXXX *ip773ss345775<<<848111aa1;=;-=><1511;;====116166165>4>6615rtyyyyyyyyyyyyyyyyyyyyyyyyyyyyytyyyyytuy",
|
"$X$$XX XX$$X$$$$XXXXXXXXXX *ip773ss345775<<<848111aa1;=;-=><1511;;====116166165>4>6615rtyyyyyyyyyyyyyyyyyyyyyyyyyyyyytyyyyytuy",
|
||||||
"X$$X$X XX$$$XX$X$XXXXX X XX*ipp773dd33783::<<<4<<6664;=6<@===-==#;=;1;@21<<646655>>>>6iryyyryyyyyyyyyyyyyyyyyywyryyyyyyyyyyyutu",
|
"X$$X$X XX$$$XX$X$XXXXX X XX*ipp773dd33783::<<<4<<6664;=6<@===-==#;=;1;@21<<646655>>>>6iryyyryyyyyyyyyyyyyyyyyywyryyyyyyyyyyyutu",
|
||||||
"XXX$XX X$$$$$$X$XXXX XXXX&iipp783pp33735771<<46<644<=<66641,-@@:41112==2<4<44545a775piiyyyyyryyyyyyyyyyyyywyyyyyywyyyytyyyutyy",
|
"XXX$XX X$$$$$$X$XXXX XXXX&iipp783pp33735771<<46<644<=<66641,-@@:41112==2<4<44545a775piiyyyyyryyyyyyyyyyyyywyyyyyywyyyytyyyutyy",
|
||||||
"XX$*XX XX$$$$$$$$XXXXXXX oriipsp784dp333a7p761446<442=2661666611<6161<1<@=;2<46555aa5ppqryyyyrryryyyyyyyyyyyyyryywyywyywuytyyyyy",
|
"XX$*XX XX$$$$$$$$XXXXXXX oriipsp784dp333a7p761446<442=2661666611<6161<1<@=;2<46555aa5ppqryyyyrryryyyyyyyyyyyyyryywyywyywuytyyyyy",
|
||||||
"*oe*XX XXXXX$XXX$XXX Xoiihhisp774ppp837a7dp>4464<<2=<16666666666116661===;<1<445a77p3iryyyyyyyyyyyyyyyyyryyyyyyyyyyyyytyyyyyyy",
|
"*oe*XX XXXXX$XXX$XXX Xoiihhisp774ppp837a7dp>4464<<2=<16666666666116661===;<1<445a77p3iryyyyyyyyyyyyyyyyyryyyyyyyyyyyyytyyyyyyy",
|
||||||
"iiiXXXX XXXXX$XX$X X o@iihishpp788dpp#:7p7a,3447842=;166aaa6aaaaaa16666<;=;<<4643ap33iirryyyryyryyyyyyyyyyryyyyyyyyyyyytyyttyyy",
|
"iiiXXXX XXXXX$XX$X X o@iihishpp788dpp#:7p7a,3447842=;166aaa6aaaaaa16666<;=;<<4643ap33iirryyyryyryyyyyyyyyyryyyyyyyyyyyytyyttyyy",
|
||||||
"di&o o %*%XXXX$XXXX Oeiishippp773dd3:#:57>.-47664;@8<61a6a1aaaaaa676a11<=<<6548->53iirrryyyyyyyyyyyyyyyyyyyryyyrryyywyyyyyutuy",
|
"di&o o %*%XXXX$XXXX Oeiishippp773dd3:#:57>.-47664;@8<61a6a1aaaaaa676a11<=<<6548->53iirrryyyyyyyyyyyyyyyyyyyryyyrryyywyyyyyutuy",
|
||||||
"ppO.oX *q&XXXXXX$XXX..@,eshsipdp783pp3:##:,@.#:4474<:<<11<>1<1661<21<<<6<6;166643##,7irrryyyyyyyyyyyyyryyyyyywyyyryrywtyyyyyyyty",
|
"ppO.oX *q&XXXXXX$XXX..@,eshsipdp783pp3:##:,@.#:4474<:<<11<>1<1661<21<<<6<6;166643##,7irrryyyyyyyyyyyyyryyyyyywyyyryrywtyyyyyyyty",
|
||||||
"di*+X. *&OoXXXXXXX$ .o@&,sshsiip377pd3,##:3,@@4466718<<<2=====22=2===-=;2<6676158##333iryyyyytyyyyyyyyyyyyyyyyyyyyyyyyyyytytyyyy",
|
"di*+X. *&OoXXXXXXX$ .o@&,sshsiip377pd3,##:3,@@4466718<<<2=====22=2===-=;2<6676158##333iryyyyytyyyyyyyyyyyyyyyyyyyyyyyyyyytytyyyy",
|
||||||
"gge. *OoXXXXXXXXXX..@@,3shsipp778dp3,-@@@@+@-46667<22==;22,22=2111<6<<<<8677453##33iriyyyyyyyyyyyyyyyyyyyyyyyryyyyytyyyyyyyyyy",
|
"gge. *OoXXXXXXXXXX..@@,3shsipp778dp3,-@@@@+@-46667<22==;22,22=2111<6<<<<8677453##33iriyyyyyyyyyyyyyyyyyyyyyyyryyyyytyyyyyyyyyy",
|
||||||
"esi* &*XXXXXXXXXX .@@=;ppssppp77377:-:@+.+++-446774<<<1116666aa16a61<66<6766558#,3ihrryyyyyyyyyyyyyyyyyyyrryyyyyyyyyytytyyyyyy",
|
"esi* &*XXXXXXXXXX .@@=;ppssppp77377:-:@+.+++-446774<<<1116666aa16a61<66<6766558#,3ihrryyyyyyyyyyyyyyyyyyyrryyyyyyyyyytytyyyyyy",
|
||||||
"&.&eo oi& XXX$XXXXXX.@@@=ishhpsp873p3,:28@@.@+=4<4774868<1116aa6a611<88668664453##&3iryyyyyyyyhyyyyyyyyyyyyyyyyyyyryyyyyytyyyyyy",
|
"&.&eo oi& XXX$XXXXXX.@@@=ishhpsp873p3,:28@@.@+=4<4774868<1116aa6a611<88668664453##&3iryyyyyyyyhyyyyyyyyyyyyyyyyyyyryyyyyytyyyyyy",
|
||||||
"oXXo XX&eXXXXX XXXXX..=@@1ssipsp875p3::888:@.@@;44464<68<<2112;;;22<<6664<16443>##3iiryhuyyyyyyyyyyyyryyryyyyrryyyyyyryyyyyyyyyy",
|
"oXXo XX&eXXXXX XXXXX..=@@1ssipsp875p3::888:@.@@;44464<68<<2112;;;22<<6664<16443>##3iiryhuyyyyyyyyyyyyryyryyyyrryyyyyyryyyyyyyyyy",
|
||||||
"XXXXX X&OXXXXXXXX .@@===6ssis577377>::88882@@-:<<68<66611<2;;;2=;:<<<<644<<<5-#3&3iyhyyyyyyyyyyyyyyyyyyyyyyyyyryyyyyryyyyyyyyy",
|
"XXXXX X&OXXXXXXXX .@@===6ssis577377>::88882@@-:<<68<66611<2;;;2=;:<<<<644<<<5-#3&3iyhyyyyyyyyyyyyyyyyyyyyyyyyyryyyyyryyyyyyyyy",
|
||||||
"XXXX X %OoXXXXXXXX..@=@=@1ssis578377:::82822;@;:4<8244<8<1<46a56144<<<656<6<<1#&eerryryyyyyyuyyyyyyyyyyyyyyyyyyyyyyyyyytytytyty",
|
"XXXX X %OoXXXXXXXX..@=@=@1ssis578377:::82822;@;:4<8244<8<1<46a56144<<<656<6<<1#&eerryryyyyyyuyyyyyyyyyyyyyyyyyyyyyyyyyytytytyty",
|
||||||
"XXXXX XXXXXXXXX..@=@====sspp578877:8228282;=;<<><46666666aaaaaa66777a5<4<1,i-&3riryyyyyyyyyuyyyyyyyyyyyyyyyyyyyyyyyryyyyyyyyy",
|
"XXXXX XXXXXXXXX..@=@====sspp578877:8228282;=;<<><46666666aaaaaa66777a5<4<1,i-&3riryyyyyyyyyuyyyyyyyyyyyyyyyyyyyyyyyryyyyyyyyy",
|
||||||
"X$XXX XXXXXX ..@@==@===1ppp5878p8222828282==<:<<6<<<84667aaaa6aa777744<;113,eiryyyyyyyyyyuyuyhyyyiyyyyyyyyyyyyyyyyyyyytyyyyy",
|
"X$XXX XXXXXX ..@@==@===1ppp5878p8222828282==<:<<6<<<84667aaaa6aa777744<;113,eiryyyyyyyyyyuyuyhyyyiyyyyyyyyyyyyyyyyyyyytyyyyy",
|
||||||
"XXXXX XXXXXX X .@===@=====1ap387838:8:282822=@>4:>44>44644666a66aaa744>>:::>3,erryyuuyyyyyyyyhyyyyyyuyyyyyyyyyyyyyyytyyyyyyuty",
|
"XXXXX XXXXXX X .@===@=====1ap387838:8:282822=@>4:>44>44644666a66aaa744>>:::>3,erryyuuyyyyyyyyhyyyyyyuyyyyyyyyyyyyyyytyyyyyyuty",
|
||||||
"XXXX XXXXXXXo@@@===@@===11s>87888:8:828828@-p4;::<:<44<4446455656548>#---33Oirryyuyyyyyyuyyuyyyyyyyyhyyyyhyyyuyyyyuyyytuyyyy",
|
"XXXX XXXXXXXo@@@===@@===11s>87888:8:828828@-p4;::<:<44<4446455656548>#---33Oirryyuyyyyyyuyyuyyyyyyyyhyyyyhyyyuyyyyuyyytuyyyy",
|
||||||
"XXXXX XXXXXX .@@==========;1s187882;8:28888=+sp1,-=;-:<<444<<><141<<:;=@@=>p,XOrryuuuyyyyyyyyyhyyyyyyyyyyyyyyyyyyyyyyyyyytyyyy",
|
"XXXXX XXXXXX .@@==========;1s187882;8:28888=+sp1,-=;-:<<444<<><141<<:;=@@=>p,XOrryuuuyyyyyyyyyhyyyyyyyyyyyyyyyyyyyyyyyyyytyyyy",
|
||||||
"XXXX X XXXX .@@======@===@=1118788:;8:8288;.+d151-@@@@;:>2:---;,,-;--#@@@:333 ++qyyyyuyyyyyyyyyyuyyyuyyyyyyyyyuyyyyyyyyyyyutuy",
|
"XXXX X XXXX .@@======@===@=1118788:;8:8288;.+d151-@@@@;:>2:---;,,-;--#@@@:333 ++qyyyyuyyyyyyyyyyuyyyuyyyyyyyyyuyyyyyyyyyyyutuy",
|
||||||
"XXXXX XXXXX..@@=======@==@==>5<8788:;8:8:8:..&d,35>-@@@@-@@@@@@@@@@@@==@@,55p, Xqyyyyyyyyyhyyyyyyyyyyyyyyyyyyyyyuyyyyyyuttyyy",
|
"XXXXX XXXXX..@@=======@==@==>5<8788:;8:8:8:..&d,35>-@@@@-@@@@@@@@@@@@==@@,55p, Xqyyyyyyyyyhyyyyyyyyyyyyyyyyyyyyyuyyyyyyuttyyy",
|
||||||
"$XXX o...@@=========@====262888:;-82::-.. ip#513:=@@@@@..@......@@---;1>53, Xqhyyhyyyyuyyyyyhyuyhhuuyhyyyyyyyyyyyyyyyyuyy",
|
"$XXX o...@@=========@====262888:;-82::-.. ip#513:=@@@@@..@......@@---;1>53, Xqhyyhyyyyuyyyyyhyuyhhuuyhyyyyyyyyyyyyyyyyuyy",
|
||||||
"XXXXX oXoO@@@=======@=@=====s;878:=-:-;@.. hp@74>:---##@@......@@#-,--,<51p3 +Oryyuhuyyyyyyyyyyyyyyuyyyyyyyyyyuyyyyuyyyyy",
|
"XXXXX oXoO@@@=======@=@=====s;878:=-:-;@.. hp@74>:---##@@......@@#-,--,<51p3 +Oryyuhuyyyyyyyyyyyyyyuyyyyyyyyyyuyyyyuyyyyy",
|
||||||
"XXXX X .o**==========@@@=@===1;878:;-:#.. gd@54>3:-:--@@@.....@@-;--;<>13d& + +O&ryyyyhyuyuyyyuyyyyyyyyyyyuyyyyyuyyyyyyyu",
|
"XXXX X .o**==========@@@=@===1;878:;-:#.. gd@54>3:-:--@@@.....@@-;--;<>13d& + +O&ryyyyhyuyuyyyuyyyyyyyyyyyuyyyyyuyyyyyyyu",
|
||||||
"XXXXX .&h1@=========@@@=====2;778:@@. hd@343<;;;,--@@@@O@@@#;;-->1>5pg&X X%qyyyyyyyyyuyyyuyyyyyyyyyuyuyyyyyyyyyyy",
|
"XXXXX .&h1@=========@@@=====2;778:@@. hd@343<;;;,--@@@@O@@@#;;-->1>5pg&X X%qyyyyyyyyyuyyyuyyyyyyyyyuyuyyyyyyyyyyy",
|
||||||
"XXXXX Xisi1;===@======@@=====>>88#+ gg#,5>:>:-;---@@@@@@=-;;-;<>53df& X X&ryyyyyyyyuhyuyhyhyyyyhyyyuyyyyyyyyy",
|
"XXXXX Xisi1;===@======@@=====>>88#+ gg#,5>:>:-;---@@@@@@=-;;-;<>53df& X X&ryyyyyyyyuhyuyhyhyyyyhyyyuyyyyyyyyy",
|
||||||
"XXXX &idi31=========@@@=@==@=. + dg+-51<:;;;-#==#@#---->;-:>>5dff& XXXX*rhyyhuyyyyyyuyyyuyyyyyuyyhyyyyyyy",
|
"XXXX &idi31=========@@@=@==@=. + dg+-51<:;;;-#==#@#---->;-:>>5dff& XXXX*rhyyhuyyyyyyuyyyuyyyyyuyyhyyyyyyy",
|
||||||
"X XX +iipi3s2==@======@@@=@@.. df@#55<>:>,---#=#-;=-;;;:>>35gggO X XXX$XOqrhyyyyhuyuyyyyyyyuuyuyyyyyyyuy",
|
"X XX +iipi3s2==@======@@@=@@.. df@#55<>:>,---#=#-;=-;;;:>>35gggO X XXX$XOqrhyyyyhuyuyyyyyyyuuyuyyyyyyyuy",
|
||||||
"X X X+pssiiss2======@....... igs@>1<>::>;-----;;;;;>;>>3>dffg . XX XO %qyyyyyyyhhyyuuyyyuyyuyyyyhyyy",
|
"X X X+pssiiss2======@....... igs@>1<>::>;-----;;;;;>;>>3>dffg . XX XO %qyyyyyyyhhyyuuyyyuyyuyyyyhyyy",
|
||||||
"XXX .iissshss===@@... .. egf,-1<:<:>:----;>;;;>:;;>>5ggfs X XO+OX O*qiyyyyyyyyyyuyuyyuyyyyyyyy",
|
"XXX .iissshss===@@... .. egf,-1<:<:>:----;>;;;>:;;>>5ggfs X XO+OX O*qiyyyyyyyyyyuyuyyuyyyyyyyy",
|
||||||
"XXXX .ppssssdg,...... &gfd@>4::>>>----;;;;;>>;>>,gfggq X+ X XXXOOO9rryyyyhyyyyyyyuyyyyyyy",
|
"XXXX .ppssssdg,...... &gfd@>4::>>>----;;;;;>>;>>,gfggq X+ X XXXOOO9rryyyyhyyyyyyyuyyyyyyy",
|
||||||
"XXX X .iphhshhsO X&gff,#><>:>;;---;>;2;>::--pgfgf* o ++ + X XXX++O++%&ryyyhyyuyyyyyyyyyy",
|
"XXX X .iphhshhsO X&gff,#><>:>;;---;>;2;>::--pgfgf* o ++ + X XXX++O++%&ryyyhyyuyyyyyyyyyy",
|
||||||
"XXXX +3pdphi3 *ggfg#-><;:>:-;=;-;;;>;-#3gfgfg X+XX +X XXXXXXXXX%qyhyyyyyyuyyyyyy",
|
"XXXX +3pdphi3 *ggfg#-><;:>:-;=;-;;;>;-#3gfgfg X+XX +X XXXXXXXXX%qyhyyyyyyuyyyyyy",
|
||||||
"XXX iphi++ %ggffd-><><3---@----;>:@,gfffgi. +XX X+X X+ XXXoXXXXXX%qyyrhryyuyyyyy",
|
"XXX iphi++ %ggffd-><><3---@----;>:@,gfffgi. +XX X+X X+ XXXoXXXXXX%qyyrhryyuyyyyy",
|
||||||
"XXXX. pdi+ . Ogffffg;>1<>:-;@---=2,-,gffffgO XXXX X +X++X+X+ X+X XXX%%riryyyuyyyyy",
|
"XXXX. pdi+ . Ogffffg;>1<>:-;@---=2,-,gffffgO XXXX X +X++X+X+ X+X XXX%%riryyyuyyyyy",
|
||||||
" X X .ih& hgffffd-56>::-=--#->,-dfffffg X XXX X + X+o X+XOXXXX%ryyyyyyyyy",
|
" X X .ih& hgffffd-56>::-=--#->,-dfffffg X XXX X + X+o X+XOXXXX%ryyyyyyyyy",
|
||||||
" o X ii + *ggffffp:553>;-,--,>#gffffffr XX X XX+X+ Xo o+ OXo XXX%yyyyyyyyy",
|
" o X ii + *ggffffp:553>;-,--,>#gffffffr XX X XX+X+ Xo o+ OXo XXX%yyyyyyyyy",
|
||||||
"O o i& +ggfffff3,555>,3>,1,gfffffffO o+XXXX XXX X o XoXX +XXX$ryuyyuyyy",
|
"O o i& +ggfffff3,555>,3>,1,gfffffffO o+XXXX XXX X o XoXX +XXX$ryuyyuyyy",
|
||||||
",. 3+. qgffffff3>531>1>13gfffffffh . X X++XX +X+XX X X X + + X$*yyyuyyyy",
|
",. 3+. qgffffff3>531>1>13gfffffffh . X X++XX +X+XX X X X + + X$*yyyuyyyy",
|
||||||
"iO & o&gfffffff35pddddsiffffffff& X X XXXX X X o X X X X XXrhyyytyy",
|
"iO & o&gfffffff35pddddsiffffffff& X X XXXX X X o X X X X XXrhyyytyy",
|
||||||
"si . O ogfffffffffgfdhpO Ogfffffg ++ + X X+XX+ +X X+ X X XX X Xrryuyyry",
|
"si . O ogfffffffffgfdhpO Ogfffffg ++ + X X+XX+ +X X+ X X XX X Xrryuyyry",
|
||||||
"si# ... Xifffffffe**O+o ++ OgffffqX +X OX +X X X+X XX X+ X X X&yyyyyyy",
|
"si# ... Xifffffffe**O+o ++ OgffffqX +X OX +X X X+X XX X+ X X X&yyyyyyy",
|
||||||
"ssi@ &ffffffq+ + + o OgffgOX + X++ X++ OX+ XX+XXXXXXXX XX X X X$yyyyyyy",
|
"ssi@ &ffffffq+ + + o OgffgOX + X++ X++ OX+ XX+XXXXXXXX XX X X X$yyyyyyy",
|
||||||
"sip&.... &gffff& +o + %gfr + + X X X X+XX+X X +X+ +X X X X$yyyyyyy",
|
"sip&.... &gffff& +o + %gfr + + X X X X+XX+X X +X+ +X X X X$yyyyyyy",
|
||||||
"pisi+. . +hfff&X + + &gO X X+ X+XO+X + X X X XX o XX X X Xqryryuy",
|
"pisi+. . +hfff&X + + &gO X X+ X+XO+X + X X X XX o XX X X Xqryryuy",
|
||||||
"ppp3#. +eff& o + *+ + + + + XX X OXXX X +X X+ X XX X Xhyyyyu",
|
"ppp3#. +eff& o + *+ + + + + XX X OXXX X +X X+ X XX X Xhyyyyu",
|
||||||
"ppi3,. X*fq X + + O + ++ X++XX+X X X+XXXX+ Xo X X X XXrrhyyy",
|
"ppi3,. X*fq X + + O + ++ X++XX+X X X+XXXX+ Xo X X X XXrrhyyy",
|
||||||
"p5pi,.. O& + +XX X + X X X O+X X X X X X X XX X*yryyu",
|
"p5pi,.. O& + +XX X + X X X O+X X X X X X X XX X*yryyu",
|
||||||
"p5pi3o o + X o+OO X X +X+ X+ + +X X o o X X+ XX X X XXryyuy",
|
"p5pi3o o + X o+OO X X +X+ X+ + +X X o o X X+ XX X X XXryyuy",
|
||||||
"spp3,. X riggggghy+ + + + X+ X Xo XXo+X X X X+ X X X X Xqyyyu",
|
"spp3,. X riggggghy+ + + + X+ X Xo XXo+X X X X+ X X X X Xqyyyu",
|
||||||
"ppi3, . X O+ &gfffffffg&+ + +X X X +X o +X X+ X qiyyu",
|
"ppi3, . X O+ &gfffffffg&+ + +X X X +X o +X X+ X qiyyu",
|
||||||
"6pp3,. X +hgfffffffgqX o +XX + X X ooX X X X X X X X %yyyu",
|
"6pp3,. X +hgfffffffgqX o +XX + X X ooX X X X X X X X %yyyu",
|
||||||
"pp5i, X+ +X &gffffffffgO X X + ++ + X oX X X XX Xyhyy",
|
"pp5i, X+ +X &gffffffffgO X X + ++ + X oX X X XX Xyhyy",
|
||||||
"ppi3# . +X Ohgfffffffgi+ + ++ X X X +X +X o X XX XX X Xryyu",
|
"ppi3# . +X Ohgfffffffgi+ + ++ X X X +X +X o X XX XX X Xryyu",
|
||||||
"p5ii# Oigffffffffg* X X+X ++XX+ + +XXXoX XX X X X Xryyu",
|
"p5ii# Oigffffffffg* X X+X ++XX+ + +XXXoX XX X X X Xryyu",
|
||||||
"5pp1*. X +XX Oiggfffffffhh OO X+ + + X+XX +.X X o+ X XX X X&uyy",
|
"5pp1*. X +XX Oiggfffffffhh OO X+ + + X+XX +.X X o+ X XX X X&uyy",
|
||||||
"5pp3@ X +XX ihffffffffgh#oX X+O + X X o o X X XX X X*uuu",
|
"5pp3@ X +XX ihffffffffgh#oX X+O + X X o o X X XX X X*uuu",
|
||||||
"p3pi. + X+eggffffffgiqO +X++X oo o + . ooo + X X X%uuu",
|
"p3pi. + X+eggffffffgiqO +X++X oo o + . ooo + X X X%uuu",
|
||||||
"p53p. &ii&&&&#O+ + + O*hgfffffgi&O X o O ++ oo .o.o$OO% . X X X $hyu",
|
"p53p. &ii&&&&#O+ + + O*hgfffffgi&O X o O ++ oo .o.o$OO% . X X X $hyu",
|
||||||
"p5i3. 3hfffi3rihhhii3r&& X oihffffgi&&XXoX+X X O+ X ooooo+*@*=#=*=*&, X . XX X$hyu",
|
"p5i3. 3hfffi3rihhhii3r&& X oihffffgi&&XXoX+X X O+ X ooooo+*@*=#=*=*&, X . XX X$hyu",
|
||||||
"p5i3 .idffg&iiiiphhddhip& Xo &hgffgi&&* o X oX X X X oXX o.Oe,22,,2112s%oXX . X Xryy",
|
"p5i3 .idffg&iiiiphhddhip& Xo &hgffgi&&* o X oX X X X oXX o.Oe,22,,2112s%oXX . X Xryy",
|
||||||
"5ii,. Oihgggiiiihhphhhiihi* X X XXOhdggh&ii XX O XXX+X+X+X+ oo .ooe,=222e22eso.o$... . XXryy",
|
"5ii,. Oihgggiiiihhphhhiihi* X X XXOhdggh&ii XX O XXX+X+X+X+ oo .ooe,=222e22eso.o$... . XXryy",
|
||||||
"p3p# Opgghfiiihgggdgghhhhi* oX ehgheid*XXoXXX X+ XX+X+ X ..&ieeq*1ee,eeee&,e=2=#--&* X Xquh",
|
"p3p# Opgghfiiihgggdgghhhhi* oX ehgheid*XXoXXX X+ XX+X+ X ..&ieeq*1ee,eeee&,e=2=#--&* X Xquh",
|
||||||
"pppO *rpggiqqiiiiihiphpphiio OX o.&gsieii. X+ XX+X + .@&ifseeeheeeeehq,de122=17i*. . X*yu",
|
"pppO *rpggiqqiiiiihiphpphiio OX o.&gsieii. X+ XX+X + .@&ifseeeheeeeehq,de122=17i*. . X*yu",
|
||||||
"p3p. . O&&q&&iiiiiihihihiiiii X X + hp&&3O X + X+ + + +.@=,sgh1e,heeesqhe,s11222221&% + X+ X%uu",
|
"p3p. . O&&q&&iiiiiihihihiiiii X X + hp&&3O X + X+ + + +.@=,sgh1e,heeesqhe,s11222221&% + X+ X%uu",
|
||||||
"ppi. . +oO*&&e&i,iiiiiX XX X &i**& + X + XX X +@-,2212eeieqee,,ee*,22222222@o X X X%hu",
|
"ppi. . +oO*&&e&i,iiiiiX XX X &i**& + X + XX X +@-,2212eeieqee,,ee*,22222222@o X X X%hu",
|
||||||
"ii,. .XoO +&OO+ XX ++ +..+@>6a5=2,eih*ihf*&hie=22222==1o + X XXOyy",
|
"ii,. .XoO +&OO+ XX ++ +..+@>6a5=2,eih*ihf*&hie=22222==1o + X XXOyy",
|
||||||
"5p,. X +** X +X ..*-375522=eigqeig&,ie,222222=2<oo X X X Xyh",
|
"5p,. X +** X +X ..*-375522=eigqeig&,ie,222222=2<oo X X X Xyh",
|
||||||
"5i# + O+ + XX oo.@O##O@@@@O**oo+*+OOO..@@....@. X XXX XXXuy",
|
"5i# + O+ + XX oo.@O##O@@@@O**oo+*+OOO..@@....@. X XXX XXXuy",
|
||||||
"ip# X o .oo....+..ooo.XooX Xoo..oo..+.. X + Xrh",
|
"ip# X o .oo....+..ooo.XooX Xoo..oo..+.. X + Xrh",
|
||||||
"p3@ + X oXoX .oo .oXo .oo .oo o .oo X + + X X X X XXqy",
|
"p3@ + X oXoX .oo .oXo .oo .oo o .oo X + + X X X X XXqy",
|
||||||
"pi@ X XX +o+ X X XXX XX.. XOoX X oo X X + X X XX&y"
|
"pi@ X XX +o+ X X XXX XX.. XOoX X oo X X + X X XX&y"
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,2 +1,2 @@
|
||||||
P7 332
|
P7 332
|
||||||
# Artificially edited file to cause unexpected EOF
|
# Artificially edited file to cause unexpected EOF
|
||||||
|
|
|
@ -1,174 +1,174 @@
|
||||||
#define hopper_underscore_width 128
|
#define hopper_underscore_width 128
|
||||||
#define hopper_underscore_height 128
|
#define hopper_underscore_height 128
|
||||||
static char hopper_underscore_bits[] = {
|
static char hopper_underscore_bits[] = {
|
||||||
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0x3D, 0x80, 0x96, 0xDA, 0xB6, 0xD6, 0x2A,
|
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0x3D, 0x80, 0x96, 0xDA, 0xB6, 0xD6, 0x2A,
|
||||||
0xA9, 0x6D, 0x25, 0x29, 0xFF, 0xFF, 0xFF, 0xBF, 0xFE, 0x7D, 0xC0, 0xFB,
|
0xA9, 0x6D, 0x25, 0x29, 0xFF, 0xFF, 0xFF, 0xBF, 0xFE, 0x7D, 0xC0, 0xFB,
|
||||||
0x69, 0x69, 0xA9, 0xD5, 0x96, 0x96, 0x5E, 0x9A, 0xFF, 0xFF, 0xFF, 0x9F,
|
0x69, 0x69, 0xA9, 0xD5, 0x96, 0x96, 0x5E, 0x9A, 0xFF, 0xFF, 0xFF, 0x9F,
|
||||||
0xFE, 0xFD, 0x80, 0xFF, 0x97, 0xB6, 0x5A, 0x6A, 0x5D, 0x6D, 0x5A, 0x62,
|
0xFE, 0xFD, 0x80, 0xFF, 0x97, 0xB6, 0x5A, 0x6A, 0x5D, 0x6D, 0x5A, 0x62,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xC1, 0xCF, 0x5F, 0x89, 0xA5, 0xD5,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xC1, 0xCF, 0x5F, 0x89, 0xA5, 0xD5,
|
||||||
0xAA, 0x92, 0xA5, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xF8, 0x00,
|
0xAA, 0x92, 0xA5, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xF8, 0x00,
|
||||||
0xB8, 0x59, 0xAA, 0x56, 0xDA, 0x5A, 0x56, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xB8, 0x59, 0xAA, 0x56, 0xDA, 0x5A, 0x56, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFE, 0xFC, 0xF9, 0x00, 0xF0, 0xA6, 0x55, 0xA9, 0x65, 0xA5, 0xA9, 0xA2,
|
0xFE, 0xFC, 0xF9, 0x00, 0xF0, 0xA6, 0x55, 0xA9, 0x65, 0xA5, 0xA9, 0xA2,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0x71, 0x00, 0x60, 0x70, 0xAA, 0x54,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0x71, 0x00, 0x60, 0x70, 0xAA, 0x54,
|
||||||
0xAA, 0x5A, 0x54, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0x38, 0x00,
|
0xAA, 0x5A, 0x54, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0x38, 0x00,
|
||||||
0xE0, 0x80, 0x55, 0xAB, 0x55, 0x75, 0xAB, 0x56, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xE0, 0x80, 0x55, 0xAB, 0x55, 0x75, 0xAB, 0x56, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFE, 0x1D, 0x70, 0x00, 0xF0, 0x00, 0xAE, 0xAA, 0xAA, 0xA6, 0x95, 0x55,
|
0xFE, 0x1D, 0x70, 0x00, 0xF0, 0x00, 0xAE, 0xAA, 0xAA, 0xA6, 0x95, 0x55,
|
||||||
0xFB, 0xFF, 0xFF, 0xFF, 0xFE, 0x1D, 0xF0, 0x00, 0xF0, 0x00, 0x50, 0x55,
|
0xFB, 0xFF, 0xFF, 0xFF, 0xFE, 0x1D, 0xF0, 0x00, 0xF0, 0x00, 0x50, 0x55,
|
||||||
0x55, 0x59, 0x6A, 0xAA, 0xF3, 0xFF, 0xFF, 0xFF, 0xFE, 0x04, 0xF0, 0x00,
|
0x55, 0x59, 0x6A, 0xAA, 0xF3, 0xFF, 0xFF, 0xFF, 0xFE, 0x04, 0xF0, 0x00,
|
||||||
0xF0, 0x00, 0xA4, 0xAA, 0xA9, 0xA5, 0x95, 0x55, 0x21, 0xFF, 0xFF, 0xFF,
|
0xF0, 0x00, 0xA4, 0xAA, 0xA9, 0xA5, 0x95, 0x55, 0x21, 0xFF, 0xFF, 0xFF,
|
||||||
0xFE, 0x01, 0xF8, 0x00, 0xF0, 0x00, 0x50, 0x55, 0x56, 0x5A, 0x6A, 0xAA,
|
0xFE, 0x01, 0xF8, 0x00, 0xF0, 0x00, 0x50, 0x55, 0x56, 0x5A, 0x6A, 0xAA,
|
||||||
0x83, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0xFC, 0x00, 0xF0, 0x01, 0x50, 0xD5,
|
0x83, 0x9F, 0xFF, 0xFF, 0xFE, 0x00, 0xFC, 0x00, 0xF0, 0x01, 0x50, 0xD5,
|
||||||
0x95, 0x95, 0xA5, 0x5A, 0x83, 0x9F, 0xFF, 0xFF, 0xFE, 0x81, 0xFF, 0x00,
|
0x95, 0x95, 0xA5, 0x5A, 0x83, 0x9F, 0xFF, 0xFF, 0xFE, 0x81, 0xFF, 0x00,
|
||||||
0xE0, 0x0B, 0xA0, 0xAA, 0x7A, 0x6A, 0x5A, 0x65, 0x80, 0x1F, 0xF0, 0xFF,
|
0xE0, 0x0B, 0xA0, 0xAA, 0x7A, 0x6A, 0x5A, 0x65, 0x80, 0x1F, 0xF0, 0xFF,
|
||||||
0xFE, 0xF0, 0xFF, 0x00, 0xF0, 0x3F, 0x50, 0x55, 0xA5, 0xB5, 0xA5, 0xAA,
|
0xFE, 0xF0, 0xFF, 0x00, 0xF0, 0x3F, 0x50, 0x55, 0xA5, 0xB5, 0xA5, 0xAA,
|
||||||
0x00, 0x1F, 0xF8, 0xFD, 0xFE, 0xF0, 0xF7, 0x00, 0xF0, 0x6D, 0xA0, 0xAA,
|
0x00, 0x1F, 0xF8, 0xFD, 0xFE, 0xF0, 0xF7, 0x00, 0xF0, 0x6D, 0xA0, 0xAA,
|
||||||
0x5A, 0x6A, 0x5A, 0x55, 0x83, 0x0F, 0xF8, 0xC9, 0xFE, 0x79, 0x00, 0xF8,
|
0x5A, 0x6A, 0x5A, 0x55, 0x83, 0x0F, 0xF8, 0xC9, 0xFE, 0x79, 0x00, 0xF8,
|
||||||
0x02, 0xC0, 0x81, 0x55, 0xAD, 0xD5, 0xA5, 0xA6, 0xE3, 0x03, 0xFC, 0xC0,
|
0x02, 0xC0, 0x81, 0x55, 0xAD, 0xD5, 0xA5, 0xA6, 0xE3, 0x03, 0xFC, 0xC0,
|
||||||
0xFE, 0xFF, 0x04, 0xF0, 0x00, 0x80, 0x63, 0xAA, 0x52, 0x2A, 0x5A, 0x58,
|
0xFE, 0xFF, 0x04, 0xF0, 0x00, 0x80, 0x63, 0xAA, 0x52, 0x2A, 0x5A, 0x58,
|
||||||
0xE7, 0x03, 0xFC, 0xE1, 0xFE, 0xFF, 0x2F, 0xFC, 0x03, 0x0C, 0xFE, 0x55,
|
0xE7, 0x03, 0xFC, 0xE1, 0xFE, 0xFF, 0x2F, 0xFC, 0x03, 0x0C, 0xFE, 0x55,
|
||||||
0xA9, 0x55, 0x66, 0x15, 0xF3, 0x0F, 0x7C, 0xF0, 0xFE, 0xFF, 0xFF, 0xFD,
|
0xA9, 0x55, 0x66, 0x15, 0xF3, 0x0F, 0x7C, 0xF0, 0xFE, 0xFF, 0xFF, 0xFD,
|
||||||
0xEF, 0x38, 0xFF, 0xAA, 0x56, 0xAA, 0x99, 0xAA, 0xF7, 0x1F, 0x78, 0xF0,
|
0xEF, 0x38, 0xFF, 0xAA, 0x56, 0xAA, 0x99, 0xAA, 0xF7, 0x1F, 0x78, 0xF0,
|
||||||
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0x55, 0xAA, 0x5B, 0x66, 0xA4,
|
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0x55, 0xAA, 0x5B, 0x66, 0xA4,
|
||||||
0xFF, 0x9F, 0xFD, 0xF0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB,
|
0xFF, 0x9F, 0xFD, 0xF0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB,
|
||||||
0x65, 0xA4, 0x99, 0x1B, 0xFF, 0xDF, 0xFF, 0xE0, 0xFE, 0xFF, 0xFF, 0xFF,
|
0x65, 0xA4, 0x99, 0x1B, 0xFF, 0xDF, 0xFF, 0xE0, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x69, 0x51, 0x5A, 0x24, 0x62, 0xFF, 0xDF, 0xFF, 0xEC,
|
0xFF, 0xFF, 0xFF, 0x69, 0x51, 0x5A, 0x24, 0x62, 0xFF, 0xDF, 0xFF, 0xEC,
|
||||||
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0xAA, 0x24, 0x59, 0x55,
|
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95, 0xAA, 0x24, 0x59, 0x55,
|
||||||
0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x25,
|
0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x25,
|
||||||
0x49, 0xAD, 0x55, 0x2A, 0xFF, 0xFF, 0xFF, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF,
|
0x49, 0xAD, 0x55, 0x2A, 0xFF, 0xFF, 0xFF, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x9B, 0xA5, 0x52, 0x2A, 0x94, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0x9B, 0xA5, 0x52, 0x2A, 0x94, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x67, 0x64, 0xC1, 0x92, 0x6D,
|
0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x67, 0x64, 0xC1, 0x92, 0x6D,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x95,
|
||||||
0x49, 0x2C, 0x55, 0x92, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF,
|
0x49, 0x2C, 0x55, 0x92, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||||
0x7F, 0xFF, 0xFF, 0x15, 0xB4, 0x62, 0x44, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x7F, 0xFF, 0xFF, 0x15, 0xB4, 0x62, 0x44, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFD, 0xFF, 0x51, 0x30, 0x03, 0xE0, 0xFF, 0x53, 0x03, 0x89, 0x96, 0x92,
|
0xFD, 0xFF, 0x51, 0x30, 0x03, 0xE0, 0xFF, 0x53, 0x03, 0x89, 0x96, 0x92,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x7F, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xCD,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x7F, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xCD,
|
||||||
0x68, 0x19, 0x68, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0x00, 0x00,
|
0x68, 0x19, 0x68, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0x00, 0x00,
|
||||||
0x00, 0x00, 0xFF, 0x13, 0x4A, 0x64, 0x23, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x00, 0x00, 0xFF, 0x13, 0x4A, 0x64, 0x23, 0x49, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x47, 0x8A, 0xA4, 0xD8, 0x30,
|
0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x47, 0x8A, 0xA4, 0xD8, 0x30,
|
||||||
0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x39,
|
0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x39,
|
||||||
0x29, 0x49, 0x06, 0x86, 0xCC, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0x00, 0x00,
|
0x29, 0x49, 0x06, 0x86, 0xCC, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0x00, 0x00,
|
||||||
0x80, 0x00, 0xF2, 0x81, 0x50, 0x31, 0xA2, 0x8C, 0xE4, 0xFF, 0xFF, 0xFF,
|
0x80, 0x00, 0xF2, 0x81, 0x50, 0x31, 0xA2, 0x8C, 0xE4, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0x0A, 0x08, 0x00, 0x00, 0x00, 0xF0, 0xA7, 0x46, 0x8C, 0x28, 0x31,
|
0xFF, 0x0A, 0x08, 0x00, 0x00, 0x00, 0xF0, 0xA7, 0x46, 0x8C, 0x28, 0x31,
|
||||||
0xC0, 0xFC, 0xFF, 0xFF, 0xFC, 0x03, 0x10, 0x00, 0xE0, 0x01, 0xE0, 0x19,
|
0xC0, 0xFC, 0xFF, 0xFF, 0xFC, 0x03, 0x10, 0x00, 0xE0, 0x01, 0xE0, 0x19,
|
||||||
0x41, 0x61, 0x66, 0x05, 0xE0, 0xB8, 0xFF, 0xFF, 0x7E, 0x0C, 0x44, 0x00,
|
0x41, 0x61, 0x66, 0x05, 0xE0, 0xB8, 0xFF, 0xFF, 0x7E, 0x0C, 0x44, 0x00,
|
||||||
0x40, 0xBF, 0xEF, 0x41, 0x5C, 0x04, 0x00, 0xA8, 0xF0, 0xC1, 0xFF, 0xFF,
|
0x40, 0xBF, 0xEF, 0x41, 0x5C, 0x04, 0x00, 0xA8, 0xF0, 0xC1, 0xFF, 0xFF,
|
||||||
0xFE, 0x21, 0x9E, 0x00, 0xE0, 0xFF, 0xED, 0xA5, 0x12, 0x92, 0xDB, 0xA2,
|
0xFE, 0x21, 0x9E, 0x00, 0xE0, 0xFF, 0xED, 0xA5, 0x12, 0x92, 0xDB, 0xA2,
|
||||||
0xE0, 0xC0, 0xFF, 0xFF, 0x7D, 0xFA, 0xFF, 0x00, 0x70, 0x00, 0xFF, 0x42,
|
0xE0, 0xC0, 0xFF, 0xFF, 0x7D, 0xFA, 0xFF, 0x00, 0x70, 0x00, 0xFF, 0x42,
|
||||||
0x84, 0x0C, 0x00, 0x08, 0xC0, 0xC0, 0xFF, 0xFC, 0x7D, 0xFF, 0x90, 0x07,
|
0x84, 0x0C, 0x00, 0x08, 0xC0, 0xC0, 0xFF, 0xFC, 0x7D, 0xFF, 0x90, 0x07,
|
||||||
0xC0, 0x1F, 0xDB, 0x0A, 0x24, 0xC8, 0x68, 0x09, 0xCC, 0xC0, 0x7F, 0xFE,
|
0xC0, 0x1F, 0xDB, 0x0A, 0x24, 0xC8, 0x68, 0x09, 0xCC, 0xC0, 0x7F, 0xFE,
|
||||||
0x1E, 0x7F, 0x3E, 0x00, 0xD4, 0xFF, 0x3E, 0x60, 0x81, 0x21, 0x02, 0xA0,
|
0x1E, 0x7F, 0x3E, 0x00, 0xD4, 0xFF, 0x3E, 0x60, 0x81, 0x21, 0x02, 0xA0,
|
||||||
0xFC, 0xE0, 0x7F, 0xFF, 0xCE, 0x9F, 0xFF, 0x05, 0xFA, 0xFF, 0xBF, 0x04,
|
0xFC, 0xE0, 0x7F, 0xFF, 0xCE, 0x9F, 0xFF, 0x05, 0xFA, 0xFF, 0xBF, 0x04,
|
||||||
0x24, 0x0A, 0x61, 0x1B, 0xFC, 0xC0, 0xBF, 0xFF, 0xAC, 0x7D, 0xFF, 0x03,
|
0x24, 0x0A, 0x61, 0x1B, 0xFC, 0xC0, 0xBF, 0xFF, 0xAC, 0x7D, 0xFF, 0x03,
|
||||||
0x40, 0x1F, 0x80, 0x91, 0xC2, 0xA0, 0x05, 0x80, 0xFF, 0x8D, 0x7F, 0xFF,
|
0x40, 0x1F, 0x80, 0x91, 0xC2, 0xA0, 0x05, 0x80, 0xFF, 0x8D, 0x7F, 0xFF,
|
||||||
0xEF, 0xF5, 0xDF, 0x00, 0x00, 0x94, 0x42, 0x81, 0x01, 0x10, 0x92, 0x85,
|
0xEF, 0xF5, 0xDF, 0x00, 0x00, 0x94, 0x42, 0x81, 0x01, 0x10, 0x92, 0x85,
|
||||||
0xFF, 0xFD, 0xFF, 0xFE, 0x2C, 0x62, 0x03, 0x00, 0x20, 0x00, 0x10, 0x2B,
|
0xFF, 0xFD, 0xFF, 0xFE, 0x2C, 0x62, 0x03, 0x00, 0x20, 0x00, 0x10, 0x2B,
|
||||||
0x24, 0x82, 0x00, 0x20, 0xFF, 0xFD, 0xFF, 0xFF, 0xBD, 0x55, 0x01, 0x00,
|
0x24, 0x82, 0x00, 0x20, 0xFF, 0xFD, 0xFF, 0xFF, 0xBD, 0x55, 0x01, 0x00,
|
||||||
0x40, 0x00, 0x08, 0x19, 0x81, 0x58, 0x54, 0x14, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x40, 0x00, 0x08, 0x19, 0x81, 0x58, 0x54, 0x14, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0x3C, 0x82, 0x05, 0x08, 0x00, 0x24, 0x20, 0x81, 0x24, 0x02, 0x02, 0x82,
|
0x3C, 0x82, 0x05, 0x08, 0x00, 0x24, 0x20, 0x81, 0x24, 0x02, 0x02, 0x82,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x82, 0x01, 0x00, 0x00, 0x00, 0x69, 0x22,
|
0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x82, 0x01, 0x00, 0x00, 0x00, 0x69, 0x22,
|
||||||
0x90, 0xA0, 0x49, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x2D, 0x26, 0x00, 0x00,
|
0x90, 0xA0, 0x49, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x2D, 0x26, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x20, 0x20, 0x0A, 0x02, 0x20, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x00, 0x00, 0x20, 0x20, 0x0A, 0x02, 0x20, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0x04, 0x81, 0x01, 0x00, 0x10, 0x00, 0xA0, 0x04, 0x02, 0x0A, 0x09, 0x00,
|
0x04, 0x81, 0x01, 0x00, 0x10, 0x00, 0xA0, 0x04, 0x02, 0x0A, 0x09, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0x19, 0x02, 0x02, 0x00, 0x00, 0x02, 0x42,
|
0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0x19, 0x02, 0x02, 0x00, 0x00, 0x02, 0x42,
|
||||||
0x50, 0xA0, 0x20, 0x95, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x00, 0x01,
|
0x50, 0xA0, 0x20, 0x95, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x00, 0x01,
|
||||||
0x80, 0x02, 0x42, 0x52, 0x40, 0x20, 0xA0, 0x20, 0xFF, 0xFF, 0xFF, 0x7F,
|
0x80, 0x02, 0x42, 0x52, 0x40, 0x20, 0xA0, 0x20, 0xFF, 0xFF, 0xFF, 0x7F,
|
||||||
0x00, 0x00, 0x8C, 0x01, 0x40, 0x00, 0x00, 0x00, 0x06, 0x06, 0x09, 0x05,
|
0x00, 0x00, 0x8C, 0x01, 0x40, 0x00, 0x00, 0x00, 0x06, 0x06, 0x09, 0x05,
|
||||||
0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x50, 0x00, 0x00, 0x40, 0x00, 0x02, 0x18,
|
0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x50, 0x00, 0x00, 0x40, 0x00, 0x02, 0x18,
|
||||||
0xA0, 0x90, 0x84, 0x64, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x10, 0x81, 0x07,
|
0xA0, 0x90, 0x84, 0x64, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x10, 0x81, 0x07,
|
||||||
0xD0, 0x00, 0x48, 0x82, 0x02, 0x02, 0x20, 0x00, 0xFF, 0xFF, 0xFF, 0x0F,
|
0xD0, 0x00, 0x48, 0x82, 0x02, 0x02, 0x20, 0x00, 0xFF, 0xFF, 0xFF, 0x0F,
|
||||||
0x00, 0x04, 0xC0, 0x7E, 0x9F, 0x01, 0x10, 0x04, 0x00, 0x00, 0x24, 0x25,
|
0x00, 0x04, 0xC0, 0x7E, 0x9F, 0x01, 0x10, 0x04, 0x00, 0x00, 0x24, 0x25,
|
||||||
0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x60, 0x48, 0xC0, 0xC1, 0x13, 0x00, 0x41,
|
0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x60, 0x48, 0xC0, 0xC1, 0x13, 0x00, 0x41,
|
||||||
0x9A, 0x99, 0x81, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x40, 0x40, 0x60, 0x00,
|
0x9A, 0x99, 0x81, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x40, 0x40, 0x60, 0x00,
|
||||||
0x84, 0x0B, 0x00, 0x50, 0x02, 0x40, 0x24, 0x90, 0xFF, 0xFF, 0xFF, 0x01,
|
0x84, 0x0B, 0x00, 0x50, 0x02, 0x40, 0x24, 0x90, 0xFF, 0xFF, 0xFF, 0x01,
|
||||||
0x00, 0x00, 0x32, 0x00, 0x00, 0x57, 0x00, 0x04, 0x40, 0x02, 0x01, 0x05,
|
0x00, 0x00, 0x32, 0x00, 0x00, 0x57, 0x00, 0x04, 0x40, 0x02, 0x01, 0x05,
|
||||||
0xF8, 0xFF, 0xFF, 0x01, 0x40, 0x00, 0x38, 0x00, 0x00, 0x0E, 0x10, 0x05,
|
0xF8, 0xFF, 0xFF, 0x01, 0x40, 0x00, 0x38, 0x00, 0x00, 0x0E, 0x10, 0x05,
|
||||||
0x99, 0x0A, 0xA4, 0x0A, 0xFC, 0xFF, 0x7F, 0x00, 0x80, 0x30, 0x10, 0x00,
|
0x99, 0x0A, 0xA4, 0x0A, 0xFC, 0xFF, 0x7F, 0x00, 0x80, 0x30, 0x10, 0x00,
|
||||||
0x00, 0x84, 0x04, 0x60, 0x00, 0x50, 0x00, 0x60, 0xFC, 0xFF, 0xFF, 0x00,
|
0x00, 0x84, 0x04, 0x60, 0x00, 0x50, 0x00, 0x60, 0xFC, 0xFF, 0xFF, 0x00,
|
||||||
0x00, 0x3A, 0x08, 0x00, 0x00, 0x04, 0x8E, 0x06, 0x00, 0x41, 0x56, 0x00,
|
0x00, 0x3A, 0x08, 0x00, 0x00, 0x04, 0x8E, 0x06, 0x00, 0x41, 0x56, 0x00,
|
||||||
0xF8, 0xFE, 0xFF, 0x01, 0x80, 0x79, 0xA0, 0x7F, 0xFF, 0x01, 0x06, 0x20,
|
0xF8, 0xFE, 0xFF, 0x01, 0x80, 0x79, 0xA0, 0x7F, 0xFF, 0x01, 0x06, 0x20,
|
||||||
0x51, 0x08, 0x00, 0x2A, 0xF8, 0xFF, 0xFF, 0x00, 0xE0, 0x3F, 0xE0, 0xAF,
|
0x51, 0x08, 0x00, 0x2A, 0xF8, 0xFF, 0xFF, 0x00, 0xE0, 0x3F, 0xE0, 0xAF,
|
||||||
0x00, 0x00, 0x06, 0x11, 0x91, 0x52, 0x02, 0x92, 0xF8, 0xFF, 0xFF, 0x00,
|
0x00, 0x00, 0x06, 0x11, 0x91, 0x52, 0x02, 0x92, 0xF8, 0xFF, 0xFF, 0x00,
|
||||||
0x00, 0x7F, 0x00, 0x00, 0x80, 0x02, 0x02, 0x08, 0x00, 0x00, 0x50, 0x00,
|
0x00, 0x7F, 0x00, 0x00, 0x80, 0x02, 0x02, 0x08, 0x00, 0x00, 0x50, 0x00,
|
||||||
0x7E, 0xFF, 0xFF, 0x01, 0x40, 0x7F, 0x00, 0x00, 0x10, 0x80, 0x86, 0x00,
|
0x7E, 0xFF, 0xFF, 0x01, 0x40, 0x7F, 0x00, 0x00, 0x10, 0x80, 0x86, 0x00,
|
||||||
0x08, 0x09, 0x06, 0x08, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0xFC, 0x20, 0x51,
|
0x08, 0x09, 0x06, 0x08, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0xFC, 0x20, 0x51,
|
||||||
0x0D, 0x20, 0x23, 0x94, 0x91, 0x50, 0x20, 0x92, 0xFF, 0xFE, 0xFF, 0x03,
|
0x0D, 0x20, 0x23, 0x94, 0x91, 0x50, 0x20, 0x92, 0xFF, 0xFE, 0xFF, 0x03,
|
||||||
0x20, 0x70, 0x05, 0x88, 0x01, 0x80, 0x21, 0x06, 0x84, 0x44, 0x80, 0x25,
|
0x20, 0x70, 0x05, 0x88, 0x01, 0x80, 0x21, 0x06, 0x84, 0x44, 0x80, 0x25,
|
||||||
0xFF, 0xFF, 0xFF, 0x03, 0x40, 0xEA, 0x90, 0x00, 0x20, 0xA4, 0x05, 0x00,
|
0xFF, 0xFF, 0xFF, 0x03, 0x40, 0xEA, 0x90, 0x00, 0x20, 0xA4, 0x05, 0x00,
|
||||||
0x00, 0x10, 0x26, 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0x40, 0xD8, 0x08, 0x00,
|
0x00, 0x10, 0x26, 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0x40, 0xD8, 0x08, 0x00,
|
||||||
0x00, 0xA0, 0x81, 0x92, 0x01, 0x01, 0x84, 0x40, 0xFF, 0xFF, 0xFF, 0x0F,
|
0x00, 0xA0, 0x81, 0x92, 0x01, 0x01, 0x84, 0x40, 0xFF, 0xFF, 0xFF, 0x0F,
|
||||||
0x20, 0xC3, 0x42, 0x00, 0x00, 0x0A, 0x24, 0x00, 0x44, 0x48, 0x20, 0x25,
|
0x20, 0xC3, 0x42, 0x00, 0x00, 0x0A, 0x24, 0x00, 0x44, 0x48, 0x20, 0x25,
|
||||||
0xFF, 0xFF, 0xFF, 0x0F, 0x20, 0xD5, 0x05, 0x02, 0x00, 0x46, 0x12, 0x40,
|
0xFF, 0xFF, 0xFF, 0x0F, 0x20, 0xD5, 0x05, 0x02, 0x00, 0x46, 0x12, 0x40,
|
||||||
0x02, 0x22, 0x44, 0x00, 0xFF, 0xFF, 0xFF, 0x1F, 0x90, 0x50, 0x90, 0x00,
|
0x02, 0x22, 0x44, 0x00, 0xFF, 0xFF, 0xFF, 0x1F, 0x90, 0x50, 0x90, 0x00,
|
||||||
0x00, 0x9A, 0x40, 0x02, 0x40, 0x00, 0x10, 0x64, 0xFF, 0xFF, 0xFF, 0x1F,
|
0x00, 0x9A, 0x40, 0x02, 0x40, 0x00, 0x10, 0x64, 0xFF, 0xFF, 0xFF, 0x1F,
|
||||||
0x98, 0x62, 0x7C, 0x10, 0x11, 0xDF, 0x07, 0x14, 0x28, 0x08, 0x01, 0x05,
|
0x98, 0x62, 0x7C, 0x10, 0x11, 0xDF, 0x07, 0x14, 0x28, 0x08, 0x01, 0x05,
|
||||||
0xFF, 0xFF, 0xFF, 0x1F, 0x20, 0x74, 0xF8, 0xE5, 0xEA, 0x87, 0x23, 0x01,
|
0xFF, 0xFF, 0xFF, 0x1F, 0x20, 0x74, 0xF8, 0xE5, 0xEA, 0x87, 0x23, 0x01,
|
||||||
0x81, 0x11, 0x48, 0x20, 0xFF, 0xFF, 0xFF, 0x1F, 0x50, 0x38, 0xF2, 0xFF,
|
0x81, 0x11, 0x48, 0x20, 0xFF, 0xFF, 0xFF, 0x1F, 0x50, 0x38, 0xF2, 0xFF,
|
||||||
0xFF, 0xC7, 0x8F, 0x80, 0x00, 0x84, 0x40, 0x04, 0xFF, 0xFF, 0xFF, 0xBF,
|
0xFF, 0xC7, 0x8F, 0x80, 0x00, 0x84, 0x40, 0x04, 0xFF, 0xFF, 0xFF, 0xBF,
|
||||||
0x68, 0x3D, 0xE9, 0xFF, 0x7F, 0xC1, 0x1F, 0x28, 0x14, 0x10, 0x06, 0x50,
|
0x68, 0x3D, 0xE9, 0xFF, 0x7F, 0xC1, 0x1F, 0x28, 0x14, 0x10, 0x06, 0x50,
|
||||||
0xFF, 0xFF, 0xFF, 0x3F, 0x90, 0x3F, 0x81, 0xFE, 0x5F, 0x89, 0x3F, 0x82,
|
0xFF, 0xFF, 0xFF, 0x3F, 0x90, 0x3F, 0x81, 0xFE, 0x5F, 0x89, 0x3F, 0x82,
|
||||||
0x00, 0x02, 0xA2, 0x01, 0xFF, 0xFF, 0xFF, 0xBF, 0xB0, 0x3F, 0xB1, 0xFF,
|
0x00, 0x02, 0xA2, 0x01, 0xFF, 0xFF, 0xFF, 0xBF, 0xB0, 0x3F, 0xB1, 0xFF,
|
||||||
0xBF, 0xC1, 0xFF, 0x00, 0x82, 0x80, 0x00, 0x24, 0xFF, 0xFB, 0xFF, 0x7F,
|
0xBF, 0xC1, 0xFF, 0x00, 0x82, 0x80, 0x00, 0x24, 0xFF, 0xFB, 0xFF, 0x7F,
|
||||||
0xF8, 0x3F, 0xA9, 0xFC, 0x5F, 0x81, 0xFF, 0x0F, 0x08, 0x00, 0x04, 0x48,
|
0xF8, 0x3F, 0xA9, 0xFC, 0x5F, 0x81, 0xFF, 0x0F, 0x08, 0x00, 0x04, 0x48,
|
||||||
0xFF, 0xF0, 0xFF, 0xBF, 0xFC, 0x3F, 0x41, 0xEB, 0xE7, 0xC0, 0xFF, 0x1F,
|
0xFF, 0xF0, 0xFF, 0xBF, 0xFC, 0x3F, 0x41, 0xEB, 0xE7, 0xC0, 0xFF, 0x1F,
|
||||||
0x40, 0x24, 0x40, 0x01, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0x3F, 0xB3, 0x7D,
|
0x40, 0x24, 0x40, 0x01, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0x3F, 0xB3, 0x7D,
|
||||||
0xAD, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0xA0, 0x90, 0x7F, 0xC0, 0xFF, 0xFF,
|
0xAD, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0xA0, 0x90, 0x7F, 0xC0, 0xFF, 0xFF,
|
||||||
0xFF, 0x3F, 0x43, 0xFA, 0x27, 0xC0, 0xFF, 0xFF, 0x93, 0x51, 0x04, 0x04,
|
0xFF, 0x3F, 0x43, 0xFA, 0x27, 0xC0, 0xFF, 0xFF, 0x93, 0x51, 0x04, 0x04,
|
||||||
0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x60, 0x6D, 0x56, 0xC0, 0xFF, 0xFF,
|
0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x60, 0x6D, 0x56, 0xC0, 0xFF, 0xFF,
|
||||||
0x1F, 0x20, 0x0A, 0x40, 0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x84, 0x6A,
|
0x1F, 0x20, 0x0A, 0x40, 0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x84, 0x6A,
|
||||||
0x6D, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x02, 0x7F, 0x00, 0xFF, 0xFF,
|
0x6D, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x02, 0x7F, 0x00, 0xFF, 0xFF,
|
||||||
0xFF, 0x3F, 0x2C, 0xBA, 0x22, 0xC0, 0xFF, 0xFF, 0xFF, 0x87, 0x04, 0x98,
|
0xFF, 0x3F, 0x2C, 0xBA, 0x22, 0xC0, 0xFF, 0xFF, 0xFF, 0x87, 0x04, 0x98,
|
||||||
0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x48, 0x66, 0xD5, 0xC0, 0xFF, 0xFF,
|
0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x48, 0x66, 0xD5, 0xC0, 0xFF, 0xFF,
|
||||||
0xFF, 0x3F, 0x90, 0x02, 0x7F, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F, 0x80, 0xA6,
|
0xFF, 0x3F, 0x90, 0x02, 0x7F, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F, 0x80, 0xA6,
|
||||||
0x63, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x24, 0x7F, 0xF8, 0xFF, 0xFF,
|
0x63, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x24, 0x7F, 0xF8, 0xFF, 0xFF,
|
||||||
0xFF, 0x7F, 0x90, 0x78, 0x3A, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x27, 0x00,
|
0xFF, 0x7F, 0x90, 0x78, 0x3A, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x27, 0x00,
|
||||||
0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xF9, 0x06, 0xF0, 0xFF, 0xFF,
|
0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xF9, 0x06, 0xF0, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x8F, 0x61, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xA4,
|
0xFF, 0xFF, 0x8F, 0x61, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xA4,
|
||||||
0x0B, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x04, 0x7F, 0xFE, 0xFF, 0xFF,
|
0x0B, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x04, 0x7F, 0xFE, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x00, 0xD0, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x08,
|
0xFF, 0xFF, 0x00, 0xD0, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x08,
|
||||||
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0xF8, 0xFF, 0xFF,
|
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0xF8, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x61, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x88,
|
0xFF, 0xFF, 0xFF, 0x61, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x88,
|
||||||
0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFE, 0xFF, 0xFF, 0xFF,
|
0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x48,
|
0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x48,
|
||||||
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x07, 0xFC, 0xFF, 0xFF,
|
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x07, 0xFC, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x01, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xD0,
|
0xFF, 0xFF, 0xFF, 0x01, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xD0,
|
||||||
0x0F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x69, 0xF8, 0xFF, 0xFF, 0xFF,
|
0x0F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x69, 0xF8, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x03, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05,
|
0xFF, 0xFF, 0x03, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0x3F, 0xFE, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0x3F, 0xFE, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x21, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF,
|
0xFF, 0xFF, 0xFF, 0x21, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF,
|
||||||
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF,
|
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6B,
|
0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6B,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x23, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0x23, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xEF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x27,
|
0xFF, 0xFF, 0xFF, 0xEF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x27,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
|
0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F,
|
0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F,
|
||||||
0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF,
|
0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
|
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xF0, 0xFF, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F,
|
0xFF, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F,
|
||||||
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0xFF,
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
|
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
|
||||||
0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF,
|
0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F,
|
0xFF, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F,
|
||||||
0xF8, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xF8, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0x03, 0x00, 0xF1, 0xFF, 0x7F, 0x80,
|
0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0x03, 0x00, 0xF1, 0xFF, 0x7F, 0x80,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0x03, 0x00,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0x03, 0x00,
|
||||||
0xF0, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x7F, 0x6F, 0xFD, 0xFF, 0xFF, 0x1F,
|
0xF0, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x7F, 0x6F, 0xFD, 0xFF, 0xFF, 0x1F,
|
||||||
0xF8, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x7F, 0x7F,
|
0xF8, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x7F, 0x7F,
|
||||||
0xFD, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0x03, 0x00, 0xC0, 0xFF, 0xFF, 0x90,
|
0xFD, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0x03, 0x00, 0xC0, 0xFF, 0xFF, 0x90,
|
||||||
0xFF, 0xFF, 0x5F, 0xA2, 0xF4, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0x03, 0x00,
|
0xFF, 0xFF, 0x5F, 0xA2, 0xF4, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0x03, 0x00,
|
||||||
0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x0F, 0xAA, 0x42, 0xF1, 0xFF, 0x3F,
|
0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x0F, 0xAA, 0x42, 0xF1, 0xFF, 0x3F,
|
||||||
0xF8, 0xFF, 0xAF, 0x00, 0x80, 0xFF, 0xFF, 0xD9, 0xFF, 0xFF, 0x0F, 0x02,
|
0xF8, 0xFF, 0xAF, 0x00, 0x80, 0xFF, 0xFF, 0xD9, 0xFF, 0xFF, 0x0F, 0x02,
|
||||||
0x64, 0xF1, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x3F, 0xC2, 0xFF, 0xFF, 0xDB,
|
0x64, 0xF1, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x3F, 0xC2, 0xFF, 0xFF, 0xDB,
|
||||||
0xFF, 0xFF, 0xCB, 0xD1, 0xDA, 0xF7, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xCB, 0xD1, 0xDA, 0xF7, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x71, 0x44, 0xFC, 0xF6, 0xFF, 0x3F,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x71, 0x44, 0xFC, 0xF6, 0xFF, 0x3F,
|
||||||
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0xC0,
|
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0xC0,
|
||||||
0xA8, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xA8, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFC, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
|
||||||
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, };
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, };
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
GIMP Palette
|
GIMP Palette
|
||||||
Name: Test
|
Name: Test
|
||||||
Columns: 0
|
Columns: 0
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
Images in this directory were created with GIMP.
|
Images in this directory were created with GIMP.
|
||||||
|
|
||||||
TGAs have names in the following format:
|
TGAs have names in the following format:
|
||||||
|
|
||||||
{width}x{height}_{mode}_{origin}_{compression}.tga
|
{width}x{height}_{mode}_{origin}_{compression}.tga
|
||||||
|
|
||||||
Where:
|
Where:
|
||||||
mode is PIL mode in lower case (L, P, RGB, etc.)
|
mode is PIL mode in lower case (L, P, RGB, etc.)
|
||||||
origin:
|
origin:
|
||||||
"bl" - bottom left
|
"bl" - bottom left
|
||||||
"tl" - top left
|
"tl" - top left
|
||||||
compression is either "raw" or "rle"
|
compression is either "raw" or "rle"
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
#!/bin/bash -eu
|
#!/bin/bash -eu
|
||||||
# Copyright 2020 Google LLC
|
# Copyright 2020 Google LLC
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
# You may obtain a copy of the License at
|
# You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
python3 -m pip install .
|
python3 -m pip install .
|
||||||
|
|
||||||
# Build fuzzers in $OUT.
|
# Build fuzzers in $OUT.
|
||||||
for fuzzer in $(find $SRC -name 'fuzz_*.py'); do
|
for fuzzer in $(find $SRC -name 'fuzz_*.py'); do
|
||||||
compile_python_fuzzer $fuzzer \
|
compile_python_fuzzer $fuzzer \
|
||||||
--add-binary /usr/local/lib/libjpeg.so.62.4.0:. \
|
--add-binary /usr/local/lib/libjpeg.so.62.4.0:. \
|
||||||
--add-binary /usr/local/lib/libfreetype.so.6:. \
|
--add-binary /usr/local/lib/libfreetype.so.6:. \
|
||||||
--add-binary /usr/local/lib/liblcms2.so.2:. \
|
--add-binary /usr/local/lib/liblcms2.so.2:. \
|
||||||
--add-binary /usr/local/lib/libopenjp2.so.7:. \
|
--add-binary /usr/local/lib/libopenjp2.so.7:. \
|
||||||
--add-binary /usr/local/lib/libpng16.so.16:. \
|
--add-binary /usr/local/lib/libpng16.so.16:. \
|
||||||
--add-binary /usr/local/lib/libtiff.so.6:. \
|
--add-binary /usr/local/lib/libtiff.so.6:. \
|
||||||
--add-binary /usr/local/lib/libwebp.so.7:. \
|
--add-binary /usr/local/lib/libwebp.so.7:. \
|
||||||
--add-binary /usr/local/lib/libwebpdemux.so.2:. \
|
--add-binary /usr/local/lib/libwebpdemux.so.2:. \
|
||||||
--add-binary /usr/local/lib/libwebpmux.so.3:. \
|
--add-binary /usr/local/lib/libwebpmux.so.3:. \
|
||||||
--add-binary /usr/local/lib/libxcb.so.1:.
|
--add-binary /usr/local/lib/libxcb.so.1:.
|
||||||
done
|
done
|
||||||
|
|
||||||
find Tests/images Tests/icc -print | zip -q $OUT/fuzz_pillow_seed_corpus.zip -@
|
find Tests/images Tests/icc -print | zip -q $OUT/fuzz_pillow_seed_corpus.zip -@
|
||||||
find Tests/fonts -print | zip -q $OUT/fuzz_font_seed_corpus.zip -@
|
find Tests/fonts -print | zip -q $OUT/fuzz_font_seed_corpus.zip -@
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
#!/bin/bash -eu
|
#!/bin/bash -eu
|
||||||
# Copyright 2020 Google LLC
|
# Copyright 2020 Google LLC
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
# You may obtain a copy of the License at
|
# You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# Generate image dictionaries here for each of the fuzzers and put them in the
|
# Generate image dictionaries here for each of the fuzzers and put them in the
|
||||||
# $OUT directory, named for the fuzzer
|
# $OUT directory, named for the fuzzer
|
||||||
|
|
||||||
git clone --depth 1 https://github.com/google/fuzzing
|
git clone --depth 1 https://github.com/google/fuzzing
|
||||||
cat fuzzing/dictionaries/bmp.dict \
|
cat fuzzing/dictionaries/bmp.dict \
|
||||||
fuzzing/dictionaries/dds.dict \
|
fuzzing/dictionaries/dds.dict \
|
||||||
fuzzing/dictionaries/gif.dict \
|
fuzzing/dictionaries/gif.dict \
|
||||||
fuzzing/dictionaries/icns.dict \
|
fuzzing/dictionaries/icns.dict \
|
||||||
fuzzing/dictionaries/jpeg.dict \
|
fuzzing/dictionaries/jpeg.dict \
|
||||||
fuzzing/dictionaries/jpeg2000.dict \
|
fuzzing/dictionaries/jpeg2000.dict \
|
||||||
fuzzing/dictionaries/pbm.dict \
|
fuzzing/dictionaries/pbm.dict \
|
||||||
fuzzing/dictionaries/png.dict \
|
fuzzing/dictionaries/png.dict \
|
||||||
fuzzing/dictionaries/psd.dict \
|
fuzzing/dictionaries/psd.dict \
|
||||||
fuzzing/dictionaries/tiff.dict \
|
fuzzing/dictionaries/tiff.dict \
|
||||||
fuzzing/dictionaries/webp.dict \
|
fuzzing/dictionaries/webp.dict \
|
||||||
> $OUT/fuzz_pillow.dict
|
> $OUT/fuzz_pillow.dict
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user