Showing
1000 changed files
with
4866 additions
and
0 deletions
Too many changes to show.
To preserve performance only 1000 of 1000+ files are displayed.
code/FAA2_VM/.idea/FAA2.iml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<module type="PYTHON_MODULE" version="4"> | ||
3 | + <component name="NewModuleRootManager"> | ||
4 | + <content url="file://$MODULE_DIR$" /> | ||
5 | + <orderEntry type="jdk" jdkName="Python 3.6 (FAA2)" jdkType="Python SDK" /> | ||
6 | + <orderEntry type="sourceFolder" forTests="false" /> | ||
7 | + </component> | ||
8 | + <component name="TestRunnerService"> | ||
9 | + <option name="PROJECT_TEST_RUNNER" value="Unittests" /> | ||
10 | + </component> | ||
11 | +</module> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
code/FAA2_VM/.idea/encodings.xml
0 → 100644
code/FAA2_VM/.idea/misc.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="JavaScriptSettings"> | ||
4 | + <option name="languageLevel" value="ES6" /> | ||
5 | + </component> | ||
6 | + <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (FAA2)" project-jdk-type="Python SDK" /> | ||
7 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
code/FAA2_VM/.idea/modules.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="ProjectModuleManager"> | ||
4 | + <modules> | ||
5 | + <module fileurl="file://$PROJECT_DIR$/.idea/FAA2.iml" filepath="$PROJECT_DIR$/.idea/FAA2.iml" /> | ||
6 | + </modules> | ||
7 | + </component> | ||
8 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
code/FAA2_VM/.idea/vcs.xml
0 → 100644
code/FAA2_VM/.idea/workspace.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="ChangeListManager"> | ||
4 | + <list default="true" id="ecac36b2-5eb8-4bdd-ae5c-1971962221d8" name="Default Changelist" comment=""> | ||
5 | + <change beforePath="$PROJECT_DIR$/../.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/../.idea/workspace.xml" afterDir="false" /> | ||
6 | + <change beforePath="$PROJECT_DIR$/fast_auto_augment.py" beforeDir="false" afterPath="$PROJECT_DIR$/fast_auto_augment.py" afterDir="false" /> | ||
7 | + <change beforePath="$PROJECT_DIR$/requirements.txt" beforeDir="false" afterPath="$PROJECT_DIR$/requirements.txt" afterDir="false" /> | ||
8 | + <change beforePath="$PROJECT_DIR$/train.py" beforeDir="false" afterPath="$PROJECT_DIR$/train.py" afterDir="false" /> | ||
9 | + <change beforePath="$PROJECT_DIR$/transforms.py" beforeDir="false" afterPath="$PROJECT_DIR$/transforms.py" afterDir="false" /> | ||
10 | + <change beforePath="$PROJECT_DIR$/utils.py" beforeDir="false" afterPath="$PROJECT_DIR$/utils.py" afterDir="false" /> | ||
11 | + <change beforePath="$PROJECT_DIR$/../getframe.m" beforeDir="false" afterPath="$PROJECT_DIR$/../getframe.m" afterDir="false" /> | ||
12 | + </list> | ||
13 | + <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> | ||
14 | + <option name="SHOW_DIALOG" value="false" /> | ||
15 | + <option name="HIGHLIGHT_CONFLICTS" value="true" /> | ||
16 | + <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> | ||
17 | + <option name="LAST_RESOLUTION" value="IGNORE" /> | ||
18 | + </component> | ||
19 | + <component name="FileEditorManager"> | ||
20 | + <leaf> | ||
21 | + <file pinned="false" current-in-tab="true"> | ||
22 | + <entry file="file://$PROJECT_DIR$/requirements.txt"> | ||
23 | + <provider selected="true" editor-type-id="text-editor"> | ||
24 | + <state relative-caret-position="176"> | ||
25 | + <caret line="8" lean-forward="true" selection-start-line="8" selection-end-line="8" /> | ||
26 | + </state> | ||
27 | + </provider> | ||
28 | + </entry> | ||
29 | + </file> | ||
30 | + </leaf> | ||
31 | + </component> | ||
32 | + <component name="Git.Settings"> | ||
33 | + <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../.." /> | ||
34 | + </component> | ||
35 | + <component name="IdeDocumentHistory"> | ||
36 | + <option name="CHANGED_PATHS"> | ||
37 | + <list> | ||
38 | + <option value="$PROJECT_DIR$/requirements.txt" /> | ||
39 | + </list> | ||
40 | + </option> | ||
41 | + </component> | ||
42 | + <component name="ProjectFrameBounds" extendedState="6"> | ||
43 | + <option name="x" value="-9" /> | ||
44 | + <option name="width" value="1825" /> | ||
45 | + <option name="height" value="1040" /> | ||
46 | + </component> | ||
47 | + <component name="ProjectLevelVcsManager" settingsEditedManually="true" /> | ||
48 | + <component name="ProjectView"> | ||
49 | + <navigator proportions="" version="1"> | ||
50 | + <foldersAlwaysOnTop value="true" /> | ||
51 | + </navigator> | ||
52 | + <panes> | ||
53 | + <pane id="ProjectPane"> | ||
54 | + <subPane> | ||
55 | + <expand> | ||
56 | + <path> | ||
57 | + <item name="FAA2" type="b2602c69:ProjectViewProjectNode" /> | ||
58 | + <item name="FAA2" type="462c0819:PsiDirectoryNode" /> | ||
59 | + </path> | ||
60 | + </expand> | ||
61 | + <select /> | ||
62 | + </subPane> | ||
63 | + </pane> | ||
64 | + <pane id="Scope" /> | ||
65 | + </panes> | ||
66 | + </component> | ||
67 | + <component name="PropertiesComponent"> | ||
68 | + <property name="WebServerToolWindowFactoryState" value="false" /> | ||
69 | + <property name="last_opened_file_path" value="$USER_HOME$/Anaconda3/Scripts/conda.exe" /> | ||
70 | + <property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" /> | ||
71 | + <property name="nodejs_npm_path_reset_for_default_project" value="true" /> | ||
72 | + <property name="settings.editor.selected.configurable" value="web.server" /> | ||
73 | + </component> | ||
74 | + <component name="RunDashboard"> | ||
75 | + <option name="ruleStates"> | ||
76 | + <list> | ||
77 | + <RuleState> | ||
78 | + <option name="name" value="ConfigurationTypeDashboardGroupingRule" /> | ||
79 | + </RuleState> | ||
80 | + <RuleState> | ||
81 | + <option name="name" value="StatusDashboardGroupingRule" /> | ||
82 | + </RuleState> | ||
83 | + </list> | ||
84 | + </option> | ||
85 | + </component> | ||
86 | + <component name="SvnConfiguration"> | ||
87 | + <configuration /> | ||
88 | + </component> | ||
89 | + <component name="TaskManager"> | ||
90 | + <task active="true" id="Default" summary="Default task"> | ||
91 | + <changelist id="ecac36b2-5eb8-4bdd-ae5c-1971962221d8" name="Default Changelist" comment="" /> | ||
92 | + <created>1585929097107</created> | ||
93 | + <option name="number" value="Default" /> | ||
94 | + <option name="presentableId" value="Default" /> | ||
95 | + <updated>1585929097107</updated> | ||
96 | + <workItem from="1585929098868" duration="1531000" /> | ||
97 | + </task> | ||
98 | + <servers /> | ||
99 | + </component> | ||
100 | + <component name="TimeTrackingManager"> | ||
101 | + <option name="totallyTimeSpent" value="1531000" /> | ||
102 | + </component> | ||
103 | + <component name="ToolWindowManager"> | ||
104 | + <frame x="-7" y="-7" width="1550" height="838" extended-state="6" /> | ||
105 | + <layout> | ||
106 | + <window_info id="Favorites" side_tool="true" /> | ||
107 | + <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.23489933" /> | ||
108 | + <window_info id="Structure" order="1" side_tool="true" weight="0.25" /> | ||
109 | + <window_info anchor="bottom" id="Docker" show_stripe_button="false" /> | ||
110 | + <window_info anchor="bottom" id="Database Changes" /> | ||
111 | + <window_info anchor="bottom" id="Version Control" /> | ||
112 | + <window_info anchor="bottom" id="Python Console" /> | ||
113 | + <window_info anchor="bottom" id="Terminal" weight="0.6028369" /> | ||
114 | + <window_info anchor="bottom" id="Event Log" side_tool="true" /> | ||
115 | + <window_info anchor="bottom" id="Message" order="0" /> | ||
116 | + <window_info anchor="bottom" id="Find" order="1" /> | ||
117 | + <window_info anchor="bottom" id="Run" order="2" /> | ||
118 | + <window_info anchor="bottom" id="Debug" order="3" weight="0.4" /> | ||
119 | + <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" /> | ||
120 | + <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" /> | ||
121 | + <window_info anchor="bottom" id="TODO" order="6" /> | ||
122 | + <window_info anchor="right" id="SciView" /> | ||
123 | + <window_info anchor="right" id="Database" /> | ||
124 | + <window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" /> | ||
125 | + <window_info anchor="right" id="Ant Build" order="1" weight="0.25" /> | ||
126 | + <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" /> | ||
127 | + </layout> | ||
128 | + </component> | ||
129 | + <component name="TypeScriptGeneratedFilesManager"> | ||
130 | + <option name="version" value="1" /> | ||
131 | + </component> | ||
132 | + <component name="editorHistoryManager"> | ||
133 | + <entry file="file://$PROJECT_DIR$/requirements.txt"> | ||
134 | + <provider selected="true" editor-type-id="text-editor"> | ||
135 | + <state relative-caret-position="176"> | ||
136 | + <caret line="8" lean-forward="true" selection-start-line="8" selection-end-line="8" /> | ||
137 | + </state> | ||
138 | + </provider> | ||
139 | + </entry> | ||
140 | + </component> | ||
141 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
code/FAA2_VM/.vscode/settings.json
0 → 100644
1 | +Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later) | ||
2 | +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) | ||
3 | +Copyright 2004 Manfred Stienstra (the original version) | ||
4 | + | ||
5 | +All rights reserved. | ||
6 | + | ||
7 | +Redistribution and use in source and binary forms, with or without | ||
8 | +modification, are permitted provided that the following conditions are met: | ||
9 | + | ||
10 | +* Redistributions of source code must retain the above copyright | ||
11 | + notice, this list of conditions and the following disclaimer. | ||
12 | +* Redistributions in binary form must reproduce the above copyright | ||
13 | + notice, this list of conditions and the following disclaimer in the | ||
14 | + documentation and/or other materials provided with the distribution. | ||
15 | +* Neither the name of the Python Markdown Project nor the | ||
16 | + names of its contributors may be used to endorse or promote products | ||
17 | + derived from this software without specific prior written permission. | ||
18 | + | ||
19 | +THIS SOFTWARE IS PROVIDED BY THE PYTHON MARKDOWN PROJECT ''AS IS'' AND ANY | ||
20 | +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
21 | +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
22 | +DISCLAIMED. IN NO EVENT SHALL ANY CONTRIBUTORS TO THE PYTHON MARKDOWN PROJECT | ||
23 | +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
24 | +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
25 | +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
26 | +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
27 | +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
28 | +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
29 | +POSSIBILITY OF SUCH DAMAGE. |
1 | +Metadata-Version: 2.1 | ||
2 | +Name: Markdown | ||
3 | +Version: 3.2.1 | ||
4 | +Summary: Python implementation of Markdown. | ||
5 | +Home-page: https://Python-Markdown.github.io/ | ||
6 | +Author: Manfred Stienstra, Yuri takhteyev and Waylan limberg | ||
7 | +Author-email: waylan.limberg@icloud.com | ||
8 | +Maintainer: Waylan Limberg | ||
9 | +Maintainer-email: waylan.limberg@icloud.com | ||
10 | +License: BSD License | ||
11 | +Download-URL: http://pypi.python.org/packages/source/M/Markdown/Markdown-3.2.1-py2.py3-none-any.whl | ||
12 | +Platform: UNKNOWN | ||
13 | +Classifier: Development Status :: 5 - Production/Stable | ||
14 | +Classifier: License :: OSI Approved :: BSD License | ||
15 | +Classifier: Operating System :: OS Independent | ||
16 | +Classifier: Programming Language :: Python | ||
17 | +Classifier: Programming Language :: Python :: 3 | ||
18 | +Classifier: Programming Language :: Python :: 3.5 | ||
19 | +Classifier: Programming Language :: Python :: 3.6 | ||
20 | +Classifier: Programming Language :: Python :: 3.7 | ||
21 | +Classifier: Programming Language :: Python :: 3.8 | ||
22 | +Classifier: Programming Language :: Python :: 3 :: Only | ||
23 | +Classifier: Programming Language :: Python :: Implementation :: CPython | ||
24 | +Classifier: Programming Language :: Python :: Implementation :: PyPy | ||
25 | +Classifier: Topic :: Communications :: Email :: Filters | ||
26 | +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries | ||
27 | +Classifier: Topic :: Internet :: WWW/HTTP :: Site Management | ||
28 | +Classifier: Topic :: Software Development :: Documentation | ||
29 | +Classifier: Topic :: Software Development :: Libraries :: Python Modules | ||
30 | +Classifier: Topic :: Text Processing :: Filters | ||
31 | +Classifier: Topic :: Text Processing :: Markup :: HTML | ||
32 | +Requires-Python: >=3.5 | ||
33 | +Requires-Dist: setuptools (>=36) | ||
34 | +Provides-Extra: testing | ||
35 | +Requires-Dist: coverage ; extra == 'testing' | ||
36 | +Requires-Dist: pyyaml ; extra == 'testing' | ||
37 | + | ||
38 | + | ||
39 | +This is a Python implementation of John Gruber's Markdown_. | ||
40 | +It is almost completely compliant with the reference implementation, | ||
41 | +though there are a few known issues. See Features_ for information | ||
42 | +on what exactly is supported and what is not. Additional features are | ||
43 | +supported by the `Available Extensions`_. | ||
44 | + | ||
45 | +.. _Markdown: https://daringfireball.net/projects/markdown/ | ||
46 | +.. _Features: https://Python-Markdown.github.io#features | ||
47 | +.. _`Available Extensions`: https://Python-Markdown.github.io/extensions/ | ||
48 | + | ||
49 | +Support | ||
50 | +======= | ||
51 | + | ||
52 | +You may report bugs, ask for help, and discuss various other issues on | ||
53 | +the `bug tracker`_. | ||
54 | + | ||
55 | +.. _`bug tracker`: https://github.com/Python-Markdown/markdown/issues | ||
56 | + | ||
57 | + |
1 | +../../Scripts/markdown_py.exe,sha256=xcQRheiF218v5xGonxUh_TeNVUrb4yPs3E0DTOZZuAA,106376 | ||
2 | +Markdown-3.2.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 | ||
3 | +Markdown-3.2.1.dist-info/LICENSE.md,sha256=bxGTy2NHGOZcOlN9biXr1hSCDsDvaTz8EiSBEmONZNo,1645 | ||
4 | +Markdown-3.2.1.dist-info/METADATA,sha256=PK6UzXb9yL09qZJH7SCqZd6-mj8keovCmxQLt89NlEQ,2383 | ||
5 | +Markdown-3.2.1.dist-info/RECORD,, | ||
6 | +Markdown-3.2.1.dist-info/WHEEL,sha256=h_aVn5OB2IERUjMbi2pucmR_zzWJtk303YXvhh60NJ8,110 | ||
7 | +Markdown-3.2.1.dist-info/entry_points.txt,sha256=j4jiKg-iwZGImvi8OzotZePWoFbJJ4GrfzDqH03u3SQ,1103 | ||
8 | +Markdown-3.2.1.dist-info/top_level.txt,sha256=IAxs8x618RXoH1uCqeLLxXsDefJvE_mIibr_M4sOlyk,9 | ||
9 | +markdown/__init__.py,sha256=002-LuHviYzROW2rg_gBGai81nMouUNO9UFj5nSsTSk,2065 | ||
10 | +markdown/__main__.py,sha256=MpVK3zlwQ-4AzDzZmIScPB90PpunMGVgS5KBmJuHYTw,5802 | ||
11 | +markdown/__meta__.py,sha256=xhmwLb0Eb6kfiapdM21pCb80lyVEl8hxv8Re_X6wsI0,1837 | ||
12 | +markdown/__pycache__/__init__.cpython-37.pyc,, | ||
13 | +markdown/__pycache__/__main__.cpython-37.pyc,, | ||
14 | +markdown/__pycache__/__meta__.cpython-37.pyc,, | ||
15 | +markdown/__pycache__/blockparser.cpython-37.pyc,, | ||
16 | +markdown/__pycache__/blockprocessors.cpython-37.pyc,, | ||
17 | +markdown/__pycache__/core.cpython-37.pyc,, | ||
18 | +markdown/__pycache__/inlinepatterns.cpython-37.pyc,, | ||
19 | +markdown/__pycache__/pep562.cpython-37.pyc,, | ||
20 | +markdown/__pycache__/postprocessors.cpython-37.pyc,, | ||
21 | +markdown/__pycache__/preprocessors.cpython-37.pyc,, | ||
22 | +markdown/__pycache__/serializers.cpython-37.pyc,, | ||
23 | +markdown/__pycache__/test_tools.cpython-37.pyc,, | ||
24 | +markdown/__pycache__/treeprocessors.cpython-37.pyc,, | ||
25 | +markdown/__pycache__/util.cpython-37.pyc,, | ||
26 | +markdown/blockparser.py,sha256=JpBhOokOoBUGCXolftOc5m1hPcR2y9s9hVd9WSuhHzo,4285 | ||
27 | +markdown/blockprocessors.py,sha256=l4gmkAN9b2L340EX0gm24EyWS7UzBviPqX6wYrcgEco,23736 | ||
28 | +markdown/core.py,sha256=JLR5hIMwWSeIHRQhTzAymB3QUD3gHCdITFvmuuCpIcA,15360 | ||
29 | +markdown/extensions/__init__.py,sha256=6kUSgoqDT4gGUVsqf7F9oQD_jA0RJCbX5EK3JVo8iQE,3517 | ||
30 | +markdown/extensions/__pycache__/__init__.cpython-37.pyc,, | ||
31 | +markdown/extensions/__pycache__/abbr.cpython-37.pyc,, | ||
32 | +markdown/extensions/__pycache__/admonition.cpython-37.pyc,, | ||
33 | +markdown/extensions/__pycache__/attr_list.cpython-37.pyc,, | ||
34 | +markdown/extensions/__pycache__/codehilite.cpython-37.pyc,, | ||
35 | +markdown/extensions/__pycache__/def_list.cpython-37.pyc,, | ||
36 | +markdown/extensions/__pycache__/extra.cpython-37.pyc,, | ||
37 | +markdown/extensions/__pycache__/fenced_code.cpython-37.pyc,, | ||
38 | +markdown/extensions/__pycache__/footnotes.cpython-37.pyc,, | ||
39 | +markdown/extensions/__pycache__/legacy_attrs.cpython-37.pyc,, | ||
40 | +markdown/extensions/__pycache__/legacy_em.cpython-37.pyc,, | ||
41 | +markdown/extensions/__pycache__/md_in_html.cpython-37.pyc,, | ||
42 | +markdown/extensions/__pycache__/meta.cpython-37.pyc,, | ||
43 | +markdown/extensions/__pycache__/nl2br.cpython-37.pyc,, | ||
44 | +markdown/extensions/__pycache__/sane_lists.cpython-37.pyc,, | ||
45 | +markdown/extensions/__pycache__/smarty.cpython-37.pyc,, | ||
46 | +markdown/extensions/__pycache__/tables.cpython-37.pyc,, | ||
47 | +markdown/extensions/__pycache__/toc.cpython-37.pyc,, | ||
48 | +markdown/extensions/__pycache__/wikilinks.cpython-37.pyc,, | ||
49 | +markdown/extensions/abbr.py,sha256=pqp2HnOR2giT-iYKyqtsp2_eUOWBR0j_hUfjvUV5c88,2916 | ||
50 | +markdown/extensions/admonition.py,sha256=HWHHjuYZPAPOg5X8hbpDuSbw8gB6k0odw8GuTT1v_N4,3124 | ||
51 | +markdown/extensions/attr_list.py,sha256=m9a1H-S33rV2twtlFYuoxSiCAf22ndU5tziSzNF2dNg,6003 | ||
52 | +markdown/extensions/codehilite.py,sha256=rVZVOIjp2KEIZsnz90mX6E2_xnwVPQZpVVQVJMuMVU0,9834 | ||
53 | +markdown/extensions/def_list.py,sha256=iqRXAEl2XnyF415afCxihAgOmEUOK1hIuBPIK1k7Tzo,3521 | ||
54 | +markdown/extensions/extra.py,sha256=udRN8OvSWcq3UwkPygvsFl1RlCVtCJ-ARVg2IwVH6VY,1831 | ||
55 | +markdown/extensions/fenced_code.py,sha256=dww9rDu2kQtkoTpjn9BBgeGCTNdE1bMPJ2wgR6695iM,3897 | ||
56 | +markdown/extensions/footnotes.py,sha256=a9sb8RoKqFU8p8ZhpTObrn_Uek0hbyPFVGYpRaEDXaw,15339 | ||
57 | +markdown/extensions/legacy_attrs.py,sha256=2EaVQkxQoNnP8_lMPvGRBdNda8L4weUQroiyEuVdS-w,2547 | ||
58 | +markdown/extensions/legacy_em.py,sha256=9ZMGCTrFh01eiOpnFjS0jVkqgYXiTzCGn-eNvYcvObg,1579 | ||
59 | +markdown/extensions/md_in_html.py,sha256=ohSiGcgR5yBqusuTs0opbTO_5fq442fqPK-klFd_qaM,4040 | ||
60 | +markdown/extensions/meta.py,sha256=EUfkzM7l7UpH__Or9K3pl8ldVddwndlCZWA3d712RAE,2331 | ||
61 | +markdown/extensions/nl2br.py,sha256=wAqTNOuf2L1NzlEvEqoID70n9y-aiYaGLkuyQk3CD0w,783 | ||
62 | +markdown/extensions/sane_lists.py,sha256=ZQmCf-247KBexVG0fc62nDvokGkV6W1uavYbieNKSG4,1505 | ||
63 | +markdown/extensions/smarty.py,sha256=0padzkVCNACainKw-Xj1S5UfT0125VCTfNejmrCZItA,10238 | ||
64 | +markdown/extensions/tables.py,sha256=bicFx_wqhnEx6Y_8MJqA56rh71pt5fOe94oiWbvcobY,7685 | ||
65 | +markdown/extensions/toc.py,sha256=E-d3R4etcM_R2sQyTpKkejRv2NHrHPCvaXK9hUqfK58,13224 | ||
66 | +markdown/extensions/wikilinks.py,sha256=GkgT9BY7b1-qW--dIwFAhC9V20RoeF13b7CFdw_V21Q,2812 | ||
67 | +markdown/inlinepatterns.py,sha256=EnYq9aU_Hi1gu5e8dcbUxUu0mRz-pHFV79uGQCYbD5I,29378 | ||
68 | +markdown/pep562.py,sha256=5UkqT7sb-cQufgbOl_jF-RYUVVHS7VThzlMzR9vrd3I,8917 | ||
69 | +markdown/postprocessors.py,sha256=25g6qqpJ4kuiq4RBrGz8RA6GMb7ArUi1AN2VDVnR35U,3738 | ||
70 | +markdown/preprocessors.py,sha256=dsmMVPP2afKAZ0s59_mFidM_mCiNfgdBJ9aVDWu_viE,15323 | ||
71 | +markdown/serializers.py,sha256=_wQl-iJrPSUEQ4Q1owWYqN9qceVh6TOlAOH_i44BKAQ,6540 | ||
72 | +markdown/test_tools.py,sha256=zFHFzmtzjfMRroyyli3LY4SP8yLfLf4S7SsU3z7Z1SQ,6823 | ||
73 | +markdown/treeprocessors.py,sha256=NBaYc9TEGP7TBaN6YRROIqE5Lj-AMoAqp0jN-coGW3Q,15401 | ||
74 | +markdown/util.py,sha256=0ySktJgYplEV7g6TOOs8fatAS4Fi-6F7iv4D9Vw3g0c,15201 |
1 | +[console_scripts] | ||
2 | +markdown_py = markdown.__main__:run | ||
3 | + | ||
4 | +[markdown.extensions] | ||
5 | +abbr = markdown.extensions.abbr:AbbrExtension | ||
6 | +admonition = markdown.extensions.admonition:AdmonitionExtension | ||
7 | +attr_list = markdown.extensions.attr_list:AttrListExtension | ||
8 | +codehilite = markdown.extensions.codehilite:CodeHiliteExtension | ||
9 | +def_list = markdown.extensions.def_list:DefListExtension | ||
10 | +extra = markdown.extensions.extra:ExtraExtension | ||
11 | +fenced_code = markdown.extensions.fenced_code:FencedCodeExtension | ||
12 | +footnotes = markdown.extensions.footnotes:FootnoteExtension | ||
13 | +legacy_attrs = markdown.extensions.legacy_attrs:LegacyAttrExtension | ||
14 | +legacy_em = markdown.extensions.legacy_em:LegacyEmExtension | ||
15 | +md_in_html = markdown.extensions.md_in_html:MarkdownInHtmlExtension | ||
16 | +meta = markdown.extensions.meta:MetaExtension | ||
17 | +nl2br = markdown.extensions.nl2br:Nl2BrExtension | ||
18 | +sane_lists = markdown.extensions.sane_lists:SaneListExtension | ||
19 | +smarty = markdown.extensions.smarty:SmartyExtension | ||
20 | +tables = markdown.extensions.tables:TableExtension | ||
21 | +toc = markdown.extensions.toc:TocExtension | ||
22 | +wikilinks = markdown.extensions.wikilinks:WikiLinkExtension | ||
23 | + |
1 | +markdown |
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# bitmap distribution font (bdf) file parser | ||
6 | +# | ||
7 | +# history: | ||
8 | +# 1996-05-16 fl created (as bdf2pil) | ||
9 | +# 1997-08-25 fl converted to FontFile driver | ||
10 | +# 2001-05-25 fl removed bogus __init__ call | ||
11 | +# 2002-11-20 fl robustification (from Kevin Cazabon, Dmitry Vasiliev) | ||
12 | +# 2003-04-22 fl more robustification (from Graham Dumpleton) | ||
13 | +# | ||
14 | +# Copyright (c) 1997-2003 by Secret Labs AB. | ||
15 | +# Copyright (c) 1997-2003 by Fredrik Lundh. | ||
16 | +# | ||
17 | +# See the README file for information on usage and redistribution. | ||
18 | +# | ||
19 | + | ||
20 | +from __future__ import print_function | ||
21 | + | ||
22 | +from . import FontFile, Image | ||
23 | + | ||
24 | +# -------------------------------------------------------------------- | ||
25 | +# parse X Bitmap Distribution Format (BDF) | ||
26 | +# -------------------------------------------------------------------- | ||
27 | + | ||
28 | +bdf_slant = { | ||
29 | + "R": "Roman", | ||
30 | + "I": "Italic", | ||
31 | + "O": "Oblique", | ||
32 | + "RI": "Reverse Italic", | ||
33 | + "RO": "Reverse Oblique", | ||
34 | + "OT": "Other", | ||
35 | +} | ||
36 | + | ||
37 | +bdf_spacing = {"P": "Proportional", "M": "Monospaced", "C": "Cell"} | ||
38 | + | ||
39 | + | ||
40 | +def bdf_char(f): | ||
41 | + # skip to STARTCHAR | ||
42 | + while True: | ||
43 | + s = f.readline() | ||
44 | + if not s: | ||
45 | + return None | ||
46 | + if s[:9] == b"STARTCHAR": | ||
47 | + break | ||
48 | + id = s[9:].strip().decode("ascii") | ||
49 | + | ||
50 | + # load symbol properties | ||
51 | + props = {} | ||
52 | + while True: | ||
53 | + s = f.readline() | ||
54 | + if not s or s[:6] == b"BITMAP": | ||
55 | + break | ||
56 | + i = s.find(b" ") | ||
57 | + props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii") | ||
58 | + | ||
59 | + # load bitmap | ||
60 | + bitmap = [] | ||
61 | + while True: | ||
62 | + s = f.readline() | ||
63 | + if not s or s[:7] == b"ENDCHAR": | ||
64 | + break | ||
65 | + bitmap.append(s[:-1]) | ||
66 | + bitmap = b"".join(bitmap) | ||
67 | + | ||
68 | + [x, y, l, d] = [int(p) for p in props["BBX"].split()] | ||
69 | + [dx, dy] = [int(p) for p in props["DWIDTH"].split()] | ||
70 | + | ||
71 | + bbox = (dx, dy), (l, -d - y, x + l, -d), (0, 0, x, y) | ||
72 | + | ||
73 | + try: | ||
74 | + im = Image.frombytes("1", (x, y), bitmap, "hex", "1") | ||
75 | + except ValueError: | ||
76 | + # deal with zero-width characters | ||
77 | + im = Image.new("1", (x, y)) | ||
78 | + | ||
79 | + return id, int(props["ENCODING"]), bbox, im | ||
80 | + | ||
81 | + | ||
82 | +## | ||
83 | +# Font file plugin for the X11 BDF format. | ||
84 | + | ||
85 | + | ||
86 | +class BdfFontFile(FontFile.FontFile): | ||
87 | + def __init__(self, fp): | ||
88 | + | ||
89 | + FontFile.FontFile.__init__(self) | ||
90 | + | ||
91 | + s = fp.readline() | ||
92 | + if s[:13] != b"STARTFONT 2.1": | ||
93 | + raise SyntaxError("not a valid BDF file") | ||
94 | + | ||
95 | + props = {} | ||
96 | + comments = [] | ||
97 | + | ||
98 | + while True: | ||
99 | + s = fp.readline() | ||
100 | + if not s or s[:13] == b"ENDPROPERTIES": | ||
101 | + break | ||
102 | + i = s.find(b" ") | ||
103 | + props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii") | ||
104 | + if s[:i] in [b"COMMENT", b"COPYRIGHT"]: | ||
105 | + if s.find(b"LogicalFontDescription") < 0: | ||
106 | + comments.append(s[i + 1 : -1].decode("ascii")) | ||
107 | + | ||
108 | + while True: | ||
109 | + c = bdf_char(fp) | ||
110 | + if not c: | ||
111 | + break | ||
112 | + id, ch, (xy, dst, src), im = c | ||
113 | + if 0 <= ch < len(self.glyph): | ||
114 | + self.glyph[ch] = xy, dst, src, im |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# BUFR stub adapter | ||
6 | +# | ||
7 | +# Copyright (c) 1996-2003 by Fredrik Lundh | ||
8 | +# | ||
9 | +# See the README file for information on usage and redistribution. | ||
10 | +# | ||
11 | + | ||
12 | +from . import Image, ImageFile | ||
13 | + | ||
14 | +_handler = None | ||
15 | + | ||
16 | + | ||
17 | +def register_handler(handler): | ||
18 | + """ | ||
19 | + Install application-specific BUFR image handler. | ||
20 | + | ||
21 | + :param handler: Handler object. | ||
22 | + """ | ||
23 | + global _handler | ||
24 | + _handler = handler | ||
25 | + | ||
26 | + | ||
27 | +# -------------------------------------------------------------------- | ||
28 | +# Image adapter | ||
29 | + | ||
30 | + | ||
31 | +def _accept(prefix): | ||
32 | + return prefix[:4] == b"BUFR" or prefix[:4] == b"ZCZC" | ||
33 | + | ||
34 | + | ||
35 | +class BufrStubImageFile(ImageFile.StubImageFile): | ||
36 | + | ||
37 | + format = "BUFR" | ||
38 | + format_description = "BUFR" | ||
39 | + | ||
40 | + def _open(self): | ||
41 | + | ||
42 | + offset = self.fp.tell() | ||
43 | + | ||
44 | + if not _accept(self.fp.read(4)): | ||
45 | + raise SyntaxError("Not a BUFR file") | ||
46 | + | ||
47 | + self.fp.seek(offset) | ||
48 | + | ||
49 | + # make something up | ||
50 | + self.mode = "F" | ||
51 | + self._size = 1, 1 | ||
52 | + | ||
53 | + loader = self._load() | ||
54 | + if loader: | ||
55 | + loader.open(self) | ||
56 | + | ||
57 | + def _load(self): | ||
58 | + return _handler | ||
59 | + | ||
60 | + | ||
61 | +def _save(im, fp, filename): | ||
62 | + if _handler is None or not hasattr("_handler", "save"): | ||
63 | + raise IOError("BUFR save handler not installed") | ||
64 | + _handler.save(im, fp, filename) | ||
65 | + | ||
66 | + | ||
67 | +# -------------------------------------------------------------------- | ||
68 | +# Registry | ||
69 | + | ||
70 | +Image.register_open(BufrStubImageFile.format, BufrStubImageFile, _accept) | ||
71 | +Image.register_save(BufrStubImageFile.format, _save) | ||
72 | + | ||
73 | +Image.register_extension(BufrStubImageFile.format, ".bufr") |
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# a class to read from a container file | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 1995-06-18 fl Created | ||
9 | +# 1995-09-07 fl Added readline(), readlines() | ||
10 | +# | ||
11 | +# Copyright (c) 1997-2001 by Secret Labs AB | ||
12 | +# Copyright (c) 1995 by Fredrik Lundh | ||
13 | +# | ||
14 | +# See the README file for information on usage and redistribution. | ||
15 | +# | ||
16 | + | ||
17 | +## | ||
18 | +# A file object that provides read access to a part of an existing | ||
19 | +# file (for example a TAR file). | ||
20 | + | ||
21 | +import io | ||
22 | + | ||
23 | + | ||
24 | +class ContainerIO(object): | ||
25 | + def __init__(self, file, offset, length): | ||
26 | + """ | ||
27 | + Create file object. | ||
28 | + | ||
29 | + :param file: Existing file. | ||
30 | + :param offset: Start of region, in bytes. | ||
31 | + :param length: Size of region, in bytes. | ||
32 | + """ | ||
33 | + self.fh = file | ||
34 | + self.pos = 0 | ||
35 | + self.offset = offset | ||
36 | + self.length = length | ||
37 | + self.fh.seek(offset) | ||
38 | + | ||
39 | + ## | ||
40 | + # Always false. | ||
41 | + | ||
42 | + def isatty(self): | ||
43 | + return False | ||
44 | + | ||
45 | + def seek(self, offset, mode=io.SEEK_SET): | ||
46 | + """ | ||
47 | + Move file pointer. | ||
48 | + | ||
49 | + :param offset: Offset in bytes. | ||
50 | + :param mode: Starting position. Use 0 for beginning of region, 1 | ||
51 | + for current offset, and 2 for end of region. You cannot move | ||
52 | + the pointer outside the defined region. | ||
53 | + """ | ||
54 | + if mode == 1: | ||
55 | + self.pos = self.pos + offset | ||
56 | + elif mode == 2: | ||
57 | + self.pos = self.length + offset | ||
58 | + else: | ||
59 | + self.pos = offset | ||
60 | + # clamp | ||
61 | + self.pos = max(0, min(self.pos, self.length)) | ||
62 | + self.fh.seek(self.offset + self.pos) | ||
63 | + | ||
64 | + def tell(self): | ||
65 | + """ | ||
66 | + Get current file pointer. | ||
67 | + | ||
68 | + :returns: Offset from start of region, in bytes. | ||
69 | + """ | ||
70 | + return self.pos | ||
71 | + | ||
72 | + def read(self, n=0): | ||
73 | + """ | ||
74 | + Read data. | ||
75 | + | ||
76 | + :param n: Number of bytes to read. If omitted or zero, | ||
77 | + read until end of region. | ||
78 | + :returns: An 8-bit string. | ||
79 | + """ | ||
80 | + if n: | ||
81 | + n = min(n, self.length - self.pos) | ||
82 | + else: | ||
83 | + n = self.length - self.pos | ||
84 | + if not n: # EOF | ||
85 | + return "" | ||
86 | + self.pos = self.pos + n | ||
87 | + return self.fh.read(n) | ||
88 | + | ||
89 | + def readline(self): | ||
90 | + """ | ||
91 | + Read a line of text. | ||
92 | + | ||
93 | + :returns: An 8-bit string. | ||
94 | + """ | ||
95 | + s = "" | ||
96 | + while True: | ||
97 | + c = self.read(1) | ||
98 | + if not c: | ||
99 | + break | ||
100 | + s = s + c | ||
101 | + if c == "\n": | ||
102 | + break | ||
103 | + return s | ||
104 | + | ||
105 | + def readlines(self): | ||
106 | + """ | ||
107 | + Read multiple lines of text. | ||
108 | + | ||
109 | + :returns: A list of 8-bit strings. | ||
110 | + """ | ||
111 | + lines = [] | ||
112 | + while True: | ||
113 | + s = self.readline() | ||
114 | + if not s: | ||
115 | + break | ||
116 | + lines.append(s) | ||
117 | + return lines |
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# Windows Cursor support for PIL | ||
6 | +# | ||
7 | +# notes: | ||
8 | +# uses BmpImagePlugin.py to read the bitmap data. | ||
9 | +# | ||
10 | +# history: | ||
11 | +# 96-05-27 fl Created | ||
12 | +# | ||
13 | +# Copyright (c) Secret Labs AB 1997. | ||
14 | +# Copyright (c) Fredrik Lundh 1996. | ||
15 | +# | ||
16 | +# See the README file for information on usage and redistribution. | ||
17 | +# | ||
18 | + | ||
19 | +from __future__ import print_function | ||
20 | + | ||
21 | +from . import BmpImagePlugin, Image | ||
22 | +from ._binary import i8, i16le as i16, i32le as i32 | ||
23 | + | ||
24 | +# __version__ is deprecated and will be removed in a future version. Use | ||
25 | +# PIL.__version__ instead. | ||
26 | +__version__ = "0.1" | ||
27 | + | ||
28 | +# | ||
29 | +# -------------------------------------------------------------------- | ||
30 | + | ||
31 | + | ||
32 | +def _accept(prefix): | ||
33 | + return prefix[:4] == b"\0\0\2\0" | ||
34 | + | ||
35 | + | ||
36 | +## | ||
37 | +# Image plugin for Windows Cursor files. | ||
38 | + | ||
39 | + | ||
40 | +class CurImageFile(BmpImagePlugin.BmpImageFile): | ||
41 | + | ||
42 | + format = "CUR" | ||
43 | + format_description = "Windows Cursor" | ||
44 | + | ||
45 | + def _open(self): | ||
46 | + | ||
47 | + offset = self.fp.tell() | ||
48 | + | ||
49 | + # check magic | ||
50 | + s = self.fp.read(6) | ||
51 | + if not _accept(s): | ||
52 | + raise SyntaxError("not a CUR file") | ||
53 | + | ||
54 | + # pick the largest cursor in the file | ||
55 | + m = b"" | ||
56 | + for i in range(i16(s[4:])): | ||
57 | + s = self.fp.read(16) | ||
58 | + if not m: | ||
59 | + m = s | ||
60 | + elif i8(s[0]) > i8(m[0]) and i8(s[1]) > i8(m[1]): | ||
61 | + m = s | ||
62 | + if not m: | ||
63 | + raise TypeError("No cursors were found") | ||
64 | + | ||
65 | + # load as bitmap | ||
66 | + self._bitmap(i32(m[12:]) + offset) | ||
67 | + | ||
68 | + # patch up the bitmap height | ||
69 | + self._size = self.size[0], self.size[1] // 2 | ||
70 | + d, e, o, a = self.tile[0] | ||
71 | + self.tile[0] = d, (0, 0) + self.size, o, a | ||
72 | + | ||
73 | + return | ||
74 | + | ||
75 | + | ||
76 | +# | ||
77 | +# -------------------------------------------------------------------- | ||
78 | + | ||
79 | +Image.register_open(CurImageFile.format, CurImageFile, _accept) | ||
80 | + | ||
81 | +Image.register_extension(CurImageFile.format, ".cur") |
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# DCX file handling | ||
6 | +# | ||
7 | +# DCX is a container file format defined by Intel, commonly used | ||
8 | +# for fax applications. Each DCX file consists of a directory | ||
9 | +# (a list of file offsets) followed by a set of (usually 1-bit) | ||
10 | +# PCX files. | ||
11 | +# | ||
12 | +# History: | ||
13 | +# 1995-09-09 fl Created | ||
14 | +# 1996-03-20 fl Properly derived from PcxImageFile. | ||
15 | +# 1998-07-15 fl Renamed offset attribute to avoid name clash | ||
16 | +# 2002-07-30 fl Fixed file handling | ||
17 | +# | ||
18 | +# Copyright (c) 1997-98 by Secret Labs AB. | ||
19 | +# Copyright (c) 1995-96 by Fredrik Lundh. | ||
20 | +# | ||
21 | +# See the README file for information on usage and redistribution. | ||
22 | +# | ||
23 | + | ||
24 | +from . import Image | ||
25 | +from ._binary import i32le as i32 | ||
26 | +from .PcxImagePlugin import PcxImageFile | ||
27 | + | ||
28 | +# __version__ is deprecated and will be removed in a future version. Use | ||
29 | +# PIL.__version__ instead. | ||
30 | +__version__ = "0.2" | ||
31 | + | ||
32 | +MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then? | ||
33 | + | ||
34 | + | ||
35 | +def _accept(prefix): | ||
36 | + return len(prefix) >= 4 and i32(prefix) == MAGIC | ||
37 | + | ||
38 | + | ||
39 | +## | ||
40 | +# Image plugin for the Intel DCX format. | ||
41 | + | ||
42 | + | ||
43 | +class DcxImageFile(PcxImageFile): | ||
44 | + | ||
45 | + format = "DCX" | ||
46 | + format_description = "Intel DCX" | ||
47 | + _close_exclusive_fp_after_loading = False | ||
48 | + | ||
49 | + def _open(self): | ||
50 | + | ||
51 | + # Header | ||
52 | + s = self.fp.read(4) | ||
53 | + if i32(s) != MAGIC: | ||
54 | + raise SyntaxError("not a DCX file") | ||
55 | + | ||
56 | + # Component directory | ||
57 | + self._offset = [] | ||
58 | + for i in range(1024): | ||
59 | + offset = i32(self.fp.read(4)) | ||
60 | + if not offset: | ||
61 | + break | ||
62 | + self._offset.append(offset) | ||
63 | + | ||
64 | + self.__fp = self.fp | ||
65 | + self.frame = None | ||
66 | + self.seek(0) | ||
67 | + | ||
68 | + @property | ||
69 | + def n_frames(self): | ||
70 | + return len(self._offset) | ||
71 | + | ||
72 | + @property | ||
73 | + def is_animated(self): | ||
74 | + return len(self._offset) > 1 | ||
75 | + | ||
76 | + def seek(self, frame): | ||
77 | + if not self._seek_check(frame): | ||
78 | + return | ||
79 | + self.frame = frame | ||
80 | + self.fp = self.__fp | ||
81 | + self.fp.seek(self._offset[frame]) | ||
82 | + PcxImageFile._open(self) | ||
83 | + | ||
84 | + def tell(self): | ||
85 | + return self.frame | ||
86 | + | ||
87 | + def _close__fp(self): | ||
88 | + try: | ||
89 | + if self.__fp != self.fp: | ||
90 | + self.__fp.close() | ||
91 | + except AttributeError: | ||
92 | + pass | ||
93 | + finally: | ||
94 | + self.__fp = None | ||
95 | + | ||
96 | + | ||
97 | +Image.register_open(DcxImageFile.format, DcxImageFile, _accept) | ||
98 | + | ||
99 | +Image.register_extension(DcxImageFile.format, ".dcx") |
1 | +""" | ||
2 | +A Pillow loader for .dds files (S3TC-compressed aka DXTC) | ||
3 | +Jerome Leclanche <jerome@leclan.ch> | ||
4 | + | ||
5 | +Documentation: | ||
6 | + https://web.archive.org/web/20170802060935/http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_compression_s3tc.txt | ||
7 | + | ||
8 | +The contents of this file are hereby released in the public domain (CC0) | ||
9 | +Full text of the CC0 license: | ||
10 | + https://creativecommons.org/publicdomain/zero/1.0/ | ||
11 | +""" | ||
12 | + | ||
13 | +import struct | ||
14 | +from io import BytesIO | ||
15 | + | ||
16 | +from . import Image, ImageFile | ||
17 | + | ||
18 | +# Magic ("DDS ") | ||
19 | +DDS_MAGIC = 0x20534444 | ||
20 | + | ||
21 | +# DDS flags | ||
22 | +DDSD_CAPS = 0x1 | ||
23 | +DDSD_HEIGHT = 0x2 | ||
24 | +DDSD_WIDTH = 0x4 | ||
25 | +DDSD_PITCH = 0x8 | ||
26 | +DDSD_PIXELFORMAT = 0x1000 | ||
27 | +DDSD_MIPMAPCOUNT = 0x20000 | ||
28 | +DDSD_LINEARSIZE = 0x80000 | ||
29 | +DDSD_DEPTH = 0x800000 | ||
30 | + | ||
31 | +# DDS caps | ||
32 | +DDSCAPS_COMPLEX = 0x8 | ||
33 | +DDSCAPS_TEXTURE = 0x1000 | ||
34 | +DDSCAPS_MIPMAP = 0x400000 | ||
35 | + | ||
36 | +DDSCAPS2_CUBEMAP = 0x200 | ||
37 | +DDSCAPS2_CUBEMAP_POSITIVEX = 0x400 | ||
38 | +DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800 | ||
39 | +DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000 | ||
40 | +DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000 | ||
41 | +DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000 | ||
42 | +DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000 | ||
43 | +DDSCAPS2_VOLUME = 0x200000 | ||
44 | + | ||
45 | +# Pixel Format | ||
46 | +DDPF_ALPHAPIXELS = 0x1 | ||
47 | +DDPF_ALPHA = 0x2 | ||
48 | +DDPF_FOURCC = 0x4 | ||
49 | +DDPF_PALETTEINDEXED8 = 0x20 | ||
50 | +DDPF_RGB = 0x40 | ||
51 | +DDPF_LUMINANCE = 0x20000 | ||
52 | + | ||
53 | + | ||
54 | +# dds.h | ||
55 | + | ||
56 | +DDS_FOURCC = DDPF_FOURCC | ||
57 | +DDS_RGB = DDPF_RGB | ||
58 | +DDS_RGBA = DDPF_RGB | DDPF_ALPHAPIXELS | ||
59 | +DDS_LUMINANCE = DDPF_LUMINANCE | ||
60 | +DDS_LUMINANCEA = DDPF_LUMINANCE | DDPF_ALPHAPIXELS | ||
61 | +DDS_ALPHA = DDPF_ALPHA | ||
62 | +DDS_PAL8 = DDPF_PALETTEINDEXED8 | ||
63 | + | ||
64 | +DDS_HEADER_FLAGS_TEXTURE = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | ||
65 | +DDS_HEADER_FLAGS_MIPMAP = DDSD_MIPMAPCOUNT | ||
66 | +DDS_HEADER_FLAGS_VOLUME = DDSD_DEPTH | ||
67 | +DDS_HEADER_FLAGS_PITCH = DDSD_PITCH | ||
68 | +DDS_HEADER_FLAGS_LINEARSIZE = DDSD_LINEARSIZE | ||
69 | + | ||
70 | +DDS_HEIGHT = DDSD_HEIGHT | ||
71 | +DDS_WIDTH = DDSD_WIDTH | ||
72 | + | ||
73 | +DDS_SURFACE_FLAGS_TEXTURE = DDSCAPS_TEXTURE | ||
74 | +DDS_SURFACE_FLAGS_MIPMAP = DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | ||
75 | +DDS_SURFACE_FLAGS_CUBEMAP = DDSCAPS_COMPLEX | ||
76 | + | ||
77 | +DDS_CUBEMAP_POSITIVEX = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | ||
78 | +DDS_CUBEMAP_NEGATIVEX = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX | ||
79 | +DDS_CUBEMAP_POSITIVEY = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY | ||
80 | +DDS_CUBEMAP_NEGATIVEY = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY | ||
81 | +DDS_CUBEMAP_POSITIVEZ = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ | ||
82 | +DDS_CUBEMAP_NEGATIVEZ = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ | ||
83 | + | ||
84 | + | ||
85 | +# DXT1 | ||
86 | +DXT1_FOURCC = 0x31545844 | ||
87 | + | ||
88 | +# DXT3 | ||
89 | +DXT3_FOURCC = 0x33545844 | ||
90 | + | ||
91 | +# DXT5 | ||
92 | +DXT5_FOURCC = 0x35545844 | ||
93 | + | ||
94 | + | ||
95 | +# dxgiformat.h | ||
96 | + | ||
97 | +DXGI_FORMAT_BC7_TYPELESS = 97 | ||
98 | +DXGI_FORMAT_BC7_UNORM = 98 | ||
99 | +DXGI_FORMAT_BC7_UNORM_SRGB = 99 | ||
100 | + | ||
101 | + | ||
102 | +class DdsImageFile(ImageFile.ImageFile): | ||
103 | + format = "DDS" | ||
104 | + format_description = "DirectDraw Surface" | ||
105 | + | ||
106 | + def _open(self): | ||
107 | + magic, header_size = struct.unpack("<II", self.fp.read(8)) | ||
108 | + if header_size != 124: | ||
109 | + raise IOError("Unsupported header size %r" % (header_size)) | ||
110 | + header_bytes = self.fp.read(header_size - 4) | ||
111 | + if len(header_bytes) != 120: | ||
112 | + raise IOError("Incomplete header: %s bytes" % len(header_bytes)) | ||
113 | + header = BytesIO(header_bytes) | ||
114 | + | ||
115 | + flags, height, width = struct.unpack("<3I", header.read(12)) | ||
116 | + self._size = (width, height) | ||
117 | + self.mode = "RGBA" | ||
118 | + | ||
119 | + pitch, depth, mipmaps = struct.unpack("<3I", header.read(12)) | ||
120 | + struct.unpack("<11I", header.read(44)) # reserved | ||
121 | + | ||
122 | + # pixel format | ||
123 | + pfsize, pfflags = struct.unpack("<2I", header.read(8)) | ||
124 | + fourcc = header.read(4) | ||
125 | + bitcount, = struct.unpack("<I", header.read(4)) | ||
126 | + masks = struct.unpack("<4I", header.read(16)) | ||
127 | + if pfflags & 0x40: | ||
128 | + # DDPF_RGB - Texture contains uncompressed RGB data | ||
129 | + masks = {mask: ["R", "G", "B", "A"][i] for i, mask in enumerate(masks)} | ||
130 | + rawmode = "" | ||
131 | + if bitcount == 32: | ||
132 | + rawmode += masks[0xFF000000] | ||
133 | + rawmode += masks[0xFF0000] + masks[0xFF00] + masks[0xFF] | ||
134 | + | ||
135 | + self.tile = [("raw", (0, 0) + self.size, 0, (rawmode, 0, 1))] | ||
136 | + else: | ||
137 | + data_start = header_size + 4 | ||
138 | + n = 0 | ||
139 | + if fourcc == b"DXT1": | ||
140 | + self.pixel_format = "DXT1" | ||
141 | + n = 1 | ||
142 | + elif fourcc == b"DXT3": | ||
143 | + self.pixel_format = "DXT3" | ||
144 | + n = 2 | ||
145 | + elif fourcc == b"DXT5": | ||
146 | + self.pixel_format = "DXT5" | ||
147 | + n = 3 | ||
148 | + elif fourcc == b"DX10": | ||
149 | + data_start += 20 | ||
150 | + # ignoring flags which pertain to volume textures and cubemaps | ||
151 | + dxt10 = BytesIO(self.fp.read(20)) | ||
152 | + dxgi_format, dimension = struct.unpack("<II", dxt10.read(8)) | ||
153 | + if dxgi_format in (DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM): | ||
154 | + self.pixel_format = "BC7" | ||
155 | + n = 7 | ||
156 | + elif dxgi_format == DXGI_FORMAT_BC7_UNORM_SRGB: | ||
157 | + self.pixel_format = "BC7" | ||
158 | + self.im_info["gamma"] = 1 / 2.2 | ||
159 | + n = 7 | ||
160 | + else: | ||
161 | + raise NotImplementedError( | ||
162 | + "Unimplemented DXGI format %d" % (dxgi_format) | ||
163 | + ) | ||
164 | + else: | ||
165 | + raise NotImplementedError("Unimplemented pixel format %r" % (fourcc)) | ||
166 | + | ||
167 | + self.tile = [("bcn", (0, 0) + self.size, data_start, (n))] | ||
168 | + | ||
169 | + def load_seek(self, pos): | ||
170 | + pass | ||
171 | + | ||
172 | + | ||
173 | +def _validate(prefix): | ||
174 | + return prefix[:4] == b"DDS " | ||
175 | + | ||
176 | + | ||
177 | +Image.register_open(DdsImageFile.format, DdsImageFile, _validate) | ||
178 | +Image.register_extension(DdsImageFile.format, ".dds") |
This diff is collapsed. Click to expand it.
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# EXIF tags | ||
6 | +# | ||
7 | +# Copyright (c) 2003 by Secret Labs AB | ||
8 | +# | ||
9 | +# See the README file for information on usage and redistribution. | ||
10 | +# | ||
11 | + | ||
12 | +## | ||
13 | +# This module provides constants and clear-text names for various | ||
14 | +# well-known EXIF tags. | ||
15 | +## | ||
16 | + | ||
17 | +## | ||
18 | +# Maps EXIF tags to tag names. | ||
19 | + | ||
20 | +TAGS = { | ||
21 | + # possibly incomplete | ||
22 | + 0x000B: "ProcessingSoftware", | ||
23 | + 0x00FE: "NewSubfileType", | ||
24 | + 0x00FF: "SubfileType", | ||
25 | + 0x0100: "ImageWidth", | ||
26 | + 0x0101: "ImageLength", | ||
27 | + 0x0102: "BitsPerSample", | ||
28 | + 0x0103: "Compression", | ||
29 | + 0x0106: "PhotometricInterpretation", | ||
30 | + 0x0107: "Thresholding", | ||
31 | + 0x0108: "CellWidth", | ||
32 | + 0x0109: "CellLength", | ||
33 | + 0x010A: "FillOrder", | ||
34 | + 0x010D: "DocumentName", | ||
35 | + 0x010E: "ImageDescription", | ||
36 | + 0x010F: "Make", | ||
37 | + 0x0110: "Model", | ||
38 | + 0x0111: "StripOffsets", | ||
39 | + 0x0112: "Orientation", | ||
40 | + 0x0115: "SamplesPerPixel", | ||
41 | + 0x0116: "RowsPerStrip", | ||
42 | + 0x0117: "StripByteCounts", | ||
43 | + 0x0118: "MinSampleValue", | ||
44 | + 0x0119: "MaxSampleValue", | ||
45 | + 0x011A: "XResolution", | ||
46 | + 0x011B: "YResolution", | ||
47 | + 0x011C: "PlanarConfiguration", | ||
48 | + 0x011D: "PageName", | ||
49 | + 0x0120: "FreeOffsets", | ||
50 | + 0x0121: "FreeByteCounts", | ||
51 | + 0x0122: "GrayResponseUnit", | ||
52 | + 0x0123: "GrayResponseCurve", | ||
53 | + 0x0124: "T4Options", | ||
54 | + 0x0125: "T6Options", | ||
55 | + 0x0128: "ResolutionUnit", | ||
56 | + 0x0129: "PageNumber", | ||
57 | + 0x012D: "TransferFunction", | ||
58 | + 0x0131: "Software", | ||
59 | + 0x0132: "DateTime", | ||
60 | + 0x013B: "Artist", | ||
61 | + 0x013C: "HostComputer", | ||
62 | + 0x013D: "Predictor", | ||
63 | + 0x013E: "WhitePoint", | ||
64 | + 0x013F: "PrimaryChromaticities", | ||
65 | + 0x0140: "ColorMap", | ||
66 | + 0x0141: "HalftoneHints", | ||
67 | + 0x0142: "TileWidth", | ||
68 | + 0x0143: "TileLength", | ||
69 | + 0x0144: "TileOffsets", | ||
70 | + 0x0145: "TileByteCounts", | ||
71 | + 0x014A: "SubIFDs", | ||
72 | + 0x014C: "InkSet", | ||
73 | + 0x014D: "InkNames", | ||
74 | + 0x014E: "NumberOfInks", | ||
75 | + 0x0150: "DotRange", | ||
76 | + 0x0151: "TargetPrinter", | ||
77 | + 0x0152: "ExtraSamples", | ||
78 | + 0x0153: "SampleFormat", | ||
79 | + 0x0154: "SMinSampleValue", | ||
80 | + 0x0155: "SMaxSampleValue", | ||
81 | + 0x0156: "TransferRange", | ||
82 | + 0x0157: "ClipPath", | ||
83 | + 0x0158: "XClipPathUnits", | ||
84 | + 0x0159: "YClipPathUnits", | ||
85 | + 0x015A: "Indexed", | ||
86 | + 0x015B: "JPEGTables", | ||
87 | + 0x015F: "OPIProxy", | ||
88 | + 0x0200: "JPEGProc", | ||
89 | + 0x0201: "JpegIFOffset", | ||
90 | + 0x0202: "JpegIFByteCount", | ||
91 | + 0x0203: "JpegRestartInterval", | ||
92 | + 0x0205: "JpegLosslessPredictors", | ||
93 | + 0x0206: "JpegPointTransforms", | ||
94 | + 0x0207: "JpegQTables", | ||
95 | + 0x0208: "JpegDCTables", | ||
96 | + 0x0209: "JpegACTables", | ||
97 | + 0x0211: "YCbCrCoefficients", | ||
98 | + 0x0212: "YCbCrSubSampling", | ||
99 | + 0x0213: "YCbCrPositioning", | ||
100 | + 0x0214: "ReferenceBlackWhite", | ||
101 | + 0x02BC: "XMLPacket", | ||
102 | + 0x1000: "RelatedImageFileFormat", | ||
103 | + 0x1001: "RelatedImageWidth", | ||
104 | + 0x1002: "RelatedImageLength", | ||
105 | + 0x4746: "Rating", | ||
106 | + 0x4749: "RatingPercent", | ||
107 | + 0x800D: "ImageID", | ||
108 | + 0x828D: "CFARepeatPatternDim", | ||
109 | + 0x828E: "CFAPattern", | ||
110 | + 0x828F: "BatteryLevel", | ||
111 | + 0x8298: "Copyright", | ||
112 | + 0x829A: "ExposureTime", | ||
113 | + 0x829D: "FNumber", | ||
114 | + 0x83BB: "IPTCNAA", | ||
115 | + 0x8649: "ImageResources", | ||
116 | + 0x8769: "ExifOffset", | ||
117 | + 0x8773: "InterColorProfile", | ||
118 | + 0x8822: "ExposureProgram", | ||
119 | + 0x8824: "SpectralSensitivity", | ||
120 | + 0x8825: "GPSInfo", | ||
121 | + 0x8827: "ISOSpeedRatings", | ||
122 | + 0x8828: "OECF", | ||
123 | + 0x8829: "Interlace", | ||
124 | + 0x882A: "TimeZoneOffset", | ||
125 | + 0x882B: "SelfTimerMode", | ||
126 | + 0x9000: "ExifVersion", | ||
127 | + 0x9003: "DateTimeOriginal", | ||
128 | + 0x9004: "DateTimeDigitized", | ||
129 | + 0x9101: "ComponentsConfiguration", | ||
130 | + 0x9102: "CompressedBitsPerPixel", | ||
131 | + 0x9201: "ShutterSpeedValue", | ||
132 | + 0x9202: "ApertureValue", | ||
133 | + 0x9203: "BrightnessValue", | ||
134 | + 0x9204: "ExposureBiasValue", | ||
135 | + 0x9205: "MaxApertureValue", | ||
136 | + 0x9206: "SubjectDistance", | ||
137 | + 0x9207: "MeteringMode", | ||
138 | + 0x9208: "LightSource", | ||
139 | + 0x9209: "Flash", | ||
140 | + 0x920A: "FocalLength", | ||
141 | + 0x920B: "FlashEnergy", | ||
142 | + 0x920C: "SpatialFrequencyResponse", | ||
143 | + 0x920D: "Noise", | ||
144 | + 0x9211: "ImageNumber", | ||
145 | + 0x9212: "SecurityClassification", | ||
146 | + 0x9213: "ImageHistory", | ||
147 | + 0x9214: "SubjectLocation", | ||
148 | + 0x9215: "ExposureIndex", | ||
149 | + 0x9216: "TIFF/EPStandardID", | ||
150 | + 0x927C: "MakerNote", | ||
151 | + 0x9286: "UserComment", | ||
152 | + 0x9290: "SubsecTime", | ||
153 | + 0x9291: "SubsecTimeOriginal", | ||
154 | + 0x9292: "SubsecTimeDigitized", | ||
155 | + 0x9C9B: "XPTitle", | ||
156 | + 0x9C9C: "XPComment", | ||
157 | + 0x9C9D: "XPAuthor", | ||
158 | + 0x9C9E: "XPKeywords", | ||
159 | + 0x9C9F: "XPSubject", | ||
160 | + 0xA000: "FlashPixVersion", | ||
161 | + 0xA001: "ColorSpace", | ||
162 | + 0xA002: "ExifImageWidth", | ||
163 | + 0xA003: "ExifImageHeight", | ||
164 | + 0xA004: "RelatedSoundFile", | ||
165 | + 0xA005: "ExifInteroperabilityOffset", | ||
166 | + 0xA20B: "FlashEnergy", | ||
167 | + 0xA20C: "SpatialFrequencyResponse", | ||
168 | + 0xA20E: "FocalPlaneXResolution", | ||
169 | + 0xA20F: "FocalPlaneYResolution", | ||
170 | + 0xA210: "FocalPlaneResolutionUnit", | ||
171 | + 0xA214: "SubjectLocation", | ||
172 | + 0xA215: "ExposureIndex", | ||
173 | + 0xA217: "SensingMethod", | ||
174 | + 0xA300: "FileSource", | ||
175 | + 0xA301: "SceneType", | ||
176 | + 0xA302: "CFAPattern", | ||
177 | + 0xA401: "CustomRendered", | ||
178 | + 0xA402: "ExposureMode", | ||
179 | + 0xA403: "WhiteBalance", | ||
180 | + 0xA404: "DigitalZoomRatio", | ||
181 | + 0xA405: "FocalLengthIn35mmFilm", | ||
182 | + 0xA406: "SceneCaptureType", | ||
183 | + 0xA407: "GainControl", | ||
184 | + 0xA408: "Contrast", | ||
185 | + 0xA409: "Saturation", | ||
186 | + 0xA40A: "Sharpness", | ||
187 | + 0xA40B: "DeviceSettingDescription", | ||
188 | + 0xA40C: "SubjectDistanceRange", | ||
189 | + 0xA420: "ImageUniqueID", | ||
190 | + 0xA430: "CameraOwnerName", | ||
191 | + 0xA431: "BodySerialNumber", | ||
192 | + 0xA432: "LensSpecification", | ||
193 | + 0xA433: "LensMake", | ||
194 | + 0xA434: "LensModel", | ||
195 | + 0xA435: "LensSerialNumber", | ||
196 | + 0xA500: "Gamma", | ||
197 | + 0xC4A5: "PrintImageMatching", | ||
198 | + 0xC612: "DNGVersion", | ||
199 | + 0xC613: "DNGBackwardVersion", | ||
200 | + 0xC614: "UniqueCameraModel", | ||
201 | + 0xC615: "LocalizedCameraModel", | ||
202 | + 0xC616: "CFAPlaneColor", | ||
203 | + 0xC617: "CFALayout", | ||
204 | + 0xC618: "LinearizationTable", | ||
205 | + 0xC619: "BlackLevelRepeatDim", | ||
206 | + 0xC61A: "BlackLevel", | ||
207 | + 0xC61B: "BlackLevelDeltaH", | ||
208 | + 0xC61C: "BlackLevelDeltaV", | ||
209 | + 0xC61D: "WhiteLevel", | ||
210 | + 0xC61E: "DefaultScale", | ||
211 | + 0xC61F: "DefaultCropOrigin", | ||
212 | + 0xC620: "DefaultCropSize", | ||
213 | + 0xC621: "ColorMatrix1", | ||
214 | + 0xC622: "ColorMatrix2", | ||
215 | + 0xC623: "CameraCalibration1", | ||
216 | + 0xC624: "CameraCalibration2", | ||
217 | + 0xC625: "ReductionMatrix1", | ||
218 | + 0xC626: "ReductionMatrix2", | ||
219 | + 0xC627: "AnalogBalance", | ||
220 | + 0xC628: "AsShotNeutral", | ||
221 | + 0xC629: "AsShotWhiteXY", | ||
222 | + 0xC62A: "BaselineExposure", | ||
223 | + 0xC62B: "BaselineNoise", | ||
224 | + 0xC62C: "BaselineSharpness", | ||
225 | + 0xC62D: "BayerGreenSplit", | ||
226 | + 0xC62E: "LinearResponseLimit", | ||
227 | + 0xC62F: "CameraSerialNumber", | ||
228 | + 0xC630: "LensInfo", | ||
229 | + 0xC631: "ChromaBlurRadius", | ||
230 | + 0xC632: "AntiAliasStrength", | ||
231 | + 0xC633: "ShadowScale", | ||
232 | + 0xC634: "DNGPrivateData", | ||
233 | + 0xC635: "MakerNoteSafety", | ||
234 | + 0xC65A: "CalibrationIlluminant1", | ||
235 | + 0xC65B: "CalibrationIlluminant2", | ||
236 | + 0xC65C: "BestQualityScale", | ||
237 | + 0xC65D: "RawDataUniqueID", | ||
238 | + 0xC68B: "OriginalRawFileName", | ||
239 | + 0xC68C: "OriginalRawFileData", | ||
240 | + 0xC68D: "ActiveArea", | ||
241 | + 0xC68E: "MaskedAreas", | ||
242 | + 0xC68F: "AsShotICCProfile", | ||
243 | + 0xC690: "AsShotPreProfileMatrix", | ||
244 | + 0xC691: "CurrentICCProfile", | ||
245 | + 0xC692: "CurrentPreProfileMatrix", | ||
246 | + 0xC6BF: "ColorimetricReference", | ||
247 | + 0xC6F3: "CameraCalibrationSignature", | ||
248 | + 0xC6F4: "ProfileCalibrationSignature", | ||
249 | + 0xC6F6: "AsShotProfileName", | ||
250 | + 0xC6F7: "NoiseReductionApplied", | ||
251 | + 0xC6F8: "ProfileName", | ||
252 | + 0xC6F9: "ProfileHueSatMapDims", | ||
253 | + 0xC6FA: "ProfileHueSatMapData1", | ||
254 | + 0xC6FB: "ProfileHueSatMapData2", | ||
255 | + 0xC6FC: "ProfileToneCurve", | ||
256 | + 0xC6FD: "ProfileEmbedPolicy", | ||
257 | + 0xC6FE: "ProfileCopyright", | ||
258 | + 0xC714: "ForwardMatrix1", | ||
259 | + 0xC715: "ForwardMatrix2", | ||
260 | + 0xC716: "PreviewApplicationName", | ||
261 | + 0xC717: "PreviewApplicationVersion", | ||
262 | + 0xC718: "PreviewSettingsName", | ||
263 | + 0xC719: "PreviewSettingsDigest", | ||
264 | + 0xC71A: "PreviewColorSpace", | ||
265 | + 0xC71B: "PreviewDateTime", | ||
266 | + 0xC71C: "RawImageDigest", | ||
267 | + 0xC71D: "OriginalRawFileDigest", | ||
268 | + 0xC71E: "SubTileBlockSize", | ||
269 | + 0xC71F: "RowInterleaveFactor", | ||
270 | + 0xC725: "ProfileLookTableDims", | ||
271 | + 0xC726: "ProfileLookTableData", | ||
272 | + 0xC740: "OpcodeList1", | ||
273 | + 0xC741: "OpcodeList2", | ||
274 | + 0xC74E: "OpcodeList3", | ||
275 | + 0xC761: "NoiseProfile", | ||
276 | +} | ||
277 | + | ||
278 | +## | ||
279 | +# Maps EXIF GPS tags to tag names. | ||
280 | + | ||
281 | +GPSTAGS = { | ||
282 | + 0: "GPSVersionID", | ||
283 | + 1: "GPSLatitudeRef", | ||
284 | + 2: "GPSLatitude", | ||
285 | + 3: "GPSLongitudeRef", | ||
286 | + 4: "GPSLongitude", | ||
287 | + 5: "GPSAltitudeRef", | ||
288 | + 6: "GPSAltitude", | ||
289 | + 7: "GPSTimeStamp", | ||
290 | + 8: "GPSSatellites", | ||
291 | + 9: "GPSStatus", | ||
292 | + 10: "GPSMeasureMode", | ||
293 | + 11: "GPSDOP", | ||
294 | + 12: "GPSSpeedRef", | ||
295 | + 13: "GPSSpeed", | ||
296 | + 14: "GPSTrackRef", | ||
297 | + 15: "GPSTrack", | ||
298 | + 16: "GPSImgDirectionRef", | ||
299 | + 17: "GPSImgDirection", | ||
300 | + 18: "GPSMapDatum", | ||
301 | + 19: "GPSDestLatitudeRef", | ||
302 | + 20: "GPSDestLatitude", | ||
303 | + 21: "GPSDestLongitudeRef", | ||
304 | + 22: "GPSDestLongitude", | ||
305 | + 23: "GPSDestBearingRef", | ||
306 | + 24: "GPSDestBearing", | ||
307 | + 25: "GPSDestDistanceRef", | ||
308 | + 26: "GPSDestDistance", | ||
309 | + 27: "GPSProcessingMethod", | ||
310 | + 28: "GPSAreaInformation", | ||
311 | + 29: "GPSDateStamp", | ||
312 | + 30: "GPSDifferential", | ||
313 | + 31: "GPSHPositioningError", | ||
314 | +} |
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# FITS stub adapter | ||
6 | +# | ||
7 | +# Copyright (c) 1998-2003 by Fredrik Lundh | ||
8 | +# | ||
9 | +# See the README file for information on usage and redistribution. | ||
10 | +# | ||
11 | + | ||
12 | +from . import Image, ImageFile | ||
13 | + | ||
14 | +_handler = None | ||
15 | + | ||
16 | + | ||
17 | +def register_handler(handler): | ||
18 | + """ | ||
19 | + Install application-specific FITS image handler. | ||
20 | + | ||
21 | + :param handler: Handler object. | ||
22 | + """ | ||
23 | + global _handler | ||
24 | + _handler = handler | ||
25 | + | ||
26 | + | ||
27 | +# -------------------------------------------------------------------- | ||
28 | +# Image adapter | ||
29 | + | ||
30 | + | ||
31 | +def _accept(prefix): | ||
32 | + return prefix[:6] == b"SIMPLE" | ||
33 | + | ||
34 | + | ||
35 | +class FITSStubImageFile(ImageFile.StubImageFile): | ||
36 | + | ||
37 | + format = "FITS" | ||
38 | + format_description = "FITS" | ||
39 | + | ||
40 | + def _open(self): | ||
41 | + | ||
42 | + offset = self.fp.tell() | ||
43 | + | ||
44 | + if not _accept(self.fp.read(6)): | ||
45 | + raise SyntaxError("Not a FITS file") | ||
46 | + | ||
47 | + # FIXME: add more sanity checks here; mandatory header items | ||
48 | + # include SIMPLE, BITPIX, NAXIS, etc. | ||
49 | + | ||
50 | + self.fp.seek(offset) | ||
51 | + | ||
52 | + # make something up | ||
53 | + self.mode = "F" | ||
54 | + self._size = 1, 1 | ||
55 | + | ||
56 | + loader = self._load() | ||
57 | + if loader: | ||
58 | + loader.open(self) | ||
59 | + | ||
60 | + def _load(self): | ||
61 | + return _handler | ||
62 | + | ||
63 | + | ||
64 | +def _save(im, fp, filename): | ||
65 | + if _handler is None or not hasattr("_handler", "save"): | ||
66 | + raise IOError("FITS save handler not installed") | ||
67 | + _handler.save(im, fp, filename) | ||
68 | + | ||
69 | + | ||
70 | +# -------------------------------------------------------------------- | ||
71 | +# Registry | ||
72 | + | ||
73 | +Image.register_open(FITSStubImageFile.format, FITSStubImageFile, _accept) | ||
74 | +Image.register_save(FITSStubImageFile.format, _save) | ||
75 | + | ||
76 | +Image.register_extensions(FITSStubImageFile.format, [".fit", ".fits"]) |
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# FLI/FLC file handling. | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 95-09-01 fl Created | ||
9 | +# 97-01-03 fl Fixed parser, setup decoder tile | ||
10 | +# 98-07-15 fl Renamed offset attribute to avoid name clash | ||
11 | +# | ||
12 | +# Copyright (c) Secret Labs AB 1997-98. | ||
13 | +# Copyright (c) Fredrik Lundh 1995-97. | ||
14 | +# | ||
15 | +# See the README file for information on usage and redistribution. | ||
16 | +# | ||
17 | + | ||
18 | + | ||
19 | +from . import Image, ImageFile, ImagePalette | ||
20 | +from ._binary import i8, i16le as i16, i32le as i32, o8 | ||
21 | + | ||
22 | +# __version__ is deprecated and will be removed in a future version. Use | ||
23 | +# PIL.__version__ instead. | ||
24 | +__version__ = "0.2" | ||
25 | + | ||
26 | + | ||
27 | +# | ||
28 | +# decoder | ||
29 | + | ||
30 | + | ||
31 | +def _accept(prefix): | ||
32 | + return len(prefix) >= 6 and i16(prefix[4:6]) in [0xAF11, 0xAF12] | ||
33 | + | ||
34 | + | ||
35 | +## | ||
36 | +# Image plugin for the FLI/FLC animation format. Use the <b>seek</b> | ||
37 | +# method to load individual frames. | ||
38 | + | ||
39 | + | ||
40 | +class FliImageFile(ImageFile.ImageFile): | ||
41 | + | ||
42 | + format = "FLI" | ||
43 | + format_description = "Autodesk FLI/FLC Animation" | ||
44 | + _close_exclusive_fp_after_loading = False | ||
45 | + | ||
46 | + def _open(self): | ||
47 | + | ||
48 | + # HEAD | ||
49 | + s = self.fp.read(128) | ||
50 | + magic = i16(s[4:6]) | ||
51 | + if not ( | ||
52 | + magic in [0xAF11, 0xAF12] | ||
53 | + and i16(s[14:16]) in [0, 3] # flags | ||
54 | + and s[20:22] == b"\x00\x00" # reserved | ||
55 | + ): | ||
56 | + raise SyntaxError("not an FLI/FLC file") | ||
57 | + | ||
58 | + # frames | ||
59 | + self.__framecount = i16(s[6:8]) | ||
60 | + | ||
61 | + # image characteristics | ||
62 | + self.mode = "P" | ||
63 | + self._size = i16(s[8:10]), i16(s[10:12]) | ||
64 | + | ||
65 | + # animation speed | ||
66 | + duration = i32(s[16:20]) | ||
67 | + if magic == 0xAF11: | ||
68 | + duration = (duration * 1000) // 70 | ||
69 | + self.info["duration"] = duration | ||
70 | + | ||
71 | + # look for palette | ||
72 | + palette = [(a, a, a) for a in range(256)] | ||
73 | + | ||
74 | + s = self.fp.read(16) | ||
75 | + | ||
76 | + self.__offset = 128 | ||
77 | + | ||
78 | + if i16(s[4:6]) == 0xF100: | ||
79 | + # prefix chunk; ignore it | ||
80 | + self.__offset = self.__offset + i32(s) | ||
81 | + s = self.fp.read(16) | ||
82 | + | ||
83 | + if i16(s[4:6]) == 0xF1FA: | ||
84 | + # look for palette chunk | ||
85 | + s = self.fp.read(6) | ||
86 | + if i16(s[4:6]) == 11: | ||
87 | + self._palette(palette, 2) | ||
88 | + elif i16(s[4:6]) == 4: | ||
89 | + self._palette(palette, 0) | ||
90 | + | ||
91 | + palette = [o8(r) + o8(g) + o8(b) for (r, g, b) in palette] | ||
92 | + self.palette = ImagePalette.raw("RGB", b"".join(palette)) | ||
93 | + | ||
94 | + # set things up to decode first frame | ||
95 | + self.__frame = -1 | ||
96 | + self.__fp = self.fp | ||
97 | + self.__rewind = self.fp.tell() | ||
98 | + self.seek(0) | ||
99 | + | ||
100 | + def _palette(self, palette, shift): | ||
101 | + # load palette | ||
102 | + | ||
103 | + i = 0 | ||
104 | + for e in range(i16(self.fp.read(2))): | ||
105 | + s = self.fp.read(2) | ||
106 | + i = i + i8(s[0]) | ||
107 | + n = i8(s[1]) | ||
108 | + if n == 0: | ||
109 | + n = 256 | ||
110 | + s = self.fp.read(n * 3) | ||
111 | + for n in range(0, len(s), 3): | ||
112 | + r = i8(s[n]) << shift | ||
113 | + g = i8(s[n + 1]) << shift | ||
114 | + b = i8(s[n + 2]) << shift | ||
115 | + palette[i] = (r, g, b) | ||
116 | + i += 1 | ||
117 | + | ||
118 | + @property | ||
119 | + def n_frames(self): | ||
120 | + return self.__framecount | ||
121 | + | ||
122 | + @property | ||
123 | + def is_animated(self): | ||
124 | + return self.__framecount > 1 | ||
125 | + | ||
126 | + def seek(self, frame): | ||
127 | + if not self._seek_check(frame): | ||
128 | + return | ||
129 | + if frame < self.__frame: | ||
130 | + self._seek(0) | ||
131 | + | ||
132 | + for f in range(self.__frame + 1, frame + 1): | ||
133 | + self._seek(f) | ||
134 | + | ||
135 | + def _seek(self, frame): | ||
136 | + if frame == 0: | ||
137 | + self.__frame = -1 | ||
138 | + self.__fp.seek(self.__rewind) | ||
139 | + self.__offset = 128 | ||
140 | + else: | ||
141 | + # ensure that the previous frame was loaded | ||
142 | + self.load() | ||
143 | + | ||
144 | + if frame != self.__frame + 1: | ||
145 | + raise ValueError("cannot seek to frame %d" % frame) | ||
146 | + self.__frame = frame | ||
147 | + | ||
148 | + # move to next frame | ||
149 | + self.fp = self.__fp | ||
150 | + self.fp.seek(self.__offset) | ||
151 | + | ||
152 | + s = self.fp.read(4) | ||
153 | + if not s: | ||
154 | + raise EOFError | ||
155 | + | ||
156 | + framesize = i32(s) | ||
157 | + | ||
158 | + self.decodermaxblock = framesize | ||
159 | + self.tile = [("fli", (0, 0) + self.size, self.__offset, None)] | ||
160 | + | ||
161 | + self.__offset += framesize | ||
162 | + | ||
163 | + def tell(self): | ||
164 | + return self.__frame | ||
165 | + | ||
166 | + def _close__fp(self): | ||
167 | + try: | ||
168 | + if self.__fp != self.fp: | ||
169 | + self.__fp.close() | ||
170 | + except AttributeError: | ||
171 | + pass | ||
172 | + finally: | ||
173 | + self.__fp = None | ||
174 | + | ||
175 | + | ||
176 | +# | ||
177 | +# registry | ||
178 | + | ||
179 | +Image.register_open(FliImageFile.format, FliImageFile, _accept) | ||
180 | + | ||
181 | +Image.register_extensions(FliImageFile.format, [".fli", ".flc"]) |
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# base class for raster font file parsers | ||
6 | +# | ||
7 | +# history: | ||
8 | +# 1997-06-05 fl created | ||
9 | +# 1997-08-19 fl restrict image width | ||
10 | +# | ||
11 | +# Copyright (c) 1997-1998 by Secret Labs AB | ||
12 | +# Copyright (c) 1997-1998 by Fredrik Lundh | ||
13 | +# | ||
14 | +# See the README file for information on usage and redistribution. | ||
15 | +# | ||
16 | + | ||
17 | +from __future__ import print_function | ||
18 | + | ||
19 | +import os | ||
20 | + | ||
21 | +from . import Image, _binary | ||
22 | + | ||
23 | +WIDTH = 800 | ||
24 | + | ||
25 | + | ||
26 | +def puti16(fp, values): | ||
27 | + # write network order (big-endian) 16-bit sequence | ||
28 | + for v in values: | ||
29 | + if v < 0: | ||
30 | + v += 65536 | ||
31 | + fp.write(_binary.o16be(v)) | ||
32 | + | ||
33 | + | ||
34 | +## | ||
35 | +# Base class for raster font file handlers. | ||
36 | + | ||
37 | + | ||
38 | +class FontFile(object): | ||
39 | + | ||
40 | + bitmap = None | ||
41 | + | ||
42 | + def __init__(self): | ||
43 | + | ||
44 | + self.info = {} | ||
45 | + self.glyph = [None] * 256 | ||
46 | + | ||
47 | + def __getitem__(self, ix): | ||
48 | + return self.glyph[ix] | ||
49 | + | ||
50 | + def compile(self): | ||
51 | + """Create metrics and bitmap""" | ||
52 | + | ||
53 | + if self.bitmap: | ||
54 | + return | ||
55 | + | ||
56 | + # create bitmap large enough to hold all data | ||
57 | + h = w = maxwidth = 0 | ||
58 | + lines = 1 | ||
59 | + for glyph in self: | ||
60 | + if glyph: | ||
61 | + d, dst, src, im = glyph | ||
62 | + h = max(h, src[3] - src[1]) | ||
63 | + w = w + (src[2] - src[0]) | ||
64 | + if w > WIDTH: | ||
65 | + lines += 1 | ||
66 | + w = src[2] - src[0] | ||
67 | + maxwidth = max(maxwidth, w) | ||
68 | + | ||
69 | + xsize = maxwidth | ||
70 | + ysize = lines * h | ||
71 | + | ||
72 | + if xsize == 0 and ysize == 0: | ||
73 | + return "" | ||
74 | + | ||
75 | + self.ysize = h | ||
76 | + | ||
77 | + # paste glyphs into bitmap | ||
78 | + self.bitmap = Image.new("1", (xsize, ysize)) | ||
79 | + self.metrics = [None] * 256 | ||
80 | + x = y = 0 | ||
81 | + for i in range(256): | ||
82 | + glyph = self[i] | ||
83 | + if glyph: | ||
84 | + d, dst, src, im = glyph | ||
85 | + xx = src[2] - src[0] | ||
86 | + # yy = src[3] - src[1] | ||
87 | + x0, y0 = x, y | ||
88 | + x = x + xx | ||
89 | + if x > WIDTH: | ||
90 | + x, y = 0, y + h | ||
91 | + x0, y0 = x, y | ||
92 | + x = xx | ||
93 | + s = src[0] + x0, src[1] + y0, src[2] + x0, src[3] + y0 | ||
94 | + self.bitmap.paste(im.crop(src), s) | ||
95 | + self.metrics[i] = d, dst, s | ||
96 | + | ||
97 | + def save(self, filename): | ||
98 | + """Save font""" | ||
99 | + | ||
100 | + self.compile() | ||
101 | + | ||
102 | + # font data | ||
103 | + self.bitmap.save(os.path.splitext(filename)[0] + ".pbm", "PNG") | ||
104 | + | ||
105 | + # font metrics | ||
106 | + with open(os.path.splitext(filename)[0] + ".pil", "wb") as fp: | ||
107 | + fp.write(b"PILfont\n") | ||
108 | + fp.write((";;;;;;%d;\n" % self.ysize).encode("ascii")) # HACK!!! | ||
109 | + fp.write(b"DATA\n") | ||
110 | + for id in range(256): | ||
111 | + m = self.metrics[id] | ||
112 | + if not m: | ||
113 | + puti16(fp, [0] * 10) | ||
114 | + else: | ||
115 | + puti16(fp, m[0] + m[1] + m[2]) |
1 | +# | ||
2 | +# THIS IS WORK IN PROGRESS | ||
3 | +# | ||
4 | +# The Python Imaging Library. | ||
5 | +# $Id$ | ||
6 | +# | ||
7 | +# FlashPix support for PIL | ||
8 | +# | ||
9 | +# History: | ||
10 | +# 97-01-25 fl Created (reads uncompressed RGB images only) | ||
11 | +# | ||
12 | +# Copyright (c) Secret Labs AB 1997. | ||
13 | +# Copyright (c) Fredrik Lundh 1997. | ||
14 | +# | ||
15 | +# See the README file for information on usage and redistribution. | ||
16 | +# | ||
17 | + | ||
18 | +from __future__ import print_function | ||
19 | + | ||
20 | +import olefile | ||
21 | + | ||
22 | +from . import Image, ImageFile | ||
23 | +from ._binary import i8, i32le as i32 | ||
24 | + | ||
25 | +# __version__ is deprecated and will be removed in a future version. Use | ||
26 | +# PIL.__version__ instead. | ||
27 | +__version__ = "0.1" | ||
28 | + | ||
29 | +# we map from colour field tuples to (mode, rawmode) descriptors | ||
30 | +MODES = { | ||
31 | + # opacity | ||
32 | + (0x00007FFE): ("A", "L"), | ||
33 | + # monochrome | ||
34 | + (0x00010000,): ("L", "L"), | ||
35 | + (0x00018000, 0x00017FFE): ("RGBA", "LA"), | ||
36 | + # photo YCC | ||
37 | + (0x00020000, 0x00020001, 0x00020002): ("RGB", "YCC;P"), | ||
38 | + (0x00028000, 0x00028001, 0x00028002, 0x00027FFE): ("RGBA", "YCCA;P"), | ||
39 | + # standard RGB (NIFRGB) | ||
40 | + (0x00030000, 0x00030001, 0x00030002): ("RGB", "RGB"), | ||
41 | + (0x00038000, 0x00038001, 0x00038002, 0x00037FFE): ("RGBA", "RGBA"), | ||
42 | +} | ||
43 | + | ||
44 | + | ||
45 | +# | ||
46 | +# -------------------------------------------------------------------- | ||
47 | + | ||
48 | + | ||
49 | +def _accept(prefix): | ||
50 | + return prefix[:8] == olefile.MAGIC | ||
51 | + | ||
52 | + | ||
53 | +## | ||
54 | +# Image plugin for the FlashPix images. | ||
55 | + | ||
56 | + | ||
57 | +class FpxImageFile(ImageFile.ImageFile): | ||
58 | + | ||
59 | + format = "FPX" | ||
60 | + format_description = "FlashPix" | ||
61 | + | ||
62 | + def _open(self): | ||
63 | + # | ||
64 | + # read the OLE directory and see if this is a likely | ||
65 | + # to be a FlashPix file | ||
66 | + | ||
67 | + try: | ||
68 | + self.ole = olefile.OleFileIO(self.fp) | ||
69 | + except IOError: | ||
70 | + raise SyntaxError("not an FPX file; invalid OLE file") | ||
71 | + | ||
72 | + if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B": | ||
73 | + raise SyntaxError("not an FPX file; bad root CLSID") | ||
74 | + | ||
75 | + self._open_index(1) | ||
76 | + | ||
77 | + def _open_index(self, index=1): | ||
78 | + # | ||
79 | + # get the Image Contents Property Set | ||
80 | + | ||
81 | + prop = self.ole.getproperties( | ||
82 | + ["Data Object Store %06d" % index, "\005Image Contents"] | ||
83 | + ) | ||
84 | + | ||
85 | + # size (highest resolution) | ||
86 | + | ||
87 | + self._size = prop[0x1000002], prop[0x1000003] | ||
88 | + | ||
89 | + size = max(self.size) | ||
90 | + i = 1 | ||
91 | + while size > 64: | ||
92 | + size = size / 2 | ||
93 | + i += 1 | ||
94 | + self.maxid = i - 1 | ||
95 | + | ||
96 | + # mode. instead of using a single field for this, flashpix | ||
97 | + # requires you to specify the mode for each channel in each | ||
98 | + # resolution subimage, and leaves it to the decoder to make | ||
99 | + # sure that they all match. for now, we'll cheat and assume | ||
100 | + # that this is always the case. | ||
101 | + | ||
102 | + id = self.maxid << 16 | ||
103 | + | ||
104 | + s = prop[0x2000002 | id] | ||
105 | + | ||
106 | + colors = [] | ||
107 | + for i in range(i32(s, 4)): | ||
108 | + # note: for now, we ignore the "uncalibrated" flag | ||
109 | + colors.append(i32(s, 8 + i * 4) & 0x7FFFFFFF) | ||
110 | + | ||
111 | + self.mode, self.rawmode = MODES[tuple(colors)] | ||
112 | + | ||
113 | + # load JPEG tables, if any | ||
114 | + self.jpeg = {} | ||
115 | + for i in range(256): | ||
116 | + id = 0x3000001 | (i << 16) | ||
117 | + if id in prop: | ||
118 | + self.jpeg[i] = prop[id] | ||
119 | + | ||
120 | + self._open_subimage(1, self.maxid) | ||
121 | + | ||
122 | + def _open_subimage(self, index=1, subimage=0): | ||
123 | + # | ||
124 | + # setup tile descriptors for a given subimage | ||
125 | + | ||
126 | + stream = [ | ||
127 | + "Data Object Store %06d" % index, | ||
128 | + "Resolution %04d" % subimage, | ||
129 | + "Subimage 0000 Header", | ||
130 | + ] | ||
131 | + | ||
132 | + fp = self.ole.openstream(stream) | ||
133 | + | ||
134 | + # skip prefix | ||
135 | + fp.read(28) | ||
136 | + | ||
137 | + # header stream | ||
138 | + s = fp.read(36) | ||
139 | + | ||
140 | + size = i32(s, 4), i32(s, 8) | ||
141 | + # tilecount = i32(s, 12) | ||
142 | + tilesize = i32(s, 16), i32(s, 20) | ||
143 | + # channels = i32(s, 24) | ||
144 | + offset = i32(s, 28) | ||
145 | + length = i32(s, 32) | ||
146 | + | ||
147 | + if size != self.size: | ||
148 | + raise IOError("subimage mismatch") | ||
149 | + | ||
150 | + # get tile descriptors | ||
151 | + fp.seek(28 + offset) | ||
152 | + s = fp.read(i32(s, 12) * length) | ||
153 | + | ||
154 | + x = y = 0 | ||
155 | + xsize, ysize = size | ||
156 | + xtile, ytile = tilesize | ||
157 | + self.tile = [] | ||
158 | + | ||
159 | + for i in range(0, len(s), length): | ||
160 | + | ||
161 | + compression = i32(s, i + 8) | ||
162 | + | ||
163 | + if compression == 0: | ||
164 | + self.tile.append( | ||
165 | + ( | ||
166 | + "raw", | ||
167 | + (x, y, x + xtile, y + ytile), | ||
168 | + i32(s, i) + 28, | ||
169 | + (self.rawmode), | ||
170 | + ) | ||
171 | + ) | ||
172 | + | ||
173 | + elif compression == 1: | ||
174 | + | ||
175 | + # FIXME: the fill decoder is not implemented | ||
176 | + self.tile.append( | ||
177 | + ( | ||
178 | + "fill", | ||
179 | + (x, y, x + xtile, y + ytile), | ||
180 | + i32(s, i) + 28, | ||
181 | + (self.rawmode, s[12:16]), | ||
182 | + ) | ||
183 | + ) | ||
184 | + | ||
185 | + elif compression == 2: | ||
186 | + | ||
187 | + internal_color_conversion = i8(s[14]) | ||
188 | + jpeg_tables = i8(s[15]) | ||
189 | + rawmode = self.rawmode | ||
190 | + | ||
191 | + if internal_color_conversion: | ||
192 | + # The image is stored as usual (usually YCbCr). | ||
193 | + if rawmode == "RGBA": | ||
194 | + # For "RGBA", data is stored as YCbCrA based on | ||
195 | + # negative RGB. The following trick works around | ||
196 | + # this problem : | ||
197 | + jpegmode, rawmode = "YCbCrK", "CMYK" | ||
198 | + else: | ||
199 | + jpegmode = None # let the decoder decide | ||
200 | + | ||
201 | + else: | ||
202 | + # The image is stored as defined by rawmode | ||
203 | + jpegmode = rawmode | ||
204 | + | ||
205 | + self.tile.append( | ||
206 | + ( | ||
207 | + "jpeg", | ||
208 | + (x, y, x + xtile, y + ytile), | ||
209 | + i32(s, i) + 28, | ||
210 | + (rawmode, jpegmode), | ||
211 | + ) | ||
212 | + ) | ||
213 | + | ||
214 | + # FIXME: jpeg tables are tile dependent; the prefix | ||
215 | + # data must be placed in the tile descriptor itself! | ||
216 | + | ||
217 | + if jpeg_tables: | ||
218 | + self.tile_prefix = self.jpeg[jpeg_tables] | ||
219 | + | ||
220 | + else: | ||
221 | + raise IOError("unknown/invalid compression") | ||
222 | + | ||
223 | + x = x + xtile | ||
224 | + if x >= xsize: | ||
225 | + x, y = 0, y + ytile | ||
226 | + if y >= ysize: | ||
227 | + break # isn't really required | ||
228 | + | ||
229 | + self.stream = stream | ||
230 | + self.fp = None | ||
231 | + | ||
232 | + def load(self): | ||
233 | + | ||
234 | + if not self.fp: | ||
235 | + self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"]) | ||
236 | + | ||
237 | + return ImageFile.ImageFile.load(self) | ||
238 | + | ||
239 | + | ||
240 | +# | ||
241 | +# -------------------------------------------------------------------- | ||
242 | + | ||
243 | + | ||
244 | +Image.register_open(FpxImageFile.format, FpxImageFile, _accept) | ||
245 | + | ||
246 | +Image.register_extension(FpxImageFile.format, ".fpx") |
1 | +""" | ||
2 | +A Pillow loader for .ftc and .ftu files (FTEX) | ||
3 | +Jerome Leclanche <jerome@leclan.ch> | ||
4 | + | ||
5 | +The contents of this file are hereby released in the public domain (CC0) | ||
6 | +Full text of the CC0 license: | ||
7 | + https://creativecommons.org/publicdomain/zero/1.0/ | ||
8 | + | ||
9 | +Independence War 2: Edge Of Chaos - Texture File Format - 16 October 2001 | ||
10 | + | ||
11 | +The textures used for 3D objects in Independence War 2: Edge Of Chaos are in a | ||
12 | +packed custom format called FTEX. This file format uses file extensions FTC | ||
13 | +and FTU. | ||
14 | +* FTC files are compressed textures (using standard texture compression). | ||
15 | +* FTU files are not compressed. | ||
16 | +Texture File Format | ||
17 | +The FTC and FTU texture files both use the same format. This | ||
18 | +has the following structure: | ||
19 | +{header} | ||
20 | +{format_directory} | ||
21 | +{data} | ||
22 | +Where: | ||
23 | +{header} = { | ||
24 | + u32:magic, | ||
25 | + u32:version, | ||
26 | + u32:width, | ||
27 | + u32:height, | ||
28 | + u32:mipmap_count, | ||
29 | + u32:format_count | ||
30 | +} | ||
31 | + | ||
32 | +* The "magic" number is "FTEX". | ||
33 | +* "width" and "height" are the dimensions of the texture. | ||
34 | +* "mipmap_count" is the number of mipmaps in the texture. | ||
35 | +* "format_count" is the number of texture formats (different versions of the | ||
36 | +same texture) in this file. | ||
37 | + | ||
38 | +{format_directory} = format_count * { u32:format, u32:where } | ||
39 | + | ||
40 | +The format value is 0 for DXT1 compressed textures and 1 for 24-bit RGB | ||
41 | +uncompressed textures. | ||
42 | +The texture data for a format starts at the position "where" in the file. | ||
43 | + | ||
44 | +Each set of texture data in the file has the following structure: | ||
45 | +{data} = format_count * { u32:mipmap_size, mipmap_size * { u8 } } | ||
46 | +* "mipmap_size" is the number of bytes in that mip level. For compressed | ||
47 | +textures this is the size of the texture data compressed with DXT1. For 24 bit | ||
48 | +uncompressed textures, this is 3 * width * height. Following this are the image | ||
49 | +bytes for that mipmap level. | ||
50 | + | ||
51 | +Note: All data is stored in little-Endian (Intel) byte order. | ||
52 | +""" | ||
53 | + | ||
54 | +import struct | ||
55 | +from io import BytesIO | ||
56 | + | ||
57 | +from . import Image, ImageFile | ||
58 | + | ||
59 | +MAGIC = b"FTEX" | ||
60 | +FORMAT_DXT1 = 0 | ||
61 | +FORMAT_UNCOMPRESSED = 1 | ||
62 | + | ||
63 | + | ||
64 | +class FtexImageFile(ImageFile.ImageFile): | ||
65 | + format = "FTEX" | ||
66 | + format_description = "Texture File Format (IW2:EOC)" | ||
67 | + | ||
68 | + def _open(self): | ||
69 | + struct.unpack("<I", self.fp.read(4)) # magic | ||
70 | + struct.unpack("<i", self.fp.read(4)) # version | ||
71 | + self._size = struct.unpack("<2i", self.fp.read(8)) | ||
72 | + mipmap_count, format_count = struct.unpack("<2i", self.fp.read(8)) | ||
73 | + | ||
74 | + self.mode = "RGB" | ||
75 | + | ||
76 | + # Only support single-format files. | ||
77 | + # I don't know of any multi-format file. | ||
78 | + assert format_count == 1 | ||
79 | + | ||
80 | + format, where = struct.unpack("<2i", self.fp.read(8)) | ||
81 | + self.fp.seek(where) | ||
82 | + mipmap_size, = struct.unpack("<i", self.fp.read(4)) | ||
83 | + | ||
84 | + data = self.fp.read(mipmap_size) | ||
85 | + | ||
86 | + if format == FORMAT_DXT1: | ||
87 | + self.mode = "RGBA" | ||
88 | + self.tile = [("bcn", (0, 0) + self.size, 0, (1))] | ||
89 | + elif format == FORMAT_UNCOMPRESSED: | ||
90 | + self.tile = [("raw", (0, 0) + self.size, 0, ("RGB", 0, 1))] | ||
91 | + else: | ||
92 | + raise ValueError("Invalid texture compression format: %r" % (format)) | ||
93 | + | ||
94 | + self.fp.close() | ||
95 | + self.fp = BytesIO(data) | ||
96 | + | ||
97 | + def load_seek(self, pos): | ||
98 | + pass | ||
99 | + | ||
100 | + | ||
101 | +def _validate(prefix): | ||
102 | + return prefix[:4] == MAGIC | ||
103 | + | ||
104 | + | ||
105 | +Image.register_open(FtexImageFile.format, FtexImageFile, _validate) | ||
106 | +Image.register_extensions(FtexImageFile.format, [".ftc", ".ftu"]) |
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# | ||
4 | +# load a GIMP brush file | ||
5 | +# | ||
6 | +# History: | ||
7 | +# 96-03-14 fl Created | ||
8 | +# 16-01-08 es Version 2 | ||
9 | +# | ||
10 | +# Copyright (c) Secret Labs AB 1997. | ||
11 | +# Copyright (c) Fredrik Lundh 1996. | ||
12 | +# Copyright (c) Eric Soroos 2016. | ||
13 | +# | ||
14 | +# See the README file for information on usage and redistribution. | ||
15 | +# | ||
16 | +# | ||
17 | +# See https://github.com/GNOME/gimp/blob/master/devel-docs/gbr.txt for | ||
18 | +# format documentation. | ||
19 | +# | ||
20 | +# This code Interprets version 1 and 2 .gbr files. | ||
21 | +# Version 1 files are obsolete, and should not be used for new | ||
22 | +# brushes. | ||
23 | +# Version 2 files are saved by GIMP v2.8 (at least) | ||
24 | +# Version 3 files have a format specifier of 18 for 16bit floats in | ||
25 | +# the color depth field. This is currently unsupported by Pillow. | ||
26 | + | ||
27 | +from . import Image, ImageFile | ||
28 | +from ._binary import i32be as i32 | ||
29 | + | ||
30 | + | ||
31 | +def _accept(prefix): | ||
32 | + return len(prefix) >= 8 and i32(prefix[:4]) >= 20 and i32(prefix[4:8]) in (1, 2) | ||
33 | + | ||
34 | + | ||
35 | +## | ||
36 | +# Image plugin for the GIMP brush format. | ||
37 | + | ||
38 | + | ||
39 | +class GbrImageFile(ImageFile.ImageFile): | ||
40 | + | ||
41 | + format = "GBR" | ||
42 | + format_description = "GIMP brush file" | ||
43 | + | ||
44 | + def _open(self): | ||
45 | + header_size = i32(self.fp.read(4)) | ||
46 | + version = i32(self.fp.read(4)) | ||
47 | + if header_size < 20: | ||
48 | + raise SyntaxError("not a GIMP brush") | ||
49 | + if version not in (1, 2): | ||
50 | + raise SyntaxError("Unsupported GIMP brush version: %s" % version) | ||
51 | + | ||
52 | + width = i32(self.fp.read(4)) | ||
53 | + height = i32(self.fp.read(4)) | ||
54 | + color_depth = i32(self.fp.read(4)) | ||
55 | + if width <= 0 or height <= 0: | ||
56 | + raise SyntaxError("not a GIMP brush") | ||
57 | + if color_depth not in (1, 4): | ||
58 | + raise SyntaxError("Unsupported GIMP brush color depth: %s" % color_depth) | ||
59 | + | ||
60 | + if version == 1: | ||
61 | + comment_length = header_size - 20 | ||
62 | + else: | ||
63 | + comment_length = header_size - 28 | ||
64 | + magic_number = self.fp.read(4) | ||
65 | + if magic_number != b"GIMP": | ||
66 | + raise SyntaxError("not a GIMP brush, bad magic number") | ||
67 | + self.info["spacing"] = i32(self.fp.read(4)) | ||
68 | + | ||
69 | + comment = self.fp.read(comment_length)[:-1] | ||
70 | + | ||
71 | + if color_depth == 1: | ||
72 | + self.mode = "L" | ||
73 | + else: | ||
74 | + self.mode = "RGBA" | ||
75 | + | ||
76 | + self._size = width, height | ||
77 | + | ||
78 | + self.info["comment"] = comment | ||
79 | + | ||
80 | + # Image might not be small | ||
81 | + Image._decompression_bomb_check(self.size) | ||
82 | + | ||
83 | + # Data is an uncompressed block of w * h * bytes/pixel | ||
84 | + self._data_size = width * height * color_depth | ||
85 | + | ||
86 | + def load(self): | ||
87 | + self.im = Image.core.new(self.mode, self.size) | ||
88 | + self.frombytes(self.fp.read(self._data_size)) | ||
89 | + | ||
90 | + | ||
91 | +# | ||
92 | +# registry | ||
93 | + | ||
94 | + | ||
95 | +Image.register_open(GbrImageFile.format, GbrImageFile, _accept) | ||
96 | +Image.register_extension(GbrImageFile.format, ".gbr") |
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# GD file handling | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 1996-04-12 fl Created | ||
9 | +# | ||
10 | +# Copyright (c) 1997 by Secret Labs AB. | ||
11 | +# Copyright (c) 1996 by Fredrik Lundh. | ||
12 | +# | ||
13 | +# See the README file for information on usage and redistribution. | ||
14 | +# | ||
15 | + | ||
16 | + | ||
17 | +# NOTE: This format cannot be automatically recognized, so the | ||
18 | +# class is not registered for use with Image.open(). To open a | ||
19 | +# gd file, use the GdImageFile.open() function instead. | ||
20 | + | ||
21 | +# THE GD FORMAT IS NOT DESIGNED FOR DATA INTERCHANGE. This | ||
22 | +# implementation is provided for convenience and demonstrational | ||
23 | +# purposes only. | ||
24 | + | ||
25 | + | ||
26 | +from . import ImageFile, ImagePalette | ||
27 | +from ._binary import i8, i16be as i16, i32be as i32 | ||
28 | + | ||
29 | +# __version__ is deprecated and will be removed in a future version. Use | ||
30 | +# PIL.__version__ instead. | ||
31 | +__version__ = "0.1" | ||
32 | + | ||
33 | + | ||
34 | +## | ||
35 | +# Image plugin for the GD uncompressed format. Note that this format | ||
36 | +# is not supported by the standard <b>Image.open</b> function. To use | ||
37 | +# this plugin, you have to import the <b>GdImageFile</b> module and | ||
38 | +# use the <b>GdImageFile.open</b> function. | ||
39 | + | ||
40 | + | ||
41 | +class GdImageFile(ImageFile.ImageFile): | ||
42 | + | ||
43 | + format = "GD" | ||
44 | + format_description = "GD uncompressed images" | ||
45 | + | ||
46 | + def _open(self): | ||
47 | + | ||
48 | + # Header | ||
49 | + s = self.fp.read(1037) | ||
50 | + | ||
51 | + if not i16(s[:2]) in [65534, 65535]: | ||
52 | + raise SyntaxError("Not a valid GD 2.x .gd file") | ||
53 | + | ||
54 | + self.mode = "L" # FIXME: "P" | ||
55 | + self._size = i16(s[2:4]), i16(s[4:6]) | ||
56 | + | ||
57 | + trueColor = i8(s[6]) | ||
58 | + trueColorOffset = 2 if trueColor else 0 | ||
59 | + | ||
60 | + # transparency index | ||
61 | + tindex = i32(s[7 + trueColorOffset : 7 + trueColorOffset + 4]) | ||
62 | + if tindex < 256: | ||
63 | + self.info["transparency"] = tindex | ||
64 | + | ||
65 | + self.palette = ImagePalette.raw( | ||
66 | + "XBGR", s[7 + trueColorOffset + 4 : 7 + trueColorOffset + 4 + 256 * 4] | ||
67 | + ) | ||
68 | + | ||
69 | + self.tile = [ | ||
70 | + ("raw", (0, 0) + self.size, 7 + trueColorOffset + 4 + 256 * 4, ("L", 0, 1)) | ||
71 | + ] | ||
72 | + | ||
73 | + | ||
74 | +def open(fp, mode="r"): | ||
75 | + """ | ||
76 | + Load texture from a GD image file. | ||
77 | + | ||
78 | + :param filename: GD file name, or an opened file handle. | ||
79 | + :param mode: Optional mode. In this version, if the mode argument | ||
80 | + is given, it must be "r". | ||
81 | + :returns: An image instance. | ||
82 | + :raises IOError: If the image could not be read. | ||
83 | + """ | ||
84 | + if mode != "r": | ||
85 | + raise ValueError("bad mode") | ||
86 | + | ||
87 | + try: | ||
88 | + return GdImageFile(fp) | ||
89 | + except SyntaxError: | ||
90 | + raise IOError("cannot identify this image file") |
This diff is collapsed. Click to expand it.
1 | +# | ||
2 | +# Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# stuff to read (and render) GIMP gradient files | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 97-08-23 fl Created | ||
9 | +# | ||
10 | +# Copyright (c) Secret Labs AB 1997. | ||
11 | +# Copyright (c) Fredrik Lundh 1997. | ||
12 | +# | ||
13 | +# See the README file for information on usage and redistribution. | ||
14 | +# | ||
15 | + | ||
16 | +from math import log, pi, sin, sqrt | ||
17 | + | ||
18 | +from ._binary import o8 | ||
19 | + | ||
20 | +# -------------------------------------------------------------------- | ||
21 | +# Stuff to translate curve segments to palette values (derived from | ||
22 | +# the corresponding code in GIMP, written by Federico Mena Quintero. | ||
23 | +# See the GIMP distribution for more information.) | ||
24 | +# | ||
25 | + | ||
26 | +EPSILON = 1e-10 | ||
27 | + | ||
28 | + | ||
29 | +def linear(middle, pos): | ||
30 | + if pos <= middle: | ||
31 | + if middle < EPSILON: | ||
32 | + return 0.0 | ||
33 | + else: | ||
34 | + return 0.5 * pos / middle | ||
35 | + else: | ||
36 | + pos = pos - middle | ||
37 | + middle = 1.0 - middle | ||
38 | + if middle < EPSILON: | ||
39 | + return 1.0 | ||
40 | + else: | ||
41 | + return 0.5 + 0.5 * pos / middle | ||
42 | + | ||
43 | + | ||
44 | +def curved(middle, pos): | ||
45 | + return pos ** (log(0.5) / log(max(middle, EPSILON))) | ||
46 | + | ||
47 | + | ||
48 | +def sine(middle, pos): | ||
49 | + return (sin((-pi / 2.0) + pi * linear(middle, pos)) + 1.0) / 2.0 | ||
50 | + | ||
51 | + | ||
52 | +def sphere_increasing(middle, pos): | ||
53 | + return sqrt(1.0 - (linear(middle, pos) - 1.0) ** 2) | ||
54 | + | ||
55 | + | ||
56 | +def sphere_decreasing(middle, pos): | ||
57 | + return 1.0 - sqrt(1.0 - linear(middle, pos) ** 2) | ||
58 | + | ||
59 | + | ||
60 | +SEGMENTS = [linear, curved, sine, sphere_increasing, sphere_decreasing] | ||
61 | + | ||
62 | + | ||
63 | +class GradientFile(object): | ||
64 | + | ||
65 | + gradient = None | ||
66 | + | ||
67 | + def getpalette(self, entries=256): | ||
68 | + | ||
69 | + palette = [] | ||
70 | + | ||
71 | + ix = 0 | ||
72 | + x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] | ||
73 | + | ||
74 | + for i in range(entries): | ||
75 | + | ||
76 | + x = i / float(entries - 1) | ||
77 | + | ||
78 | + while x1 < x: | ||
79 | + ix += 1 | ||
80 | + x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] | ||
81 | + | ||
82 | + w = x1 - x0 | ||
83 | + | ||
84 | + if w < EPSILON: | ||
85 | + scale = segment(0.5, 0.5) | ||
86 | + else: | ||
87 | + scale = segment((xm - x0) / w, (x - x0) / w) | ||
88 | + | ||
89 | + # expand to RGBA | ||
90 | + r = o8(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5)) | ||
91 | + g = o8(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5)) | ||
92 | + b = o8(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5)) | ||
93 | + a = o8(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5)) | ||
94 | + | ||
95 | + # add to palette | ||
96 | + palette.append(r + g + b + a) | ||
97 | + | ||
98 | + return b"".join(palette), "RGBA" | ||
99 | + | ||
100 | + | ||
101 | +## | ||
102 | +# File handler for GIMP's gradient format. | ||
103 | + | ||
104 | + | ||
105 | +class GimpGradientFile(GradientFile): | ||
106 | + def __init__(self, fp): | ||
107 | + | ||
108 | + if fp.readline()[:13] != b"GIMP Gradient": | ||
109 | + raise SyntaxError("not a GIMP gradient file") | ||
110 | + | ||
111 | + line = fp.readline() | ||
112 | + | ||
113 | + # GIMP 1.2 gradient files don't contain a name, but GIMP 1.3 files do | ||
114 | + if line.startswith(b"Name: "): | ||
115 | + line = fp.readline().strip() | ||
116 | + | ||
117 | + count = int(line) | ||
118 | + | ||
119 | + gradient = [] | ||
120 | + | ||
121 | + for i in range(count): | ||
122 | + | ||
123 | + s = fp.readline().split() | ||
124 | + w = [float(x) for x in s[:11]] | ||
125 | + | ||
126 | + x0, x1 = w[0], w[2] | ||
127 | + xm = w[1] | ||
128 | + rgb0 = w[3:7] | ||
129 | + rgb1 = w[7:11] | ||
130 | + | ||
131 | + segment = SEGMENTS[int(s[11])] | ||
132 | + cspace = int(s[12]) | ||
133 | + | ||
134 | + if cspace != 0: | ||
135 | + raise IOError("cannot handle HSV colour space") | ||
136 | + | ||
137 | + gradient.append((x0, x1, xm, rgb0, rgb1, segment)) | ||
138 | + | ||
139 | + self.gradient = gradient |
1 | +# | ||
2 | +# Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# stuff to read GIMP palette files | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 1997-08-23 fl Created | ||
9 | +# 2004-09-07 fl Support GIMP 2.0 palette files. | ||
10 | +# | ||
11 | +# Copyright (c) Secret Labs AB 1997-2004. All rights reserved. | ||
12 | +# Copyright (c) Fredrik Lundh 1997-2004. | ||
13 | +# | ||
14 | +# See the README file for information on usage and redistribution. | ||
15 | +# | ||
16 | + | ||
17 | +import re | ||
18 | + | ||
19 | +from ._binary import o8 | ||
20 | + | ||
21 | +## | ||
22 | +# File handler for GIMP's palette format. | ||
23 | + | ||
24 | + | ||
25 | +class GimpPaletteFile(object): | ||
26 | + | ||
27 | + rawmode = "RGB" | ||
28 | + | ||
29 | + def __init__(self, fp): | ||
30 | + | ||
31 | + self.palette = [o8(i) * 3 for i in range(256)] | ||
32 | + | ||
33 | + if fp.readline()[:12] != b"GIMP Palette": | ||
34 | + raise SyntaxError("not a GIMP palette file") | ||
35 | + | ||
36 | + for i in range(256): | ||
37 | + | ||
38 | + s = fp.readline() | ||
39 | + if not s: | ||
40 | + break | ||
41 | + | ||
42 | + # skip fields and comment lines | ||
43 | + if re.match(br"\w+:|#", s): | ||
44 | + continue | ||
45 | + if len(s) > 100: | ||
46 | + raise SyntaxError("bad palette file") | ||
47 | + | ||
48 | + v = tuple(map(int, s.split()[:3])) | ||
49 | + if len(v) != 3: | ||
50 | + raise ValueError("bad palette entry") | ||
51 | + | ||
52 | + self.palette[i] = o8(v[0]) + o8(v[1]) + o8(v[2]) | ||
53 | + | ||
54 | + self.palette = b"".join(self.palette) | ||
55 | + | ||
56 | + def getpalette(self): | ||
57 | + | ||
58 | + return self.palette, self.rawmode |
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# GRIB stub adapter | ||
6 | +# | ||
7 | +# Copyright (c) 1996-2003 by Fredrik Lundh | ||
8 | +# | ||
9 | +# See the README file for information on usage and redistribution. | ||
10 | +# | ||
11 | + | ||
12 | +from . import Image, ImageFile | ||
13 | +from ._binary import i8 | ||
14 | + | ||
15 | +_handler = None | ||
16 | + | ||
17 | + | ||
18 | +def register_handler(handler): | ||
19 | + """ | ||
20 | + Install application-specific GRIB image handler. | ||
21 | + | ||
22 | + :param handler: Handler object. | ||
23 | + """ | ||
24 | + global _handler | ||
25 | + _handler = handler | ||
26 | + | ||
27 | + | ||
28 | +# -------------------------------------------------------------------- | ||
29 | +# Image adapter | ||
30 | + | ||
31 | + | ||
32 | +def _accept(prefix): | ||
33 | + return prefix[0:4] == b"GRIB" and i8(prefix[7]) == 1 | ||
34 | + | ||
35 | + | ||
36 | +class GribStubImageFile(ImageFile.StubImageFile): | ||
37 | + | ||
38 | + format = "GRIB" | ||
39 | + format_description = "GRIB" | ||
40 | + | ||
41 | + def _open(self): | ||
42 | + | ||
43 | + offset = self.fp.tell() | ||
44 | + | ||
45 | + if not _accept(self.fp.read(8)): | ||
46 | + raise SyntaxError("Not a GRIB file") | ||
47 | + | ||
48 | + self.fp.seek(offset) | ||
49 | + | ||
50 | + # make something up | ||
51 | + self.mode = "F" | ||
52 | + self._size = 1, 1 | ||
53 | + | ||
54 | + loader = self._load() | ||
55 | + if loader: | ||
56 | + loader.open(self) | ||
57 | + | ||
58 | + def _load(self): | ||
59 | + return _handler | ||
60 | + | ||
61 | + | ||
62 | +def _save(im, fp, filename): | ||
63 | + if _handler is None or not hasattr("_handler", "save"): | ||
64 | + raise IOError("GRIB save handler not installed") | ||
65 | + _handler.save(im, fp, filename) | ||
66 | + | ||
67 | + | ||
68 | +# -------------------------------------------------------------------- | ||
69 | +# Registry | ||
70 | + | ||
71 | +Image.register_open(GribStubImageFile.format, GribStubImageFile, _accept) | ||
72 | +Image.register_save(GribStubImageFile.format, _save) | ||
73 | + | ||
74 | +Image.register_extension(GribStubImageFile.format, ".grib") |
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# HDF5 stub adapter | ||
6 | +# | ||
7 | +# Copyright (c) 2000-2003 by Fredrik Lundh | ||
8 | +# | ||
9 | +# See the README file for information on usage and redistribution. | ||
10 | +# | ||
11 | + | ||
12 | +from . import Image, ImageFile | ||
13 | + | ||
14 | +_handler = None | ||
15 | + | ||
16 | + | ||
17 | +def register_handler(handler): | ||
18 | + """ | ||
19 | + Install application-specific HDF5 image handler. | ||
20 | + | ||
21 | + :param handler: Handler object. | ||
22 | + """ | ||
23 | + global _handler | ||
24 | + _handler = handler | ||
25 | + | ||
26 | + | ||
27 | +# -------------------------------------------------------------------- | ||
28 | +# Image adapter | ||
29 | + | ||
30 | + | ||
31 | +def _accept(prefix): | ||
32 | + return prefix[:8] == b"\x89HDF\r\n\x1a\n" | ||
33 | + | ||
34 | + | ||
35 | +class HDF5StubImageFile(ImageFile.StubImageFile): | ||
36 | + | ||
37 | + format = "HDF5" | ||
38 | + format_description = "HDF5" | ||
39 | + | ||
40 | + def _open(self): | ||
41 | + | ||
42 | + offset = self.fp.tell() | ||
43 | + | ||
44 | + if not _accept(self.fp.read(8)): | ||
45 | + raise SyntaxError("Not an HDF file") | ||
46 | + | ||
47 | + self.fp.seek(offset) | ||
48 | + | ||
49 | + # make something up | ||
50 | + self.mode = "F" | ||
51 | + self._size = 1, 1 | ||
52 | + | ||
53 | + loader = self._load() | ||
54 | + if loader: | ||
55 | + loader.open(self) | ||
56 | + | ||
57 | + def _load(self): | ||
58 | + return _handler | ||
59 | + | ||
60 | + | ||
61 | +def _save(im, fp, filename): | ||
62 | + if _handler is None or not hasattr("_handler", "save"): | ||
63 | + raise IOError("HDF5 save handler not installed") | ||
64 | + _handler.save(im, fp, filename) | ||
65 | + | ||
66 | + | ||
67 | +# -------------------------------------------------------------------- | ||
68 | +# Registry | ||
69 | + | ||
70 | +Image.register_open(HDF5StubImageFile.format, HDF5StubImageFile, _accept) | ||
71 | +Image.register_save(HDF5StubImageFile.format, _save) | ||
72 | + | ||
73 | +Image.register_extensions(HDF5StubImageFile.format, [".h5", ".hdf"]) |
This diff is collapsed. Click to expand it.
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# Windows Icon support for PIL | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 96-05-27 fl Created | ||
9 | +# | ||
10 | +# Copyright (c) Secret Labs AB 1997. | ||
11 | +# Copyright (c) Fredrik Lundh 1996. | ||
12 | +# | ||
13 | +# See the README file for information on usage and redistribution. | ||
14 | +# | ||
15 | + | ||
16 | +# This plugin is a refactored version of Win32IconImagePlugin by Bryan Davis | ||
17 | +# <casadebender@gmail.com>. | ||
18 | +# https://code.google.com/archive/p/casadebender/wikis/Win32IconImagePlugin.wiki | ||
19 | +# | ||
20 | +# Icon format references: | ||
21 | +# * https://en.wikipedia.org/wiki/ICO_(file_format) | ||
22 | +# * https://msdn.microsoft.com/en-us/library/ms997538.aspx | ||
23 | + | ||
24 | + | ||
25 | +import struct | ||
26 | +import warnings | ||
27 | +from io import BytesIO | ||
28 | +from math import ceil, log | ||
29 | + | ||
30 | +from . import BmpImagePlugin, Image, ImageFile, PngImagePlugin | ||
31 | +from ._binary import i8, i16le as i16, i32le as i32 | ||
32 | + | ||
33 | +# __version__ is deprecated and will be removed in a future version. Use | ||
34 | +# PIL.__version__ instead. | ||
35 | +__version__ = "0.1" | ||
36 | + | ||
37 | +# | ||
38 | +# -------------------------------------------------------------------- | ||
39 | + | ||
40 | +_MAGIC = b"\0\0\1\0" | ||
41 | + | ||
42 | + | ||
43 | +def _save(im, fp, filename): | ||
44 | + fp.write(_MAGIC) # (2+2) | ||
45 | + sizes = im.encoderinfo.get( | ||
46 | + "sizes", | ||
47 | + [(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)], | ||
48 | + ) | ||
49 | + width, height = im.size | ||
50 | + sizes = filter( | ||
51 | + lambda x: False | ||
52 | + if (x[0] > width or x[1] > height or x[0] > 256 or x[1] > 256) | ||
53 | + else True, | ||
54 | + sizes, | ||
55 | + ) | ||
56 | + sizes = list(sizes) | ||
57 | + fp.write(struct.pack("<H", len(sizes))) # idCount(2) | ||
58 | + offset = fp.tell() + len(sizes) * 16 | ||
59 | + for size in sizes: | ||
60 | + width, height = size | ||
61 | + # 0 means 256 | ||
62 | + fp.write(struct.pack("B", width if width < 256 else 0)) # bWidth(1) | ||
63 | + fp.write(struct.pack("B", height if height < 256 else 0)) # bHeight(1) | ||
64 | + fp.write(b"\0") # bColorCount(1) | ||
65 | + fp.write(b"\0") # bReserved(1) | ||
66 | + fp.write(b"\0\0") # wPlanes(2) | ||
67 | + fp.write(struct.pack("<H", 32)) # wBitCount(2) | ||
68 | + | ||
69 | + image_io = BytesIO() | ||
70 | + tmp = im.copy() | ||
71 | + tmp.thumbnail(size, Image.LANCZOS) | ||
72 | + tmp.save(image_io, "png") | ||
73 | + image_io.seek(0) | ||
74 | + image_bytes = image_io.read() | ||
75 | + bytes_len = len(image_bytes) | ||
76 | + fp.write(struct.pack("<I", bytes_len)) # dwBytesInRes(4) | ||
77 | + fp.write(struct.pack("<I", offset)) # dwImageOffset(4) | ||
78 | + current = fp.tell() | ||
79 | + fp.seek(offset) | ||
80 | + fp.write(image_bytes) | ||
81 | + offset = offset + bytes_len | ||
82 | + fp.seek(current) | ||
83 | + | ||
84 | + | ||
85 | +def _accept(prefix): | ||
86 | + return prefix[:4] == _MAGIC | ||
87 | + | ||
88 | + | ||
89 | +class IcoFile(object): | ||
90 | + def __init__(self, buf): | ||
91 | + """ | ||
92 | + Parse image from file-like object containing ico file data | ||
93 | + """ | ||
94 | + | ||
95 | + # check magic | ||
96 | + s = buf.read(6) | ||
97 | + if not _accept(s): | ||
98 | + raise SyntaxError("not an ICO file") | ||
99 | + | ||
100 | + self.buf = buf | ||
101 | + self.entry = [] | ||
102 | + | ||
103 | + # Number of items in file | ||
104 | + self.nb_items = i16(s[4:]) | ||
105 | + | ||
106 | + # Get headers for each item | ||
107 | + for i in range(self.nb_items): | ||
108 | + s = buf.read(16) | ||
109 | + | ||
110 | + icon_header = { | ||
111 | + "width": i8(s[0]), | ||
112 | + "height": i8(s[1]), | ||
113 | + "nb_color": i8(s[2]), # No. of colors in image (0 if >=8bpp) | ||
114 | + "reserved": i8(s[3]), | ||
115 | + "planes": i16(s[4:]), | ||
116 | + "bpp": i16(s[6:]), | ||
117 | + "size": i32(s[8:]), | ||
118 | + "offset": i32(s[12:]), | ||
119 | + } | ||
120 | + | ||
121 | + # See Wikipedia | ||
122 | + for j in ("width", "height"): | ||
123 | + if not icon_header[j]: | ||
124 | + icon_header[j] = 256 | ||
125 | + | ||
126 | + # See Wikipedia notes about color depth. | ||
127 | + # We need this just to differ images with equal sizes | ||
128 | + icon_header["color_depth"] = ( | ||
129 | + icon_header["bpp"] | ||
130 | + or ( | ||
131 | + icon_header["nb_color"] != 0 | ||
132 | + and ceil(log(icon_header["nb_color"], 2)) | ||
133 | + ) | ||
134 | + or 256 | ||
135 | + ) | ||
136 | + | ||
137 | + icon_header["dim"] = (icon_header["width"], icon_header["height"]) | ||
138 | + icon_header["square"] = icon_header["width"] * icon_header["height"] | ||
139 | + | ||
140 | + self.entry.append(icon_header) | ||
141 | + | ||
142 | + self.entry = sorted(self.entry, key=lambda x: x["color_depth"]) | ||
143 | + # ICO images are usually squares | ||
144 | + # self.entry = sorted(self.entry, key=lambda x: x['width']) | ||
145 | + self.entry = sorted(self.entry, key=lambda x: x["square"]) | ||
146 | + self.entry.reverse() | ||
147 | + | ||
148 | + def sizes(self): | ||
149 | + """ | ||
150 | + Get a list of all available icon sizes and color depths. | ||
151 | + """ | ||
152 | + return {(h["width"], h["height"]) for h in self.entry} | ||
153 | + | ||
154 | + def getentryindex(self, size, bpp=False): | ||
155 | + for (i, h) in enumerate(self.entry): | ||
156 | + if size == h["dim"] and (bpp is False or bpp == h["color_depth"]): | ||
157 | + return i | ||
158 | + return 0 | ||
159 | + | ||
160 | + def getimage(self, size, bpp=False): | ||
161 | + """ | ||
162 | + Get an image from the icon | ||
163 | + """ | ||
164 | + return self.frame(self.getentryindex(size, bpp)) | ||
165 | + | ||
166 | + def frame(self, idx): | ||
167 | + """ | ||
168 | + Get an image from frame idx | ||
169 | + """ | ||
170 | + | ||
171 | + header = self.entry[idx] | ||
172 | + | ||
173 | + self.buf.seek(header["offset"]) | ||
174 | + data = self.buf.read(8) | ||
175 | + self.buf.seek(header["offset"]) | ||
176 | + | ||
177 | + if data[:8] == PngImagePlugin._MAGIC: | ||
178 | + # png frame | ||
179 | + im = PngImagePlugin.PngImageFile(self.buf) | ||
180 | + else: | ||
181 | + # XOR + AND mask bmp frame | ||
182 | + im = BmpImagePlugin.DibImageFile(self.buf) | ||
183 | + Image._decompression_bomb_check(im.size) | ||
184 | + | ||
185 | + # change tile dimension to only encompass XOR image | ||
186 | + im._size = (im.size[0], int(im.size[1] / 2)) | ||
187 | + d, e, o, a = im.tile[0] | ||
188 | + im.tile[0] = d, (0, 0) + im.size, o, a | ||
189 | + | ||
190 | + # figure out where AND mask image starts | ||
191 | + mode = a[0] | ||
192 | + bpp = 8 | ||
193 | + for k, v in BmpImagePlugin.BIT2MODE.items(): | ||
194 | + if mode == v[1]: | ||
195 | + bpp = k | ||
196 | + break | ||
197 | + | ||
198 | + if 32 == bpp: | ||
199 | + # 32-bit color depth icon image allows semitransparent areas | ||
200 | + # PIL's DIB format ignores transparency bits, recover them. | ||
201 | + # The DIB is packed in BGRX byte order where X is the alpha | ||
202 | + # channel. | ||
203 | + | ||
204 | + # Back up to start of bmp data | ||
205 | + self.buf.seek(o) | ||
206 | + # extract every 4th byte (eg. 3,7,11,15,...) | ||
207 | + alpha_bytes = self.buf.read(im.size[0] * im.size[1] * 4)[3::4] | ||
208 | + | ||
209 | + # convert to an 8bpp grayscale image | ||
210 | + mask = Image.frombuffer( | ||
211 | + "L", # 8bpp | ||
212 | + im.size, # (w, h) | ||
213 | + alpha_bytes, # source chars | ||
214 | + "raw", # raw decoder | ||
215 | + ("L", 0, -1), # 8bpp inverted, unpadded, reversed | ||
216 | + ) | ||
217 | + else: | ||
218 | + # get AND image from end of bitmap | ||
219 | + w = im.size[0] | ||
220 | + if (w % 32) > 0: | ||
221 | + # bitmap row data is aligned to word boundaries | ||
222 | + w += 32 - (im.size[0] % 32) | ||
223 | + | ||
224 | + # the total mask data is | ||
225 | + # padded row size * height / bits per char | ||
226 | + | ||
227 | + and_mask_offset = o + int(im.size[0] * im.size[1] * (bpp / 8.0)) | ||
228 | + total_bytes = int((w * im.size[1]) / 8) | ||
229 | + | ||
230 | + self.buf.seek(and_mask_offset) | ||
231 | + mask_data = self.buf.read(total_bytes) | ||
232 | + | ||
233 | + # convert raw data to image | ||
234 | + mask = Image.frombuffer( | ||
235 | + "1", # 1 bpp | ||
236 | + im.size, # (w, h) | ||
237 | + mask_data, # source chars | ||
238 | + "raw", # raw decoder | ||
239 | + ("1;I", int(w / 8), -1), # 1bpp inverted, padded, reversed | ||
240 | + ) | ||
241 | + | ||
242 | + # now we have two images, im is XOR image and mask is AND image | ||
243 | + | ||
244 | + # apply mask image as alpha channel | ||
245 | + im = im.convert("RGBA") | ||
246 | + im.putalpha(mask) | ||
247 | + | ||
248 | + return im | ||
249 | + | ||
250 | + | ||
251 | +## | ||
252 | +# Image plugin for Windows Icon files. | ||
253 | + | ||
254 | + | ||
255 | +class IcoImageFile(ImageFile.ImageFile): | ||
256 | + """ | ||
257 | + PIL read-only image support for Microsoft Windows .ico files. | ||
258 | + | ||
259 | + By default the largest resolution image in the file will be loaded. This | ||
260 | + can be changed by altering the 'size' attribute before calling 'load'. | ||
261 | + | ||
262 | + The info dictionary has a key 'sizes' that is a list of the sizes available | ||
263 | + in the icon file. | ||
264 | + | ||
265 | + Handles classic, XP and Vista icon formats. | ||
266 | + | ||
267 | + When saving, PNG compression is used. Support for this was only added in | ||
268 | + Windows Vista. | ||
269 | + | ||
270 | + This plugin is a refactored version of Win32IconImagePlugin by Bryan Davis | ||
271 | + <casadebender@gmail.com>. | ||
272 | + https://code.google.com/archive/p/casadebender/wikis/Win32IconImagePlugin.wiki | ||
273 | + """ | ||
274 | + | ||
275 | + format = "ICO" | ||
276 | + format_description = "Windows Icon" | ||
277 | + | ||
278 | + def _open(self): | ||
279 | + self.ico = IcoFile(self.fp) | ||
280 | + self.info["sizes"] = self.ico.sizes() | ||
281 | + self.size = self.ico.entry[0]["dim"] | ||
282 | + self.load() | ||
283 | + | ||
284 | + @property | ||
285 | + def size(self): | ||
286 | + return self._size | ||
287 | + | ||
288 | + @size.setter | ||
289 | + def size(self, value): | ||
290 | + if value not in self.info["sizes"]: | ||
291 | + raise ValueError("This is not one of the allowed sizes of this image") | ||
292 | + self._size = value | ||
293 | + | ||
294 | + def load(self): | ||
295 | + if self.im and self.im.size == self.size: | ||
296 | + # Already loaded | ||
297 | + return | ||
298 | + im = self.ico.getimage(self.size) | ||
299 | + # if tile is PNG, it won't really be loaded yet | ||
300 | + im.load() | ||
301 | + self.im = im.im | ||
302 | + self.mode = im.mode | ||
303 | + if im.size != self.size: | ||
304 | + warnings.warn("Image was not the expected size") | ||
305 | + | ||
306 | + index = self.ico.getentryindex(self.size) | ||
307 | + sizes = list(self.info["sizes"]) | ||
308 | + sizes[index] = im.size | ||
309 | + self.info["sizes"] = set(sizes) | ||
310 | + | ||
311 | + self.size = im.size | ||
312 | + | ||
313 | + def load_seek(self): | ||
314 | + # Flag the ImageFile.Parser so that it | ||
315 | + # just does all the decode at the end. | ||
316 | + pass | ||
317 | + | ||
318 | + | ||
319 | +# | ||
320 | +# -------------------------------------------------------------------- | ||
321 | + | ||
322 | + | ||
323 | +Image.register_open(IcoImageFile.format, IcoImageFile, _accept) | ||
324 | +Image.register_save(IcoImageFile.format, _save) | ||
325 | +Image.register_extension(IcoImageFile.format, ".ico") | ||
326 | + | ||
327 | +Image.register_mime(IcoImageFile.format, "image/x-icon") |
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# standard channel operations | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 1996-03-24 fl Created | ||
9 | +# 1996-08-13 fl Added logical operations (for "1" images) | ||
10 | +# 2000-10-12 fl Added offset method (from Image.py) | ||
11 | +# | ||
12 | +# Copyright (c) 1997-2000 by Secret Labs AB | ||
13 | +# Copyright (c) 1996-2000 by Fredrik Lundh | ||
14 | +# | ||
15 | +# See the README file for information on usage and redistribution. | ||
16 | +# | ||
17 | + | ||
18 | +from . import Image | ||
19 | + | ||
20 | + | ||
21 | +def constant(image, value): | ||
22 | + """Fill a channel with a given grey level. | ||
23 | + | ||
24 | + :rtype: :py:class:`~PIL.Image.Image` | ||
25 | + """ | ||
26 | + | ||
27 | + return Image.new("L", image.size, value) | ||
28 | + | ||
29 | + | ||
30 | +def duplicate(image): | ||
31 | + """Copy a channel. Alias for :py:meth:`PIL.Image.Image.copy`. | ||
32 | + | ||
33 | + :rtype: :py:class:`~PIL.Image.Image` | ||
34 | + """ | ||
35 | + | ||
36 | + return image.copy() | ||
37 | + | ||
38 | + | ||
39 | +def invert(image): | ||
40 | + """ | ||
41 | + Invert an image (channel). | ||
42 | + | ||
43 | + .. code-block:: python | ||
44 | + | ||
45 | + out = MAX - image | ||
46 | + | ||
47 | + :rtype: :py:class:`~PIL.Image.Image` | ||
48 | + """ | ||
49 | + | ||
50 | + image.load() | ||
51 | + return image._new(image.im.chop_invert()) | ||
52 | + | ||
53 | + | ||
54 | +def lighter(image1, image2): | ||
55 | + """ | ||
56 | + Compares the two images, pixel by pixel, and returns a new image containing | ||
57 | + the lighter values. At least one of the images must have mode "1". | ||
58 | + | ||
59 | + .. code-block:: python | ||
60 | + | ||
61 | + out = max(image1, image2) | ||
62 | + | ||
63 | + :rtype: :py:class:`~PIL.Image.Image` | ||
64 | + """ | ||
65 | + | ||
66 | + image1.load() | ||
67 | + image2.load() | ||
68 | + return image1._new(image1.im.chop_lighter(image2.im)) | ||
69 | + | ||
70 | + | ||
71 | +def darker(image1, image2): | ||
72 | + """ | ||
73 | + Compares the two images, pixel by pixel, and returns a new image containing | ||
74 | + the darker values. At least one of the images must have mode "1". | ||
75 | + | ||
76 | + .. code-block:: python | ||
77 | + | ||
78 | + out = min(image1, image2) | ||
79 | + | ||
80 | + :rtype: :py:class:`~PIL.Image.Image` | ||
81 | + """ | ||
82 | + | ||
83 | + image1.load() | ||
84 | + image2.load() | ||
85 | + return image1._new(image1.im.chop_darker(image2.im)) | ||
86 | + | ||
87 | + | ||
88 | +def difference(image1, image2): | ||
89 | + """ | ||
90 | + Returns the absolute value of the pixel-by-pixel difference between the two | ||
91 | + images. At least one of the images must have mode "1". | ||
92 | + | ||
93 | + .. code-block:: python | ||
94 | + | ||
95 | + out = abs(image1 - image2) | ||
96 | + | ||
97 | + :rtype: :py:class:`~PIL.Image.Image` | ||
98 | + """ | ||
99 | + | ||
100 | + image1.load() | ||
101 | + image2.load() | ||
102 | + return image1._new(image1.im.chop_difference(image2.im)) | ||
103 | + | ||
104 | + | ||
105 | +def multiply(image1, image2): | ||
106 | + """ | ||
107 | + Superimposes two images on top of each other. | ||
108 | + | ||
109 | + If you multiply an image with a solid black image, the result is black. If | ||
110 | + you multiply with a solid white image, the image is unaffected. At least | ||
111 | + one of the images must have mode "1". | ||
112 | + | ||
113 | + .. code-block:: python | ||
114 | + | ||
115 | + out = image1 * image2 / MAX | ||
116 | + | ||
117 | + :rtype: :py:class:`~PIL.Image.Image` | ||
118 | + """ | ||
119 | + | ||
120 | + image1.load() | ||
121 | + image2.load() | ||
122 | + return image1._new(image1.im.chop_multiply(image2.im)) | ||
123 | + | ||
124 | + | ||
125 | +def screen(image1, image2): | ||
126 | + """ | ||
127 | + Superimposes two inverted images on top of each other. At least one of the | ||
128 | + images must have mode "1". | ||
129 | + | ||
130 | + .. code-block:: python | ||
131 | + | ||
132 | + out = MAX - ((MAX - image1) * (MAX - image2) / MAX) | ||
133 | + | ||
134 | + :rtype: :py:class:`~PIL.Image.Image` | ||
135 | + """ | ||
136 | + | ||
137 | + image1.load() | ||
138 | + image2.load() | ||
139 | + return image1._new(image1.im.chop_screen(image2.im)) | ||
140 | + | ||
141 | + | ||
142 | +def add(image1, image2, scale=1.0, offset=0): | ||
143 | + """ | ||
144 | + Adds two images, dividing the result by scale and adding the | ||
145 | + offset. If omitted, scale defaults to 1.0, and offset to 0.0. | ||
146 | + At least one of the images must have mode "1". | ||
147 | + | ||
148 | + .. code-block:: python | ||
149 | + | ||
150 | + out = ((image1 + image2) / scale + offset) | ||
151 | + | ||
152 | + :rtype: :py:class:`~PIL.Image.Image` | ||
153 | + """ | ||
154 | + | ||
155 | + image1.load() | ||
156 | + image2.load() | ||
157 | + return image1._new(image1.im.chop_add(image2.im, scale, offset)) | ||
158 | + | ||
159 | + | ||
160 | +def subtract(image1, image2, scale=1.0, offset=0): | ||
161 | + """ | ||
162 | + Subtracts two images, dividing the result by scale and adding the offset. | ||
163 | + If omitted, scale defaults to 1.0, and offset to 0.0. At least one of the | ||
164 | + images must have mode "1". | ||
165 | + | ||
166 | + .. code-block:: python | ||
167 | + | ||
168 | + out = ((image1 - image2) / scale + offset) | ||
169 | + | ||
170 | + :rtype: :py:class:`~PIL.Image.Image` | ||
171 | + """ | ||
172 | + | ||
173 | + image1.load() | ||
174 | + image2.load() | ||
175 | + return image1._new(image1.im.chop_subtract(image2.im, scale, offset)) | ||
176 | + | ||
177 | + | ||
178 | +def add_modulo(image1, image2): | ||
179 | + """Add two images, without clipping the result. At least one of the images | ||
180 | + must have mode "1". | ||
181 | + | ||
182 | + .. code-block:: python | ||
183 | + | ||
184 | + out = ((image1 + image2) % MAX) | ||
185 | + | ||
186 | + :rtype: :py:class:`~PIL.Image.Image` | ||
187 | + """ | ||
188 | + | ||
189 | + image1.load() | ||
190 | + image2.load() | ||
191 | + return image1._new(image1.im.chop_add_modulo(image2.im)) | ||
192 | + | ||
193 | + | ||
194 | +def subtract_modulo(image1, image2): | ||
195 | + """Subtract two images, without clipping the result. At least one of the | ||
196 | + images must have mode "1". | ||
197 | + | ||
198 | + .. code-block:: python | ||
199 | + | ||
200 | + out = ((image1 - image2) % MAX) | ||
201 | + | ||
202 | + :rtype: :py:class:`~PIL.Image.Image` | ||
203 | + """ | ||
204 | + | ||
205 | + image1.load() | ||
206 | + image2.load() | ||
207 | + return image1._new(image1.im.chop_subtract_modulo(image2.im)) | ||
208 | + | ||
209 | + | ||
210 | +def logical_and(image1, image2): | ||
211 | + """Logical AND between two images. At least one of the images must have | ||
212 | + mode "1". | ||
213 | + | ||
214 | + .. code-block:: python | ||
215 | + | ||
216 | + out = ((image1 and image2) % MAX) | ||
217 | + | ||
218 | + :rtype: :py:class:`~PIL.Image.Image` | ||
219 | + """ | ||
220 | + | ||
221 | + image1.load() | ||
222 | + image2.load() | ||
223 | + return image1._new(image1.im.chop_and(image2.im)) | ||
224 | + | ||
225 | + | ||
226 | +def logical_or(image1, image2): | ||
227 | + """Logical OR between two images. At least one of the images must have | ||
228 | + mode "1". | ||
229 | + | ||
230 | + .. code-block:: python | ||
231 | + | ||
232 | + out = ((image1 or image2) % MAX) | ||
233 | + | ||
234 | + :rtype: :py:class:`~PIL.Image.Image` | ||
235 | + """ | ||
236 | + | ||
237 | + image1.load() | ||
238 | + image2.load() | ||
239 | + return image1._new(image1.im.chop_or(image2.im)) | ||
240 | + | ||
241 | + | ||
242 | +def logical_xor(image1, image2): | ||
243 | + """Logical XOR between two images. At least one of the images must have | ||
244 | + mode "1". | ||
245 | + | ||
246 | + .. code-block:: python | ||
247 | + | ||
248 | + out = ((bool(image1) != bool(image2)) % MAX) | ||
249 | + | ||
250 | + :rtype: :py:class:`~PIL.Image.Image` | ||
251 | + """ | ||
252 | + | ||
253 | + image1.load() | ||
254 | + image2.load() | ||
255 | + return image1._new(image1.im.chop_xor(image2.im)) | ||
256 | + | ||
257 | + | ||
258 | +def blend(image1, image2, alpha): | ||
259 | + """Blend images using constant transparency weight. Alias for | ||
260 | + :py:meth:`PIL.Image.Image.blend`. | ||
261 | + | ||
262 | + :rtype: :py:class:`~PIL.Image.Image` | ||
263 | + """ | ||
264 | + | ||
265 | + return Image.blend(image1, image2, alpha) | ||
266 | + | ||
267 | + | ||
268 | +def composite(image1, image2, mask): | ||
269 | + """Create composite using transparency mask. Alias for | ||
270 | + :py:meth:`PIL.Image.Image.composite`. | ||
271 | + | ||
272 | + :rtype: :py:class:`~PIL.Image.Image` | ||
273 | + """ | ||
274 | + | ||
275 | + return Image.composite(image1, image2, mask) | ||
276 | + | ||
277 | + | ||
278 | +def offset(image, xoffset, yoffset=None): | ||
279 | + """Returns a copy of the image where data has been offset by the given | ||
280 | + distances. Data wraps around the edges. If **yoffset** is omitted, it | ||
281 | + is assumed to be equal to **xoffset**. | ||
282 | + | ||
283 | + :param xoffset: The horizontal distance. | ||
284 | + :param yoffset: The vertical distance. If omitted, both | ||
285 | + distances are set to the same value. | ||
286 | + :rtype: :py:class:`~PIL.Image.Image` | ||
287 | + """ | ||
288 | + | ||
289 | + if yoffset is None: | ||
290 | + yoffset = xoffset | ||
291 | + image.load() | ||
292 | + return image._new(image.im.offset(xoffset, yoffset)) |
This diff is collapsed. Click to expand it.
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# map CSS3-style colour description strings to RGB | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 2002-10-24 fl Added support for CSS-style color strings | ||
9 | +# 2002-12-15 fl Added RGBA support | ||
10 | +# 2004-03-27 fl Fixed remaining int() problems for Python 1.5.2 | ||
11 | +# 2004-07-19 fl Fixed gray/grey spelling issues | ||
12 | +# 2009-03-05 fl Fixed rounding error in grayscale calculation | ||
13 | +# | ||
14 | +# Copyright (c) 2002-2004 by Secret Labs AB | ||
15 | +# Copyright (c) 2002-2004 by Fredrik Lundh | ||
16 | +# | ||
17 | +# See the README file for information on usage and redistribution. | ||
18 | +# | ||
19 | + | ||
20 | +import re | ||
21 | + | ||
22 | +from . import Image | ||
23 | + | ||
24 | + | ||
25 | +def getrgb(color): | ||
26 | + """ | ||
27 | + Convert a color string to an RGB tuple. If the string cannot be parsed, | ||
28 | + this function raises a :py:exc:`ValueError` exception. | ||
29 | + | ||
30 | + .. versionadded:: 1.1.4 | ||
31 | + | ||
32 | + :param color: A color string | ||
33 | + :return: ``(red, green, blue[, alpha])`` | ||
34 | + """ | ||
35 | + color = color.lower() | ||
36 | + | ||
37 | + rgb = colormap.get(color, None) | ||
38 | + if rgb: | ||
39 | + if isinstance(rgb, tuple): | ||
40 | + return rgb | ||
41 | + colormap[color] = rgb = getrgb(rgb) | ||
42 | + return rgb | ||
43 | + | ||
44 | + # check for known string formats | ||
45 | + if re.match("#[a-f0-9]{3}$", color): | ||
46 | + return (int(color[1] * 2, 16), int(color[2] * 2, 16), int(color[3] * 2, 16)) | ||
47 | + | ||
48 | + if re.match("#[a-f0-9]{4}$", color): | ||
49 | + return ( | ||
50 | + int(color[1] * 2, 16), | ||
51 | + int(color[2] * 2, 16), | ||
52 | + int(color[3] * 2, 16), | ||
53 | + int(color[4] * 2, 16), | ||
54 | + ) | ||
55 | + | ||
56 | + if re.match("#[a-f0-9]{6}$", color): | ||
57 | + return (int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16)) | ||
58 | + | ||
59 | + if re.match("#[a-f0-9]{8}$", color): | ||
60 | + return ( | ||
61 | + int(color[1:3], 16), | ||
62 | + int(color[3:5], 16), | ||
63 | + int(color[5:7], 16), | ||
64 | + int(color[7:9], 16), | ||
65 | + ) | ||
66 | + | ||
67 | + m = re.match(r"rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color) | ||
68 | + if m: | ||
69 | + return (int(m.group(1)), int(m.group(2)), int(m.group(3))) | ||
70 | + | ||
71 | + m = re.match(r"rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color) | ||
72 | + if m: | ||
73 | + return ( | ||
74 | + int((int(m.group(1)) * 255) / 100.0 + 0.5), | ||
75 | + int((int(m.group(2)) * 255) / 100.0 + 0.5), | ||
76 | + int((int(m.group(3)) * 255) / 100.0 + 0.5), | ||
77 | + ) | ||
78 | + | ||
79 | + m = re.match( | ||
80 | + r"hsl\(\s*(\d+\.?\d*)\s*,\s*(\d+\.?\d*)%\s*,\s*(\d+\.?\d*)%\s*\)$", color | ||
81 | + ) | ||
82 | + if m: | ||
83 | + from colorsys import hls_to_rgb | ||
84 | + | ||
85 | + rgb = hls_to_rgb( | ||
86 | + float(m.group(1)) / 360.0, | ||
87 | + float(m.group(3)) / 100.0, | ||
88 | + float(m.group(2)) / 100.0, | ||
89 | + ) | ||
90 | + return ( | ||
91 | + int(rgb[0] * 255 + 0.5), | ||
92 | + int(rgb[1] * 255 + 0.5), | ||
93 | + int(rgb[2] * 255 + 0.5), | ||
94 | + ) | ||
95 | + | ||
96 | + m = re.match( | ||
97 | + r"hs[bv]\(\s*(\d+\.?\d*)\s*,\s*(\d+\.?\d*)%\s*,\s*(\d+\.?\d*)%\s*\)$", color | ||
98 | + ) | ||
99 | + if m: | ||
100 | + from colorsys import hsv_to_rgb | ||
101 | + | ||
102 | + rgb = hsv_to_rgb( | ||
103 | + float(m.group(1)) / 360.0, | ||
104 | + float(m.group(2)) / 100.0, | ||
105 | + float(m.group(3)) / 100.0, | ||
106 | + ) | ||
107 | + return ( | ||
108 | + int(rgb[0] * 255 + 0.5), | ||
109 | + int(rgb[1] * 255 + 0.5), | ||
110 | + int(rgb[2] * 255 + 0.5), | ||
111 | + ) | ||
112 | + | ||
113 | + m = re.match(r"rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color) | ||
114 | + if m: | ||
115 | + return (int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(4))) | ||
116 | + raise ValueError("unknown color specifier: %r" % color) | ||
117 | + | ||
118 | + | ||
119 | +def getcolor(color, mode): | ||
120 | + """ | ||
121 | + Same as :py:func:`~PIL.ImageColor.getrgb`, but converts the RGB value to a | ||
122 | + greyscale value if the mode is not color or a palette image. If the string | ||
123 | + cannot be parsed, this function raises a :py:exc:`ValueError` exception. | ||
124 | + | ||
125 | + .. versionadded:: 1.1.4 | ||
126 | + | ||
127 | + :param color: A color string | ||
128 | + :return: ``(graylevel [, alpha]) or (red, green, blue[, alpha])`` | ||
129 | + """ | ||
130 | + # same as getrgb, but converts the result to the given mode | ||
131 | + color, alpha = getrgb(color), 255 | ||
132 | + if len(color) == 4: | ||
133 | + color, alpha = color[0:3], color[3] | ||
134 | + | ||
135 | + if Image.getmodebase(mode) == "L": | ||
136 | + r, g, b = color | ||
137 | + color = (r * 299 + g * 587 + b * 114) // 1000 | ||
138 | + if mode[-1] == "A": | ||
139 | + return (color, alpha) | ||
140 | + else: | ||
141 | + if mode[-1] == "A": | ||
142 | + return color + (alpha,) | ||
143 | + return color | ||
144 | + | ||
145 | + | ||
146 | +colormap = { | ||
147 | + # X11 colour table from https://drafts.csswg.org/css-color-4/, with | ||
148 | + # gray/grey spelling issues fixed. This is a superset of HTML 4.0 | ||
149 | + # colour names used in CSS 1. | ||
150 | + "aliceblue": "#f0f8ff", | ||
151 | + "antiquewhite": "#faebd7", | ||
152 | + "aqua": "#00ffff", | ||
153 | + "aquamarine": "#7fffd4", | ||
154 | + "azure": "#f0ffff", | ||
155 | + "beige": "#f5f5dc", | ||
156 | + "bisque": "#ffe4c4", | ||
157 | + "black": "#000000", | ||
158 | + "blanchedalmond": "#ffebcd", | ||
159 | + "blue": "#0000ff", | ||
160 | + "blueviolet": "#8a2be2", | ||
161 | + "brown": "#a52a2a", | ||
162 | + "burlywood": "#deb887", | ||
163 | + "cadetblue": "#5f9ea0", | ||
164 | + "chartreuse": "#7fff00", | ||
165 | + "chocolate": "#d2691e", | ||
166 | + "coral": "#ff7f50", | ||
167 | + "cornflowerblue": "#6495ed", | ||
168 | + "cornsilk": "#fff8dc", | ||
169 | + "crimson": "#dc143c", | ||
170 | + "cyan": "#00ffff", | ||
171 | + "darkblue": "#00008b", | ||
172 | + "darkcyan": "#008b8b", | ||
173 | + "darkgoldenrod": "#b8860b", | ||
174 | + "darkgray": "#a9a9a9", | ||
175 | + "darkgrey": "#a9a9a9", | ||
176 | + "darkgreen": "#006400", | ||
177 | + "darkkhaki": "#bdb76b", | ||
178 | + "darkmagenta": "#8b008b", | ||
179 | + "darkolivegreen": "#556b2f", | ||
180 | + "darkorange": "#ff8c00", | ||
181 | + "darkorchid": "#9932cc", | ||
182 | + "darkred": "#8b0000", | ||
183 | + "darksalmon": "#e9967a", | ||
184 | + "darkseagreen": "#8fbc8f", | ||
185 | + "darkslateblue": "#483d8b", | ||
186 | + "darkslategray": "#2f4f4f", | ||
187 | + "darkslategrey": "#2f4f4f", | ||
188 | + "darkturquoise": "#00ced1", | ||
189 | + "darkviolet": "#9400d3", | ||
190 | + "deeppink": "#ff1493", | ||
191 | + "deepskyblue": "#00bfff", | ||
192 | + "dimgray": "#696969", | ||
193 | + "dimgrey": "#696969", | ||
194 | + "dodgerblue": "#1e90ff", | ||
195 | + "firebrick": "#b22222", | ||
196 | + "floralwhite": "#fffaf0", | ||
197 | + "forestgreen": "#228b22", | ||
198 | + "fuchsia": "#ff00ff", | ||
199 | + "gainsboro": "#dcdcdc", | ||
200 | + "ghostwhite": "#f8f8ff", | ||
201 | + "gold": "#ffd700", | ||
202 | + "goldenrod": "#daa520", | ||
203 | + "gray": "#808080", | ||
204 | + "grey": "#808080", | ||
205 | + "green": "#008000", | ||
206 | + "greenyellow": "#adff2f", | ||
207 | + "honeydew": "#f0fff0", | ||
208 | + "hotpink": "#ff69b4", | ||
209 | + "indianred": "#cd5c5c", | ||
210 | + "indigo": "#4b0082", | ||
211 | + "ivory": "#fffff0", | ||
212 | + "khaki": "#f0e68c", | ||
213 | + "lavender": "#e6e6fa", | ||
214 | + "lavenderblush": "#fff0f5", | ||
215 | + "lawngreen": "#7cfc00", | ||
216 | + "lemonchiffon": "#fffacd", | ||
217 | + "lightblue": "#add8e6", | ||
218 | + "lightcoral": "#f08080", | ||
219 | + "lightcyan": "#e0ffff", | ||
220 | + "lightgoldenrodyellow": "#fafad2", | ||
221 | + "lightgreen": "#90ee90", | ||
222 | + "lightgray": "#d3d3d3", | ||
223 | + "lightgrey": "#d3d3d3", | ||
224 | + "lightpink": "#ffb6c1", | ||
225 | + "lightsalmon": "#ffa07a", | ||
226 | + "lightseagreen": "#20b2aa", | ||
227 | + "lightskyblue": "#87cefa", | ||
228 | + "lightslategray": "#778899", | ||
229 | + "lightslategrey": "#778899", | ||
230 | + "lightsteelblue": "#b0c4de", | ||
231 | + "lightyellow": "#ffffe0", | ||
232 | + "lime": "#00ff00", | ||
233 | + "limegreen": "#32cd32", | ||
234 | + "linen": "#faf0e6", | ||
235 | + "magenta": "#ff00ff", | ||
236 | + "maroon": "#800000", | ||
237 | + "mediumaquamarine": "#66cdaa", | ||
238 | + "mediumblue": "#0000cd", | ||
239 | + "mediumorchid": "#ba55d3", | ||
240 | + "mediumpurple": "#9370db", | ||
241 | + "mediumseagreen": "#3cb371", | ||
242 | + "mediumslateblue": "#7b68ee", | ||
243 | + "mediumspringgreen": "#00fa9a", | ||
244 | + "mediumturquoise": "#48d1cc", | ||
245 | + "mediumvioletred": "#c71585", | ||
246 | + "midnightblue": "#191970", | ||
247 | + "mintcream": "#f5fffa", | ||
248 | + "mistyrose": "#ffe4e1", | ||
249 | + "moccasin": "#ffe4b5", | ||
250 | + "navajowhite": "#ffdead", | ||
251 | + "navy": "#000080", | ||
252 | + "oldlace": "#fdf5e6", | ||
253 | + "olive": "#808000", | ||
254 | + "olivedrab": "#6b8e23", | ||
255 | + "orange": "#ffa500", | ||
256 | + "orangered": "#ff4500", | ||
257 | + "orchid": "#da70d6", | ||
258 | + "palegoldenrod": "#eee8aa", | ||
259 | + "palegreen": "#98fb98", | ||
260 | + "paleturquoise": "#afeeee", | ||
261 | + "palevioletred": "#db7093", | ||
262 | + "papayawhip": "#ffefd5", | ||
263 | + "peachpuff": "#ffdab9", | ||
264 | + "peru": "#cd853f", | ||
265 | + "pink": "#ffc0cb", | ||
266 | + "plum": "#dda0dd", | ||
267 | + "powderblue": "#b0e0e6", | ||
268 | + "purple": "#800080", | ||
269 | + "rebeccapurple": "#663399", | ||
270 | + "red": "#ff0000", | ||
271 | + "rosybrown": "#bc8f8f", | ||
272 | + "royalblue": "#4169e1", | ||
273 | + "saddlebrown": "#8b4513", | ||
274 | + "salmon": "#fa8072", | ||
275 | + "sandybrown": "#f4a460", | ||
276 | + "seagreen": "#2e8b57", | ||
277 | + "seashell": "#fff5ee", | ||
278 | + "sienna": "#a0522d", | ||
279 | + "silver": "#c0c0c0", | ||
280 | + "skyblue": "#87ceeb", | ||
281 | + "slateblue": "#6a5acd", | ||
282 | + "slategray": "#708090", | ||
283 | + "slategrey": "#708090", | ||
284 | + "snow": "#fffafa", | ||
285 | + "springgreen": "#00ff7f", | ||
286 | + "steelblue": "#4682b4", | ||
287 | + "tan": "#d2b48c", | ||
288 | + "teal": "#008080", | ||
289 | + "thistle": "#d8bfd8", | ||
290 | + "tomato": "#ff6347", | ||
291 | + "turquoise": "#40e0d0", | ||
292 | + "violet": "#ee82ee", | ||
293 | + "wheat": "#f5deb3", | ||
294 | + "white": "#ffffff", | ||
295 | + "whitesmoke": "#f5f5f5", | ||
296 | + "yellow": "#ffff00", | ||
297 | + "yellowgreen": "#9acd32", | ||
298 | +} |
This diff is collapsed. Click to expand it.
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# WCK-style drawing interface operations | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 2003-12-07 fl created | ||
9 | +# 2005-05-15 fl updated; added to PIL as ImageDraw2 | ||
10 | +# 2005-05-15 fl added text support | ||
11 | +# 2005-05-20 fl added arc/chord/pieslice support | ||
12 | +# | ||
13 | +# Copyright (c) 2003-2005 by Secret Labs AB | ||
14 | +# Copyright (c) 2003-2005 by Fredrik Lundh | ||
15 | +# | ||
16 | +# See the README file for information on usage and redistribution. | ||
17 | +# | ||
18 | + | ||
19 | +from . import Image, ImageColor, ImageDraw, ImageFont, ImagePath | ||
20 | + | ||
21 | + | ||
22 | +class Pen(object): | ||
23 | + def __init__(self, color, width=1, opacity=255): | ||
24 | + self.color = ImageColor.getrgb(color) | ||
25 | + self.width = width | ||
26 | + | ||
27 | + | ||
28 | +class Brush(object): | ||
29 | + def __init__(self, color, opacity=255): | ||
30 | + self.color = ImageColor.getrgb(color) | ||
31 | + | ||
32 | + | ||
33 | +class Font(object): | ||
34 | + def __init__(self, color, file, size=12): | ||
35 | + # FIXME: add support for bitmap fonts | ||
36 | + self.color = ImageColor.getrgb(color) | ||
37 | + self.font = ImageFont.truetype(file, size) | ||
38 | + | ||
39 | + | ||
40 | +class Draw(object): | ||
41 | + def __init__(self, image, size=None, color=None): | ||
42 | + if not hasattr(image, "im"): | ||
43 | + image = Image.new(image, size, color) | ||
44 | + self.draw = ImageDraw.Draw(image) | ||
45 | + self.image = image | ||
46 | + self.transform = None | ||
47 | + | ||
48 | + def flush(self): | ||
49 | + return self.image | ||
50 | + | ||
51 | + def render(self, op, xy, pen, brush=None): | ||
52 | + # handle color arguments | ||
53 | + outline = fill = None | ||
54 | + width = 1 | ||
55 | + if isinstance(pen, Pen): | ||
56 | + outline = pen.color | ||
57 | + width = pen.width | ||
58 | + elif isinstance(brush, Pen): | ||
59 | + outline = brush.color | ||
60 | + width = brush.width | ||
61 | + if isinstance(brush, Brush): | ||
62 | + fill = brush.color | ||
63 | + elif isinstance(pen, Brush): | ||
64 | + fill = pen.color | ||
65 | + # handle transformation | ||
66 | + if self.transform: | ||
67 | + xy = ImagePath.Path(xy) | ||
68 | + xy.transform(self.transform) | ||
69 | + # render the item | ||
70 | + if op == "line": | ||
71 | + self.draw.line(xy, fill=outline, width=width) | ||
72 | + else: | ||
73 | + getattr(self.draw, op)(xy, fill=fill, outline=outline) | ||
74 | + | ||
75 | + def settransform(self, offset): | ||
76 | + (xoffset, yoffset) = offset | ||
77 | + self.transform = (1, 0, xoffset, 0, 1, yoffset) | ||
78 | + | ||
79 | + def arc(self, xy, start, end, *options): | ||
80 | + self.render("arc", xy, start, end, *options) | ||
81 | + | ||
82 | + def chord(self, xy, start, end, *options): | ||
83 | + self.render("chord", xy, start, end, *options) | ||
84 | + | ||
85 | + def ellipse(self, xy, *options): | ||
86 | + self.render("ellipse", xy, *options) | ||
87 | + | ||
88 | + def line(self, xy, *options): | ||
89 | + self.render("line", xy, *options) | ||
90 | + | ||
91 | + def pieslice(self, xy, start, end, *options): | ||
92 | + self.render("pieslice", xy, start, end, *options) | ||
93 | + | ||
94 | + def polygon(self, xy, *options): | ||
95 | + self.render("polygon", xy, *options) | ||
96 | + | ||
97 | + def rectangle(self, xy, *options): | ||
98 | + self.render("rectangle", xy, *options) | ||
99 | + | ||
100 | + def text(self, xy, text, font): | ||
101 | + if self.transform: | ||
102 | + xy = ImagePath.Path(xy) | ||
103 | + xy.transform(self.transform) | ||
104 | + self.draw.text(xy, text, font=font.font, fill=font.color) | ||
105 | + | ||
106 | + def textsize(self, text, font): | ||
107 | + return self.draw.textsize(text, font=font.font) |
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# image enhancement classes | ||
6 | +# | ||
7 | +# For a background, see "Image Processing By Interpolation and | ||
8 | +# Extrapolation", Paul Haeberli and Douglas Voorhies. Available | ||
9 | +# at http://www.graficaobscura.com/interp/index.html | ||
10 | +# | ||
11 | +# History: | ||
12 | +# 1996-03-23 fl Created | ||
13 | +# 2009-06-16 fl Fixed mean calculation | ||
14 | +# | ||
15 | +# Copyright (c) Secret Labs AB 1997. | ||
16 | +# Copyright (c) Fredrik Lundh 1996. | ||
17 | +# | ||
18 | +# See the README file for information on usage and redistribution. | ||
19 | +# | ||
20 | + | ||
21 | +from . import Image, ImageFilter, ImageStat | ||
22 | + | ||
23 | + | ||
24 | +class _Enhance(object): | ||
25 | + def enhance(self, factor): | ||
26 | + """ | ||
27 | + Returns an enhanced image. | ||
28 | + | ||
29 | + :param factor: A floating point value controlling the enhancement. | ||
30 | + Factor 1.0 always returns a copy of the original image, | ||
31 | + lower factors mean less color (brightness, contrast, | ||
32 | + etc), and higher values more. There are no restrictions | ||
33 | + on this value. | ||
34 | + :rtype: :py:class:`~PIL.Image.Image` | ||
35 | + """ | ||
36 | + return Image.blend(self.degenerate, self.image, factor) | ||
37 | + | ||
38 | + | ||
39 | +class Color(_Enhance): | ||
40 | + """Adjust image color balance. | ||
41 | + | ||
42 | + This class can be used to adjust the colour balance of an image, in | ||
43 | + a manner similar to the controls on a colour TV set. An enhancement | ||
44 | + factor of 0.0 gives a black and white image. A factor of 1.0 gives | ||
45 | + the original image. | ||
46 | + """ | ||
47 | + | ||
48 | + def __init__(self, image): | ||
49 | + self.image = image | ||
50 | + self.intermediate_mode = "L" | ||
51 | + if "A" in image.getbands(): | ||
52 | + self.intermediate_mode = "LA" | ||
53 | + | ||
54 | + self.degenerate = image.convert(self.intermediate_mode).convert(image.mode) | ||
55 | + | ||
56 | + | ||
57 | +class Contrast(_Enhance): | ||
58 | + """Adjust image contrast. | ||
59 | + | ||
60 | + This class can be used to control the contrast of an image, similar | ||
61 | + to the contrast control on a TV set. An enhancement factor of 0.0 | ||
62 | + gives a solid grey image. A factor of 1.0 gives the original image. | ||
63 | + """ | ||
64 | + | ||
65 | + def __init__(self, image): | ||
66 | + self.image = image | ||
67 | + mean = int(ImageStat.Stat(image.convert("L")).mean[0] + 0.5) | ||
68 | + self.degenerate = Image.new("L", image.size, mean).convert(image.mode) | ||
69 | + | ||
70 | + if "A" in image.getbands(): | ||
71 | + self.degenerate.putalpha(image.getchannel("A")) | ||
72 | + | ||
73 | + | ||
74 | +class Brightness(_Enhance): | ||
75 | + """Adjust image brightness. | ||
76 | + | ||
77 | + This class can be used to control the brightness of an image. An | ||
78 | + enhancement factor of 0.0 gives a black image. A factor of 1.0 gives the | ||
79 | + original image. | ||
80 | + """ | ||
81 | + | ||
82 | + def __init__(self, image): | ||
83 | + self.image = image | ||
84 | + self.degenerate = Image.new(image.mode, image.size, 0) | ||
85 | + | ||
86 | + if "A" in image.getbands(): | ||
87 | + self.degenerate.putalpha(image.getchannel("A")) | ||
88 | + | ||
89 | + | ||
90 | +class Sharpness(_Enhance): | ||
91 | + """Adjust image sharpness. | ||
92 | + | ||
93 | + This class can be used to adjust the sharpness of an image. An | ||
94 | + enhancement factor of 0.0 gives a blurred image, a factor of 1.0 gives the | ||
95 | + original image, and a factor of 2.0 gives a sharpened image. | ||
96 | + """ | ||
97 | + | ||
98 | + def __init__(self, image): | ||
99 | + self.image = image | ||
100 | + self.degenerate = image.filter(ImageFilter.SMOOTH) | ||
101 | + | ||
102 | + if "A" in image.getbands(): | ||
103 | + self.degenerate.putalpha(image.getchannel("A")) |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# screen grabber (macOS and Windows only) | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 2001-04-26 fl created | ||
9 | +# 2001-09-17 fl use builtin driver, if present | ||
10 | +# 2002-11-19 fl added grabclipboard support | ||
11 | +# | ||
12 | +# Copyright (c) 2001-2002 by Secret Labs AB | ||
13 | +# Copyright (c) 2001-2002 by Fredrik Lundh | ||
14 | +# | ||
15 | +# See the README file for information on usage and redistribution. | ||
16 | +# | ||
17 | + | ||
18 | +import sys | ||
19 | + | ||
20 | +from . import Image | ||
21 | + | ||
22 | +if sys.platform == "win32": | ||
23 | + grabber = Image.core.grabscreen | ||
24 | +elif sys.platform == "darwin": | ||
25 | + import os | ||
26 | + import tempfile | ||
27 | + import subprocess | ||
28 | +else: | ||
29 | + raise ImportError("ImageGrab is macOS and Windows only") | ||
30 | + | ||
31 | + | ||
32 | +def grab(bbox=None, include_layered_windows=False, all_screens=False): | ||
33 | + if sys.platform == "darwin": | ||
34 | + fh, filepath = tempfile.mkstemp(".png") | ||
35 | + os.close(fh) | ||
36 | + subprocess.call(["screencapture", "-x", filepath]) | ||
37 | + im = Image.open(filepath) | ||
38 | + im.load() | ||
39 | + os.unlink(filepath) | ||
40 | + if bbox: | ||
41 | + im = im.crop(bbox) | ||
42 | + else: | ||
43 | + offset, size, data = grabber(include_layered_windows, all_screens) | ||
44 | + im = Image.frombytes( | ||
45 | + "RGB", | ||
46 | + size, | ||
47 | + data, | ||
48 | + # RGB, 32-bit line padding, origin lower left corner | ||
49 | + "raw", | ||
50 | + "BGR", | ||
51 | + (size[0] * 3 + 3) & -4, | ||
52 | + -1, | ||
53 | + ) | ||
54 | + if bbox: | ||
55 | + x0, y0 = offset | ||
56 | + left, top, right, bottom = bbox | ||
57 | + im = im.crop((left - x0, top - y0, right - x0, bottom - y0)) | ||
58 | + return im | ||
59 | + | ||
60 | + | ||
61 | +def grabclipboard(): | ||
62 | + if sys.platform == "darwin": | ||
63 | + fh, filepath = tempfile.mkstemp(".jpg") | ||
64 | + os.close(fh) | ||
65 | + commands = [ | ||
66 | + 'set theFile to (open for access POSIX file "' | ||
67 | + + filepath | ||
68 | + + '" with write permission)', | ||
69 | + "try", | ||
70 | + " write (the clipboard as JPEG picture) to theFile", | ||
71 | + "end try", | ||
72 | + "close access theFile", | ||
73 | + ] | ||
74 | + script = ["osascript"] | ||
75 | + for command in commands: | ||
76 | + script += ["-e", command] | ||
77 | + subprocess.call(script) | ||
78 | + | ||
79 | + im = None | ||
80 | + if os.stat(filepath).st_size != 0: | ||
81 | + im = Image.open(filepath) | ||
82 | + im.load() | ||
83 | + os.unlink(filepath) | ||
84 | + return im | ||
85 | + else: | ||
86 | + data = Image.core.grabclipboard() | ||
87 | + if isinstance(data, bytes): | ||
88 | + from . import BmpImagePlugin | ||
89 | + import io | ||
90 | + | ||
91 | + return BmpImagePlugin.DibImageFile(io.BytesIO(data)) | ||
92 | + return data |
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# a simple math add-on for the Python Imaging Library | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 1999-02-15 fl Original PIL Plus release | ||
9 | +# 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6 | ||
10 | +# 2005-09-12 fl Fixed int() and float() for Python 2.4.1 | ||
11 | +# | ||
12 | +# Copyright (c) 1999-2005 by Secret Labs AB | ||
13 | +# Copyright (c) 2005 by Fredrik Lundh | ||
14 | +# | ||
15 | +# See the README file for information on usage and redistribution. | ||
16 | +# | ||
17 | + | ||
18 | +from . import Image, _imagingmath | ||
19 | +from ._util import py3 | ||
20 | + | ||
21 | +try: | ||
22 | + import builtins | ||
23 | +except ImportError: | ||
24 | + import __builtin__ | ||
25 | + | ||
26 | + builtins = __builtin__ | ||
27 | + | ||
28 | +VERBOSE = 0 | ||
29 | + | ||
30 | + | ||
31 | +def _isconstant(v): | ||
32 | + return isinstance(v, (int, float)) | ||
33 | + | ||
34 | + | ||
35 | +class _Operand(object): | ||
36 | + """Wraps an image operand, providing standard operators""" | ||
37 | + | ||
38 | + def __init__(self, im): | ||
39 | + self.im = im | ||
40 | + | ||
41 | + def __fixup(self, im1): | ||
42 | + # convert image to suitable mode | ||
43 | + if isinstance(im1, _Operand): | ||
44 | + # argument was an image. | ||
45 | + if im1.im.mode in ("1", "L"): | ||
46 | + return im1.im.convert("I") | ||
47 | + elif im1.im.mode in ("I", "F"): | ||
48 | + return im1.im | ||
49 | + else: | ||
50 | + raise ValueError("unsupported mode: %s" % im1.im.mode) | ||
51 | + else: | ||
52 | + # argument was a constant | ||
53 | + if _isconstant(im1) and self.im.mode in ("1", "L", "I"): | ||
54 | + return Image.new("I", self.im.size, im1) | ||
55 | + else: | ||
56 | + return Image.new("F", self.im.size, im1) | ||
57 | + | ||
58 | + def apply(self, op, im1, im2=None, mode=None): | ||
59 | + im1 = self.__fixup(im1) | ||
60 | + if im2 is None: | ||
61 | + # unary operation | ||
62 | + out = Image.new(mode or im1.mode, im1.size, None) | ||
63 | + im1.load() | ||
64 | + try: | ||
65 | + op = getattr(_imagingmath, op + "_" + im1.mode) | ||
66 | + except AttributeError: | ||
67 | + raise TypeError("bad operand type for '%s'" % op) | ||
68 | + _imagingmath.unop(op, out.im.id, im1.im.id) | ||
69 | + else: | ||
70 | + # binary operation | ||
71 | + im2 = self.__fixup(im2) | ||
72 | + if im1.mode != im2.mode: | ||
73 | + # convert both arguments to floating point | ||
74 | + if im1.mode != "F": | ||
75 | + im1 = im1.convert("F") | ||
76 | + if im2.mode != "F": | ||
77 | + im2 = im2.convert("F") | ||
78 | + if im1.mode != im2.mode: | ||
79 | + raise ValueError("mode mismatch") | ||
80 | + if im1.size != im2.size: | ||
81 | + # crop both arguments to a common size | ||
82 | + size = (min(im1.size[0], im2.size[0]), min(im1.size[1], im2.size[1])) | ||
83 | + if im1.size != size: | ||
84 | + im1 = im1.crop((0, 0) + size) | ||
85 | + if im2.size != size: | ||
86 | + im2 = im2.crop((0, 0) + size) | ||
87 | + out = Image.new(mode or im1.mode, size, None) | ||
88 | + else: | ||
89 | + out = Image.new(mode or im1.mode, im1.size, None) | ||
90 | + im1.load() | ||
91 | + im2.load() | ||
92 | + try: | ||
93 | + op = getattr(_imagingmath, op + "_" + im1.mode) | ||
94 | + except AttributeError: | ||
95 | + raise TypeError("bad operand type for '%s'" % op) | ||
96 | + _imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id) | ||
97 | + return _Operand(out) | ||
98 | + | ||
99 | + # unary operators | ||
100 | + def __bool__(self): | ||
101 | + # an image is "true" if it contains at least one non-zero pixel | ||
102 | + return self.im.getbbox() is not None | ||
103 | + | ||
104 | + if not py3: | ||
105 | + # Provide __nonzero__ for pre-Py3k | ||
106 | + __nonzero__ = __bool__ | ||
107 | + del __bool__ | ||
108 | + | ||
109 | + def __abs__(self): | ||
110 | + return self.apply("abs", self) | ||
111 | + | ||
112 | + def __pos__(self): | ||
113 | + return self | ||
114 | + | ||
115 | + def __neg__(self): | ||
116 | + return self.apply("neg", self) | ||
117 | + | ||
118 | + # binary operators | ||
119 | + def __add__(self, other): | ||
120 | + return self.apply("add", self, other) | ||
121 | + | ||
122 | + def __radd__(self, other): | ||
123 | + return self.apply("add", other, self) | ||
124 | + | ||
125 | + def __sub__(self, other): | ||
126 | + return self.apply("sub", self, other) | ||
127 | + | ||
128 | + def __rsub__(self, other): | ||
129 | + return self.apply("sub", other, self) | ||
130 | + | ||
131 | + def __mul__(self, other): | ||
132 | + return self.apply("mul", self, other) | ||
133 | + | ||
134 | + def __rmul__(self, other): | ||
135 | + return self.apply("mul", other, self) | ||
136 | + | ||
137 | + def __truediv__(self, other): | ||
138 | + return self.apply("div", self, other) | ||
139 | + | ||
140 | + def __rtruediv__(self, other): | ||
141 | + return self.apply("div", other, self) | ||
142 | + | ||
143 | + def __mod__(self, other): | ||
144 | + return self.apply("mod", self, other) | ||
145 | + | ||
146 | + def __rmod__(self, other): | ||
147 | + return self.apply("mod", other, self) | ||
148 | + | ||
149 | + def __pow__(self, other): | ||
150 | + return self.apply("pow", self, other) | ||
151 | + | ||
152 | + def __rpow__(self, other): | ||
153 | + return self.apply("pow", other, self) | ||
154 | + | ||
155 | + if not py3: | ||
156 | + # Provide __div__ and __rdiv__ for pre-Py3k | ||
157 | + __div__ = __truediv__ | ||
158 | + __rdiv__ = __rtruediv__ | ||
159 | + del __truediv__ | ||
160 | + del __rtruediv__ | ||
161 | + | ||
162 | + # bitwise | ||
163 | + def __invert__(self): | ||
164 | + return self.apply("invert", self) | ||
165 | + | ||
166 | + def __and__(self, other): | ||
167 | + return self.apply("and", self, other) | ||
168 | + | ||
169 | + def __rand__(self, other): | ||
170 | + return self.apply("and", other, self) | ||
171 | + | ||
172 | + def __or__(self, other): | ||
173 | + return self.apply("or", self, other) | ||
174 | + | ||
175 | + def __ror__(self, other): | ||
176 | + return self.apply("or", other, self) | ||
177 | + | ||
178 | + def __xor__(self, other): | ||
179 | + return self.apply("xor", self, other) | ||
180 | + | ||
181 | + def __rxor__(self, other): | ||
182 | + return self.apply("xor", other, self) | ||
183 | + | ||
184 | + def __lshift__(self, other): | ||
185 | + return self.apply("lshift", self, other) | ||
186 | + | ||
187 | + def __rshift__(self, other): | ||
188 | + return self.apply("rshift", self, other) | ||
189 | + | ||
190 | + # logical | ||
191 | + def __eq__(self, other): | ||
192 | + return self.apply("eq", self, other) | ||
193 | + | ||
194 | + def __ne__(self, other): | ||
195 | + return self.apply("ne", self, other) | ||
196 | + | ||
197 | + def __lt__(self, other): | ||
198 | + return self.apply("lt", self, other) | ||
199 | + | ||
200 | + def __le__(self, other): | ||
201 | + return self.apply("le", self, other) | ||
202 | + | ||
203 | + def __gt__(self, other): | ||
204 | + return self.apply("gt", self, other) | ||
205 | + | ||
206 | + def __ge__(self, other): | ||
207 | + return self.apply("ge", self, other) | ||
208 | + | ||
209 | + | ||
210 | +# conversions | ||
211 | +def imagemath_int(self): | ||
212 | + return _Operand(self.im.convert("I")) | ||
213 | + | ||
214 | + | ||
215 | +def imagemath_float(self): | ||
216 | + return _Operand(self.im.convert("F")) | ||
217 | + | ||
218 | + | ||
219 | +# logical | ||
220 | +def imagemath_equal(self, other): | ||
221 | + return self.apply("eq", self, other, mode="I") | ||
222 | + | ||
223 | + | ||
224 | +def imagemath_notequal(self, other): | ||
225 | + return self.apply("ne", self, other, mode="I") | ||
226 | + | ||
227 | + | ||
228 | +def imagemath_min(self, other): | ||
229 | + return self.apply("min", self, other) | ||
230 | + | ||
231 | + | ||
232 | +def imagemath_max(self, other): | ||
233 | + return self.apply("max", self, other) | ||
234 | + | ||
235 | + | ||
236 | +def imagemath_convert(self, mode): | ||
237 | + return _Operand(self.im.convert(mode)) | ||
238 | + | ||
239 | + | ||
240 | +ops = {} | ||
241 | +for k, v in list(globals().items()): | ||
242 | + if k[:10] == "imagemath_": | ||
243 | + ops[k[10:]] = v | ||
244 | + | ||
245 | + | ||
246 | +def eval(expression, _dict={}, **kw): | ||
247 | + """ | ||
248 | + Evaluates an image expression. | ||
249 | + | ||
250 | + :param expression: A string containing a Python-style expression. | ||
251 | + :param options: Values to add to the evaluation context. You | ||
252 | + can either use a dictionary, or one or more keyword | ||
253 | + arguments. | ||
254 | + :return: The evaluated expression. This is usually an image object, but can | ||
255 | + also be an integer, a floating point value, or a pixel tuple, | ||
256 | + depending on the expression. | ||
257 | + """ | ||
258 | + | ||
259 | + # build execution namespace | ||
260 | + args = ops.copy() | ||
261 | + args.update(_dict) | ||
262 | + args.update(kw) | ||
263 | + for k, v in list(args.items()): | ||
264 | + if hasattr(v, "im"): | ||
265 | + args[k] = _Operand(v) | ||
266 | + | ||
267 | + out = builtins.eval(expression, args) | ||
268 | + try: | ||
269 | + return out.im | ||
270 | + except AttributeError: | ||
271 | + return out |
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# standard mode descriptors | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 2006-03-20 fl Added | ||
9 | +# | ||
10 | +# Copyright (c) 2006 by Secret Labs AB. | ||
11 | +# Copyright (c) 2006 by Fredrik Lundh. | ||
12 | +# | ||
13 | +# See the README file for information on usage and redistribution. | ||
14 | +# | ||
15 | + | ||
16 | +# mode descriptor cache | ||
17 | +_modes = None | ||
18 | + | ||
19 | + | ||
20 | +class ModeDescriptor(object): | ||
21 | + """Wrapper for mode strings.""" | ||
22 | + | ||
23 | + def __init__(self, mode, bands, basemode, basetype): | ||
24 | + self.mode = mode | ||
25 | + self.bands = bands | ||
26 | + self.basemode = basemode | ||
27 | + self.basetype = basetype | ||
28 | + | ||
29 | + def __str__(self): | ||
30 | + return self.mode | ||
31 | + | ||
32 | + | ||
33 | +def getmode(mode): | ||
34 | + """Gets a mode descriptor for the given mode.""" | ||
35 | + global _modes | ||
36 | + if not _modes: | ||
37 | + # initialize mode cache | ||
38 | + | ||
39 | + from . import Image | ||
40 | + | ||
41 | + modes = {} | ||
42 | + # core modes | ||
43 | + for m, (basemode, basetype, bands) in Image._MODEINFO.items(): | ||
44 | + modes[m] = ModeDescriptor(m, bands, basemode, basetype) | ||
45 | + # extra experimental modes | ||
46 | + modes["RGBa"] = ModeDescriptor("RGBa", ("R", "G", "B", "a"), "RGB", "L") | ||
47 | + modes["LA"] = ModeDescriptor("LA", ("L", "A"), "L", "L") | ||
48 | + modes["La"] = ModeDescriptor("La", ("L", "a"), "L", "L") | ||
49 | + modes["PA"] = ModeDescriptor("PA", ("P", "A"), "RGB", "L") | ||
50 | + # mapping modes | ||
51 | + for i16mode in ( | ||
52 | + "I;16", | ||
53 | + "I;16S", | ||
54 | + "I;16L", | ||
55 | + "I;16LS", | ||
56 | + "I;16B", | ||
57 | + "I;16BS", | ||
58 | + "I;16N", | ||
59 | + "I;16NS", | ||
60 | + ): | ||
61 | + modes[i16mode] = ModeDescriptor(i16mode, ("I",), "L", "L") | ||
62 | + # set global mode cache atomically | ||
63 | + _modes = modes | ||
64 | + return _modes[mode] |
1 | +# A binary morphology add-on for the Python Imaging Library | ||
2 | +# | ||
3 | +# History: | ||
4 | +# 2014-06-04 Initial version. | ||
5 | +# | ||
6 | +# Copyright (c) 2014 Dov Grobgeld <dov.grobgeld@gmail.com> | ||
7 | + | ||
8 | +from __future__ import print_function | ||
9 | + | ||
10 | +import re | ||
11 | + | ||
12 | +from . import Image, _imagingmorph | ||
13 | + | ||
14 | +LUT_SIZE = 1 << 9 | ||
15 | + | ||
16 | +# fmt: off | ||
17 | +ROTATION_MATRIX = [ | ||
18 | + 6, 3, 0, | ||
19 | + 7, 4, 1, | ||
20 | + 8, 5, 2, | ||
21 | +] | ||
22 | +MIRROR_MATRIX = [ | ||
23 | + 2, 1, 0, | ||
24 | + 5, 4, 3, | ||
25 | + 8, 7, 6, | ||
26 | +] | ||
27 | +# fmt: on | ||
28 | + | ||
29 | + | ||
30 | +class LutBuilder(object): | ||
31 | + """A class for building a MorphLut from a descriptive language | ||
32 | + | ||
33 | + The input patterns is a list of a strings sequences like these:: | ||
34 | + | ||
35 | + 4:(... | ||
36 | + .1. | ||
37 | + 111)->1 | ||
38 | + | ||
39 | + (whitespaces including linebreaks are ignored). The option 4 | ||
40 | + describes a series of symmetry operations (in this case a | ||
41 | + 4-rotation), the pattern is described by: | ||
42 | + | ||
43 | + - . or X - Ignore | ||
44 | + - 1 - Pixel is on | ||
45 | + - 0 - Pixel is off | ||
46 | + | ||
47 | + The result of the operation is described after "->" string. | ||
48 | + | ||
49 | + The default is to return the current pixel value, which is | ||
50 | + returned if no other match is found. | ||
51 | + | ||
52 | + Operations: | ||
53 | + | ||
54 | + - 4 - 4 way rotation | ||
55 | + - N - Negate | ||
56 | + - 1 - Dummy op for no other operation (an op must always be given) | ||
57 | + - M - Mirroring | ||
58 | + | ||
59 | + Example:: | ||
60 | + | ||
61 | + lb = LutBuilder(patterns = ["4:(... .1. 111)->1"]) | ||
62 | + lut = lb.build_lut() | ||
63 | + | ||
64 | + """ | ||
65 | + | ||
66 | + def __init__(self, patterns=None, op_name=None): | ||
67 | + if patterns is not None: | ||
68 | + self.patterns = patterns | ||
69 | + else: | ||
70 | + self.patterns = [] | ||
71 | + self.lut = None | ||
72 | + if op_name is not None: | ||
73 | + known_patterns = { | ||
74 | + "corner": ["1:(... ... ...)->0", "4:(00. 01. ...)->1"], | ||
75 | + "dilation4": ["4:(... .0. .1.)->1"], | ||
76 | + "dilation8": ["4:(... .0. .1.)->1", "4:(... .0. ..1)->1"], | ||
77 | + "erosion4": ["4:(... .1. .0.)->0"], | ||
78 | + "erosion8": ["4:(... .1. .0.)->0", "4:(... .1. ..0)->0"], | ||
79 | + "edge": [ | ||
80 | + "1:(... ... ...)->0", | ||
81 | + "4:(.0. .1. ...)->1", | ||
82 | + "4:(01. .1. ...)->1", | ||
83 | + ], | ||
84 | + } | ||
85 | + if op_name not in known_patterns: | ||
86 | + raise Exception("Unknown pattern " + op_name + "!") | ||
87 | + | ||
88 | + self.patterns = known_patterns[op_name] | ||
89 | + | ||
90 | + def add_patterns(self, patterns): | ||
91 | + self.patterns += patterns | ||
92 | + | ||
93 | + def build_default_lut(self): | ||
94 | + symbols = [0, 1] | ||
95 | + m = 1 << 4 # pos of current pixel | ||
96 | + self.lut = bytearray(symbols[(i & m) > 0] for i in range(LUT_SIZE)) | ||
97 | + | ||
98 | + def get_lut(self): | ||
99 | + return self.lut | ||
100 | + | ||
101 | + def _string_permute(self, pattern, permutation): | ||
102 | + """string_permute takes a pattern and a permutation and returns the | ||
103 | + string permuted according to the permutation list. | ||
104 | + """ | ||
105 | + assert len(permutation) == 9 | ||
106 | + return "".join(pattern[p] for p in permutation) | ||
107 | + | ||
108 | + def _pattern_permute(self, basic_pattern, options, basic_result): | ||
109 | + """pattern_permute takes a basic pattern and its result and clones | ||
110 | + the pattern according to the modifications described in the $options | ||
111 | + parameter. It returns a list of all cloned patterns.""" | ||
112 | + patterns = [(basic_pattern, basic_result)] | ||
113 | + | ||
114 | + # rotations | ||
115 | + if "4" in options: | ||
116 | + res = patterns[-1][1] | ||
117 | + for i in range(4): | ||
118 | + patterns.append( | ||
119 | + (self._string_permute(patterns[-1][0], ROTATION_MATRIX), res) | ||
120 | + ) | ||
121 | + # mirror | ||
122 | + if "M" in options: | ||
123 | + n = len(patterns) | ||
124 | + for pattern, res in patterns[0:n]: | ||
125 | + patterns.append((self._string_permute(pattern, MIRROR_MATRIX), res)) | ||
126 | + | ||
127 | + # negate | ||
128 | + if "N" in options: | ||
129 | + n = len(patterns) | ||
130 | + for pattern, res in patterns[0:n]: | ||
131 | + # Swap 0 and 1 | ||
132 | + pattern = pattern.replace("0", "Z").replace("1", "0").replace("Z", "1") | ||
133 | + res = 1 - int(res) | ||
134 | + patterns.append((pattern, res)) | ||
135 | + | ||
136 | + return patterns | ||
137 | + | ||
138 | + def build_lut(self): | ||
139 | + """Compile all patterns into a morphology lut. | ||
140 | + | ||
141 | + TBD :Build based on (file) morphlut:modify_lut | ||
142 | + """ | ||
143 | + self.build_default_lut() | ||
144 | + patterns = [] | ||
145 | + | ||
146 | + # Parse and create symmetries of the patterns strings | ||
147 | + for p in self.patterns: | ||
148 | + m = re.search(r"(\w*):?\s*\((.+?)\)\s*->\s*(\d)", p.replace("\n", "")) | ||
149 | + if not m: | ||
150 | + raise Exception('Syntax error in pattern "' + p + '"') | ||
151 | + options = m.group(1) | ||
152 | + pattern = m.group(2) | ||
153 | + result = int(m.group(3)) | ||
154 | + | ||
155 | + # Get rid of spaces | ||
156 | + pattern = pattern.replace(" ", "").replace("\n", "") | ||
157 | + | ||
158 | + patterns += self._pattern_permute(pattern, options, result) | ||
159 | + | ||
160 | + # compile the patterns into regular expressions for speed | ||
161 | + for i, pattern in enumerate(patterns): | ||
162 | + p = pattern[0].replace(".", "X").replace("X", "[01]") | ||
163 | + p = re.compile(p) | ||
164 | + patterns[i] = (p, pattern[1]) | ||
165 | + | ||
166 | + # Step through table and find patterns that match. | ||
167 | + # Note that all the patterns are searched. The last one | ||
168 | + # caught overrides | ||
169 | + for i in range(LUT_SIZE): | ||
170 | + # Build the bit pattern | ||
171 | + bitpattern = bin(i)[2:] | ||
172 | + bitpattern = ("0" * (9 - len(bitpattern)) + bitpattern)[::-1] | ||
173 | + | ||
174 | + for p, r in patterns: | ||
175 | + if p.match(bitpattern): | ||
176 | + self.lut[i] = [0, 1][r] | ||
177 | + | ||
178 | + return self.lut | ||
179 | + | ||
180 | + | ||
181 | +class MorphOp(object): | ||
182 | + """A class for binary morphological operators""" | ||
183 | + | ||
184 | + def __init__(self, lut=None, op_name=None, patterns=None): | ||
185 | + """Create a binary morphological operator""" | ||
186 | + self.lut = lut | ||
187 | + if op_name is not None: | ||
188 | + self.lut = LutBuilder(op_name=op_name).build_lut() | ||
189 | + elif patterns is not None: | ||
190 | + self.lut = LutBuilder(patterns=patterns).build_lut() | ||
191 | + | ||
192 | + def apply(self, image): | ||
193 | + """Run a single morphological operation on an image | ||
194 | + | ||
195 | + Returns a tuple of the number of changed pixels and the | ||
196 | + morphed image""" | ||
197 | + if self.lut is None: | ||
198 | + raise Exception("No operator loaded") | ||
199 | + | ||
200 | + if image.mode != "L": | ||
201 | + raise Exception("Image must be binary, meaning it must use mode L") | ||
202 | + outimage = Image.new(image.mode, image.size, None) | ||
203 | + count = _imagingmorph.apply(bytes(self.lut), image.im.id, outimage.im.id) | ||
204 | + return count, outimage | ||
205 | + | ||
206 | + def match(self, image): | ||
207 | + """Get a list of coordinates matching the morphological operation on | ||
208 | + an image. | ||
209 | + | ||
210 | + Returns a list of tuples of (x,y) coordinates | ||
211 | + of all matching pixels. See :ref:`coordinate-system`.""" | ||
212 | + if self.lut is None: | ||
213 | + raise Exception("No operator loaded") | ||
214 | + | ||
215 | + if image.mode != "L": | ||
216 | + raise Exception("Image must be binary, meaning it must use mode L") | ||
217 | + return _imagingmorph.match(bytes(self.lut), image.im.id) | ||
218 | + | ||
219 | + def get_on_pixels(self, image): | ||
220 | + """Get a list of all turned on pixels in a binary image | ||
221 | + | ||
222 | + Returns a list of tuples of (x,y) coordinates | ||
223 | + of all matching pixels. See :ref:`coordinate-system`.""" | ||
224 | + | ||
225 | + if image.mode != "L": | ||
226 | + raise Exception("Image must be binary, meaning it must use mode L") | ||
227 | + return _imagingmorph.get_on_pixels(image.im.id) | ||
228 | + | ||
229 | + def load_lut(self, filename): | ||
230 | + """Load an operator from an mrl file""" | ||
231 | + with open(filename, "rb") as f: | ||
232 | + self.lut = bytearray(f.read()) | ||
233 | + | ||
234 | + if len(self.lut) != LUT_SIZE: | ||
235 | + self.lut = None | ||
236 | + raise Exception("Wrong size operator file!") | ||
237 | + | ||
238 | + def save_lut(self, filename): | ||
239 | + """Save an operator to an mrl file""" | ||
240 | + if self.lut is None: | ||
241 | + raise Exception("No operator loaded") | ||
242 | + with open(filename, "wb") as f: | ||
243 | + f.write(self.lut) | ||
244 | + | ||
245 | + def set_lut(self, lut): | ||
246 | + """Set the lut from an external source""" | ||
247 | + self.lut = lut |
This diff is collapsed. Click to expand it.
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# image palette object | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 1996-03-11 fl Rewritten. | ||
9 | +# 1997-01-03 fl Up and running. | ||
10 | +# 1997-08-23 fl Added load hack | ||
11 | +# 2001-04-16 fl Fixed randint shadow bug in random() | ||
12 | +# | ||
13 | +# Copyright (c) 1997-2001 by Secret Labs AB | ||
14 | +# Copyright (c) 1996-1997 by Fredrik Lundh | ||
15 | +# | ||
16 | +# See the README file for information on usage and redistribution. | ||
17 | +# | ||
18 | + | ||
19 | +import array | ||
20 | + | ||
21 | +from . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile | ||
22 | + | ||
23 | + | ||
24 | +class ImagePalette(object): | ||
25 | + """ | ||
26 | + Color palette for palette mapped images | ||
27 | + | ||
28 | + :param mode: The mode to use for the Palette. See: | ||
29 | + :ref:`concept-modes`. Defaults to "RGB" | ||
30 | + :param palette: An optional palette. If given, it must be a bytearray, | ||
31 | + an array or a list of ints between 0-255 and of length ``size`` | ||
32 | + times the number of colors in ``mode``. The list must be aligned | ||
33 | + by channel (All R values must be contiguous in the list before G | ||
34 | + and B values.) Defaults to 0 through 255 per channel. | ||
35 | + :param size: An optional palette size. If given, it cannot be equal to | ||
36 | + or greater than 256. Defaults to 0. | ||
37 | + """ | ||
38 | + | ||
39 | + def __init__(self, mode="RGB", palette=None, size=0): | ||
40 | + self.mode = mode | ||
41 | + self.rawmode = None # if set, palette contains raw data | ||
42 | + self.palette = palette or bytearray(range(256)) * len(self.mode) | ||
43 | + self.colors = {} | ||
44 | + self.dirty = None | ||
45 | + if (size == 0 and len(self.mode) * 256 != len(self.palette)) or ( | ||
46 | + size != 0 and size != len(self.palette) | ||
47 | + ): | ||
48 | + raise ValueError("wrong palette size") | ||
49 | + | ||
50 | + def copy(self): | ||
51 | + new = ImagePalette() | ||
52 | + | ||
53 | + new.mode = self.mode | ||
54 | + new.rawmode = self.rawmode | ||
55 | + if self.palette is not None: | ||
56 | + new.palette = self.palette[:] | ||
57 | + new.colors = self.colors.copy() | ||
58 | + new.dirty = self.dirty | ||
59 | + | ||
60 | + return new | ||
61 | + | ||
62 | + def getdata(self): | ||
63 | + """ | ||
64 | + Get palette contents in format suitable for the low-level | ||
65 | + ``im.putpalette`` primitive. | ||
66 | + | ||
67 | + .. warning:: This method is experimental. | ||
68 | + """ | ||
69 | + if self.rawmode: | ||
70 | + return self.rawmode, self.palette | ||
71 | + return self.mode + ";L", self.tobytes() | ||
72 | + | ||
73 | + def tobytes(self): | ||
74 | + """Convert palette to bytes. | ||
75 | + | ||
76 | + .. warning:: This method is experimental. | ||
77 | + """ | ||
78 | + if self.rawmode: | ||
79 | + raise ValueError("palette contains raw palette data") | ||
80 | + if isinstance(self.palette, bytes): | ||
81 | + return self.palette | ||
82 | + arr = array.array("B", self.palette) | ||
83 | + if hasattr(arr, "tobytes"): | ||
84 | + return arr.tobytes() | ||
85 | + return arr.tostring() | ||
86 | + | ||
87 | + # Declare tostring as an alias for tobytes | ||
88 | + tostring = tobytes | ||
89 | + | ||
90 | + def getcolor(self, color): | ||
91 | + """Given an rgb tuple, allocate palette entry. | ||
92 | + | ||
93 | + .. warning:: This method is experimental. | ||
94 | + """ | ||
95 | + if self.rawmode: | ||
96 | + raise ValueError("palette contains raw palette data") | ||
97 | + if isinstance(color, tuple): | ||
98 | + try: | ||
99 | + return self.colors[color] | ||
100 | + except KeyError: | ||
101 | + # allocate new color slot | ||
102 | + if isinstance(self.palette, bytes): | ||
103 | + self.palette = bytearray(self.palette) | ||
104 | + index = len(self.colors) | ||
105 | + if index >= 256: | ||
106 | + raise ValueError("cannot allocate more than 256 colors") | ||
107 | + self.colors[color] = index | ||
108 | + self.palette[index] = color[0] | ||
109 | + self.palette[index + 256] = color[1] | ||
110 | + self.palette[index + 512] = color[2] | ||
111 | + self.dirty = 1 | ||
112 | + return index | ||
113 | + else: | ||
114 | + raise ValueError("unknown color specifier: %r" % color) | ||
115 | + | ||
116 | + def save(self, fp): | ||
117 | + """Save palette to text file. | ||
118 | + | ||
119 | + .. warning:: This method is experimental. | ||
120 | + """ | ||
121 | + if self.rawmode: | ||
122 | + raise ValueError("palette contains raw palette data") | ||
123 | + if isinstance(fp, str): | ||
124 | + fp = open(fp, "w") | ||
125 | + fp.write("# Palette\n") | ||
126 | + fp.write("# Mode: %s\n" % self.mode) | ||
127 | + for i in range(256): | ||
128 | + fp.write("%d" % i) | ||
129 | + for j in range(i * len(self.mode), (i + 1) * len(self.mode)): | ||
130 | + try: | ||
131 | + fp.write(" %d" % self.palette[j]) | ||
132 | + except IndexError: | ||
133 | + fp.write(" 0") | ||
134 | + fp.write("\n") | ||
135 | + fp.close() | ||
136 | + | ||
137 | + | ||
138 | +# -------------------------------------------------------------------- | ||
139 | +# Internal | ||
140 | + | ||
141 | + | ||
142 | +def raw(rawmode, data): | ||
143 | + palette = ImagePalette() | ||
144 | + palette.rawmode = rawmode | ||
145 | + palette.palette = data | ||
146 | + palette.dirty = 1 | ||
147 | + return palette | ||
148 | + | ||
149 | + | ||
150 | +# -------------------------------------------------------------------- | ||
151 | +# Factories | ||
152 | + | ||
153 | + | ||
154 | +def make_linear_lut(black, white): | ||
155 | + lut = [] | ||
156 | + if black == 0: | ||
157 | + for i in range(256): | ||
158 | + lut.append(white * i // 255) | ||
159 | + else: | ||
160 | + raise NotImplementedError # FIXME | ||
161 | + return lut | ||
162 | + | ||
163 | + | ||
164 | +def make_gamma_lut(exp): | ||
165 | + lut = [] | ||
166 | + for i in range(256): | ||
167 | + lut.append(int(((i / 255.0) ** exp) * 255.0 + 0.5)) | ||
168 | + return lut | ||
169 | + | ||
170 | + | ||
171 | +def negative(mode="RGB"): | ||
172 | + palette = list(range(256)) | ||
173 | + palette.reverse() | ||
174 | + return ImagePalette(mode, palette * len(mode)) | ||
175 | + | ||
176 | + | ||
177 | +def random(mode="RGB"): | ||
178 | + from random import randint | ||
179 | + | ||
180 | + palette = [] | ||
181 | + for i in range(256 * len(mode)): | ||
182 | + palette.append(randint(0, 255)) | ||
183 | + return ImagePalette(mode, palette) | ||
184 | + | ||
185 | + | ||
186 | +def sepia(white="#fff0c0"): | ||
187 | + r, g, b = ImageColor.getrgb(white) | ||
188 | + r = make_linear_lut(0, r) | ||
189 | + g = make_linear_lut(0, g) | ||
190 | + b = make_linear_lut(0, b) | ||
191 | + return ImagePalette("RGB", r + g + b) | ||
192 | + | ||
193 | + | ||
194 | +def wedge(mode="RGB"): | ||
195 | + return ImagePalette(mode, list(range(256)) * len(mode)) | ||
196 | + | ||
197 | + | ||
198 | +def load(filename): | ||
199 | + | ||
200 | + # FIXME: supports GIMP gradients only | ||
201 | + | ||
202 | + with open(filename, "rb") as fp: | ||
203 | + | ||
204 | + for paletteHandler in [ | ||
205 | + GimpPaletteFile.GimpPaletteFile, | ||
206 | + GimpGradientFile.GimpGradientFile, | ||
207 | + PaletteFile.PaletteFile, | ||
208 | + ]: | ||
209 | + try: | ||
210 | + fp.seek(0) | ||
211 | + lut = paletteHandler(fp).getpalette() | ||
212 | + if lut: | ||
213 | + break | ||
214 | + except (SyntaxError, ValueError): | ||
215 | + # import traceback | ||
216 | + # traceback.print_exc() | ||
217 | + pass | ||
218 | + else: | ||
219 | + raise IOError("cannot load palette") | ||
220 | + | ||
221 | + return lut # data, rawmode |
1 | +# | ||
2 | +# The Python Imaging Library | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# path interface | ||
6 | +# | ||
7 | +# History: | ||
8 | +# 1996-11-04 fl Created | ||
9 | +# 2002-04-14 fl Added documentation stub class | ||
10 | +# | ||
11 | +# Copyright (c) Secret Labs AB 1997. | ||
12 | +# Copyright (c) Fredrik Lundh 1996. | ||
13 | +# | ||
14 | +# See the README file for information on usage and redistribution. | ||
15 | +# | ||
16 | + | ||
17 | +from . import Image | ||
18 | + | ||
19 | +Path = Image.core.path |
1 | +# | ||
2 | +# The Python Imaging Library. | ||
3 | +# $Id$ | ||
4 | +# | ||
5 | +# a simple Qt image interface. | ||
6 | +# | ||
7 | +# history: | ||
8 | +# 2006-06-03 fl: created | ||
9 | +# 2006-06-04 fl: inherit from QImage instead of wrapping it | ||
10 | +# 2006-06-05 fl: removed toimage helper; move string support to ImageQt | ||
11 | +# 2013-11-13 fl: add support for Qt5 (aurelien.ballier@cyclonit.com) | ||
12 | +# | ||
13 | +# Copyright (c) 2006 by Secret Labs AB | ||
14 | +# Copyright (c) 2006 by Fredrik Lundh | ||
15 | +# | ||
16 | +# See the README file for information on usage and redistribution. | ||
17 | +# | ||
18 | + | ||
19 | +import sys | ||
20 | +import warnings | ||
21 | +from io import BytesIO | ||
22 | + | ||
23 | +from . import Image | ||
24 | +from ._util import isPath, py3 | ||
25 | + | ||
26 | +qt_versions = [["5", "PyQt5"], ["side2", "PySide2"], ["4", "PyQt4"], ["side", "PySide"]] | ||
27 | + | ||
28 | +WARNING_TEXT = ( | ||
29 | + "Support for EOL {} is deprecated and will be removed in a future version. " | ||
30 | + "Please upgrade to PyQt5 or PySide2." | ||
31 | +) | ||
32 | + | ||
33 | +# If a version has already been imported, attempt it first | ||
34 | +qt_versions.sort(key=lambda qt_version: qt_version[1] in sys.modules, reverse=True) | ||
35 | +for qt_version, qt_module in qt_versions: | ||
36 | + try: | ||
37 | + if qt_module == "PyQt5": | ||
38 | + from PyQt5.QtGui import QImage, qRgba, QPixmap | ||
39 | + from PyQt5.QtCore import QBuffer, QIODevice | ||
40 | + elif qt_module == "PySide2": | ||
41 | + from PySide2.QtGui import QImage, qRgba, QPixmap | ||
42 | + from PySide2.QtCore import QBuffer, QIODevice | ||
43 | + elif qt_module == "PyQt4": | ||
44 | + from PyQt4.QtGui import QImage, qRgba, QPixmap | ||
45 | + from PyQt4.QtCore import QBuffer, QIODevice | ||
46 | + | ||
47 | + warnings.warn(WARNING_TEXT.format(qt_module), DeprecationWarning) | ||
48 | + elif qt_module == "PySide": | ||
49 | + from PySide.QtGui import QImage, qRgba, QPixmap | ||
50 | + from PySide.QtCore import QBuffer, QIODevice | ||
51 | + | ||
52 | + warnings.warn(WARNING_TEXT.format(qt_module), DeprecationWarning) | ||
53 | + except (ImportError, RuntimeError): | ||
54 | + continue | ||
55 | + qt_is_installed = True | ||
56 | + break | ||
57 | +else: | ||
58 | + qt_is_installed = False | ||
59 | + qt_version = None | ||
60 | + | ||
61 | + | ||
62 | +def rgb(r, g, b, a=255): | ||
63 | + """(Internal) Turns an RGB color into a Qt compatible color integer.""" | ||
64 | + # use qRgb to pack the colors, and then turn the resulting long | ||
65 | + # into a negative integer with the same bitpattern. | ||
66 | + return qRgba(r, g, b, a) & 0xFFFFFFFF | ||
67 | + | ||
68 | + | ||
69 | +def fromqimage(im): | ||
70 | + """ | ||
71 | + :param im: A PIL Image object, or a file name | ||
72 | + (given either as Python string or a PyQt string object) | ||
73 | + """ | ||
74 | + buffer = QBuffer() | ||
75 | + buffer.open(QIODevice.ReadWrite) | ||
76 | + # preserve alpha channel with png | ||
77 | + # otherwise ppm is more friendly with Image.open | ||
78 | + if im.hasAlphaChannel(): | ||
79 | + im.save(buffer, "png") | ||
80 | + else: | ||
81 | + im.save(buffer, "ppm") | ||
82 | + | ||
83 | + b = BytesIO() | ||
84 | + try: | ||
85 | + b.write(buffer.data()) | ||
86 | + except TypeError: | ||
87 | + # workaround for Python 2 | ||
88 | + b.write(str(buffer.data())) | ||
89 | + buffer.close() | ||
90 | + b.seek(0) | ||
91 | + | ||
92 | + return Image.open(b) | ||
93 | + | ||
94 | + | ||
95 | +def fromqpixmap(im): | ||
96 | + return fromqimage(im) | ||
97 | + # buffer = QBuffer() | ||
98 | + # buffer.open(QIODevice.ReadWrite) | ||
99 | + # # im.save(buffer) | ||
100 | + # # What if png doesn't support some image features like animation? | ||
101 | + # im.save(buffer, 'ppm') | ||
102 | + # bytes_io = BytesIO() | ||
103 | + # bytes_io.write(buffer.data()) | ||
104 | + # buffer.close() | ||
105 | + # bytes_io.seek(0) | ||
106 | + # return Image.open(bytes_io) | ||
107 | + | ||
108 | + | ||
109 | +def align8to32(bytes, width, mode): | ||
110 | + """ | ||
111 | + converts each scanline of data from 8 bit to 32 bit aligned | ||
112 | + """ | ||
113 | + | ||
114 | + bits_per_pixel = {"1": 1, "L": 8, "P": 8}[mode] | ||
115 | + | ||
116 | + # calculate bytes per line and the extra padding if needed | ||
117 | + bits_per_line = bits_per_pixel * width | ||
118 | + full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8) | ||
119 | + bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0) | ||
120 | + | ||
121 | + extra_padding = -bytes_per_line % 4 | ||
122 | + | ||
123 | + # already 32 bit aligned by luck | ||
124 | + if not extra_padding: | ||
125 | + return bytes | ||
126 | + | ||
127 | + new_data = [] | ||
128 | + for i in range(len(bytes) // bytes_per_line): | ||
129 | + new_data.append( | ||
130 | + bytes[i * bytes_per_line : (i + 1) * bytes_per_line] | ||
131 | + + b"\x00" * extra_padding | ||
132 | + ) | ||
133 | + | ||
134 | + return b"".join(new_data) | ||
135 | + | ||
136 | + | ||
137 | +def _toqclass_helper(im): | ||
138 | + data = None | ||
139 | + colortable = None | ||
140 | + | ||
141 | + # handle filename, if given instead of image name | ||
142 | + if hasattr(im, "toUtf8"): | ||
143 | + # FIXME - is this really the best way to do this? | ||
144 | + if py3: | ||
145 | + im = str(im.toUtf8(), "utf-8") | ||
146 | + else: | ||
147 | + im = unicode(im.toUtf8(), "utf-8") # noqa: F821 | ||
148 | + if isPath(im): | ||
149 | + im = Image.open(im) | ||
150 | + | ||
151 | + if im.mode == "1": | ||
152 | + format = QImage.Format_Mono | ||
153 | + elif im.mode == "L": | ||
154 | + format = QImage.Format_Indexed8 | ||
155 | + colortable = [] | ||
156 | + for i in range(256): | ||
157 | + colortable.append(rgb(i, i, i)) | ||
158 | + elif im.mode == "P": | ||
159 | + format = QImage.Format_Indexed8 | ||
160 | + colortable = [] | ||
161 | + palette = im.getpalette() | ||
162 | + for i in range(0, len(palette), 3): | ||
163 | + colortable.append(rgb(*palette[i : i + 3])) | ||
164 | + elif im.mode == "RGB": | ||
165 | + data = im.tobytes("raw", "BGRX") | ||
166 | + format = QImage.Format_RGB32 | ||
167 | + elif im.mode == "RGBA": | ||
168 | + try: | ||
169 | + data = im.tobytes("raw", "BGRA") | ||
170 | + except SystemError: | ||
171 | + # workaround for earlier versions | ||
172 | + r, g, b, a = im.split() | ||
173 | + im = Image.merge("RGBA", (b, g, r, a)) | ||
174 | + format = QImage.Format_ARGB32 | ||
175 | + else: | ||
176 | + raise ValueError("unsupported image mode %r" % im.mode) | ||
177 | + | ||
178 | + __data = data or align8to32(im.tobytes(), im.size[0], im.mode) | ||
179 | + return {"data": __data, "im": im, "format": format, "colortable": colortable} | ||
180 | + | ||
181 | + | ||
182 | +if qt_is_installed: | ||
183 | + | ||
184 | + class ImageQt(QImage): | ||
185 | + def __init__(self, im): | ||
186 | + """ | ||
187 | + An PIL image wrapper for Qt. This is a subclass of PyQt's QImage | ||
188 | + class. | ||
189 | + | ||
190 | + :param im: A PIL Image object, or a file name (given either as | ||
191 | + Python string or a PyQt string object). | ||
192 | + """ | ||
193 | + im_data = _toqclass_helper(im) | ||
194 | + # must keep a reference, or Qt will crash! | ||
195 | + # All QImage constructors that take data operate on an existing | ||
196 | + # buffer, so this buffer has to hang on for the life of the image. | ||
197 | + # Fixes https://github.com/python-pillow/Pillow/issues/1370 | ||
198 | + self.__data = im_data["data"] | ||
199 | + QImage.__init__( | ||
200 | + self, | ||
201 | + self.__data, | ||
202 | + im_data["im"].size[0], | ||
203 | + im_data["im"].size[1], | ||
204 | + im_data["format"], | ||
205 | + ) | ||
206 | + if im_data["colortable"]: | ||
207 | + self.setColorTable(im_data["colortable"]) | ||
208 | + | ||
209 | + | ||
210 | +def toqimage(im): | ||
211 | + return ImageQt(im) | ||
212 | + | ||
213 | + | ||
214 | +def toqpixmap(im): | ||
215 | + # # This doesn't work. For now using a dumb approach. | ||
216 | + # im_data = _toqclass_helper(im) | ||
217 | + # result = QPixmap(im_data['im'].size[0], im_data['im'].size[1]) | ||
218 | + # result.loadFromData(im_data['data']) | ||
219 | + # Fix some strange bug that causes | ||
220 | + if im.mode == "RGB": | ||
221 | + im = im.convert("RGBA") | ||
222 | + | ||
223 | + qimage = toqimage(im) | ||
224 | + return QPixmap.fromImage(qimage) |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/PIL/__pycache__/BufrStubImagePlugin.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/PIL/__pycache__/FitsStubImagePlugin.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/PIL/__pycache__/GribStubImagePlugin.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/PIL/__pycache__/Hdf5StubImagePlugin.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/absl/flags/__pycache__/_argument_parser.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/absl/flags/__pycache__/argparse_flags.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/absl/testing/__pycache__/_bazel_selected_py3.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/absl/testing/__pycache__/_bazelize_command.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/absl/testing/__pycache__/parameterized.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/absl/testing/__pycache__/xml_reporter.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/absl/third_party/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/chardistribution.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/charsetgroupprober.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/codingstatemachine.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/langhebrewmodel.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/langhungarianmodel.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/langturkishmodel.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/mbcharsetprober.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/sbcharsetprober.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/chardet/__pycache__/universaldetector.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/cloudpickle/__pycache__/cloudpickle.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/cloudpickle/__pycache__/cloudpickle_fast.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
No preview for this file type
This diff could not be displayed because it is too large.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff could not be displayed because it is too large.
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/docs/site/fonts/glyphicons-halflings-regular.woff2
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/docs/site/getting-started/minimizing_functions/index.html
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/docs/site/getting-started/search_spaces/index.html
0 → 100644
This diff is collapsed. Click to expand it.
No preview for this file type
1.42 KB
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/docs/sources/getting-started/minimizing_functions.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/docs/templates/getting-started/minimizing_functions.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/__pycache__/custom_descriptions.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/__pycache__/custom_descriptions_test.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/__pycache__/docstrings_fuzz_test.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/__pycache__/formatting_windows.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/__pycache__/test_components_bin.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/__pycache__/test_components_py3.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/__pycache__/test_components_test.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/console/__pycache__/console_attr.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/console/__pycache__/console_attr_os.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/console/__pycache__/console_io.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/fire/console/__pycache__/console_pager.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/__pycache__/_markupbase.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/__pycache__/datetime.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/__pycache__/socket.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/__pycache__/socketserver.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/__pycache__/total_ordering.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/_parseaddr.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/_policybase.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/base64mime.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/charset.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/encoders.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/errors.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/feedparser.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/generator.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/header.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/iterators.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/message.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/parser.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/policy.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/quoprimime.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/__pycache__/utils.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/mime/__pycache__/audio.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/mime/__pycache__/base.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/mime/__pycache__/image.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/email/mime/__pycache__/text.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/html/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/html/__pycache__/entities.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/html/__pycache__/parser.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/http/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/http/__pycache__/client.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/http/__pycache__/cookiejar.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/http/__pycache__/cookies.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/http/__pycache__/server.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/test/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/test/__pycache__/pystone.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/test/__pycache__/ssl_servers.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/test/__pycache__/support.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/test/https_svn_python_org_root.pem
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/urllib/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/urllib/__pycache__/error.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/urllib/__pycache__/parse.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/urllib/__pycache__/request.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/urllib/__pycache__/response.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/xmlrpc/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/xmlrpc/__pycache__/client.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/backports/xmlrpc/__pycache__/server.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/builtins/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/builtins/__pycache__/disabled.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/builtins/__pycache__/iterators.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/builtins/__pycache__/new_min_max.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/builtins/__pycache__/newnext.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/builtins/__pycache__/newround.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/builtins/__pycache__/newsuper.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/__pycache__/_dummy_thread.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/__pycache__/_markupbase.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/__pycache__/collections.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/__pycache__/configparser.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/__pycache__/socketserver.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/__pycache__/subprocess.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/dbm/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/html/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/html/__pycache__/entities.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/html/__pycache__/parser.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/http/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/http/__pycache__/client.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/http/__pycache__/cookiejar.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/http/__pycache__/cookies.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/http/__pycache__/server.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/test/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/test/__pycache__/support.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/colorchooser.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/commondialog.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/constants.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/dialog.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/dnd.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/filedialog.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/font.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/messagebox.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/scrolledtext.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/simpledialog.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/tix.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/tkinter/__pycache__/ttk.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/urllib/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/urllib/__pycache__/error.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/urllib/__pycache__/parse.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/urllib/__pycache__/request.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/urllib/__pycache__/response.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/urllib/__pycache__/robotparser.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/xmlrpc/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/xmlrpc/__pycache__/client.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/moves/xmlrpc/__pycache__/server.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/future/standard_library/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/types/__pycache__/newmemoryview.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/future/utils/__pycache__/surrogateescape.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/__pycache__/_oauth2client.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/__pycache__/_service_account_info.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/__pycache__/credentials.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/__pycache__/environment_vars.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/crypt/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/crypt/__pycache__/_helpers.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/crypt/__pycache__/_python_rsa.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/crypt/__pycache__/es256.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/transport/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/transport/__pycache__/_http_client.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/transport/__pycache__/_mtls_helper.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/transport/__pycache__/grpc.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/transport/__pycache__/requests.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/auth/transport/__pycache__/urllib3.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/oauth2/__pycache__/credentials.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/oauth2/__pycache__/service_account.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/any_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/any_test_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/api_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/descriptor.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_pool.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/duration_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/empty_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/field_mask_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/json_format.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/map_unittest_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/message.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/message_factory.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/proto_builder.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/reflection.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/service.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/service_reflection.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/source_context_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/struct_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/symbol_database.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/text_encoding.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/text_format.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/timestamp_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/type_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/unittest_arena_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/unittest_mset_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/unittest_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/__pycache__/wrappers_pb2.cpython-37.pyc
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
code/FAA2_VM/cd-venv/Lib/site-packages/google/protobuf/compiler/__pycache__/__init__.cpython-37.pyc
0 → 100644
No preview for this file type
-
Please register or login to post a comment