Open Media Library Platform
This commit is contained in:
commit
411ad5b16f
5849 changed files with 1778641 additions and 0 deletions
|
|
@ -0,0 +1,58 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: Flask
|
||||
Version: 0.10.1
|
||||
Summary: A microframework based on Werkzeug, Jinja2 and good intentions
|
||||
Home-page: http://github.com/mitsuhiko/flask/
|
||||
Author: Armin Ronacher
|
||||
Author-email: armin.ronacher@active-4.com
|
||||
License: BSD
|
||||
Description:
|
||||
Flask
|
||||
-----
|
||||
|
||||
Flask is a microframework for Python based on Werkzeug, Jinja 2 and good
|
||||
intentions. And before you ask: It's BSD licensed!
|
||||
|
||||
Flask is Fun
|
||||
````````````
|
||||
|
||||
.. code:: python
|
||||
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello World!"
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
|
||||
And Easy to Setup
|
||||
`````````````````
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ pip install Flask
|
||||
$ python hello.py
|
||||
* Running on http://localhost:5000/
|
||||
|
||||
Links
|
||||
`````
|
||||
|
||||
* `website <http://flask.pocoo.org/>`_
|
||||
* `documentation <http://flask.pocoo.org/docs/>`_
|
||||
* `development version
|
||||
<http://github.com/mitsuhiko/flask/zipball/master#egg=Flask-dev>`_
|
||||
|
||||
|
||||
Platform: any
|
||||
Classifier: Development Status :: 4 - Beta
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
AUTHORS
|
||||
CHANGES
|
||||
LICENSE
|
||||
MANIFEST.in
|
||||
Makefile
|
||||
README
|
||||
run-tests.py
|
||||
setup.cfg
|
||||
setup.py
|
||||
Flask.egg-info/PKG-INFO
|
||||
Flask.egg-info/SOURCES.txt
|
||||
Flask.egg-info/dependency_links.txt
|
||||
Flask.egg-info/not-zip-safe
|
||||
Flask.egg-info/requires.txt
|
||||
Flask.egg-info/top_level.txt
|
||||
artwork/.DS_Store
|
||||
artwork/LICENSE
|
||||
artwork/logo-full.svg
|
||||
docs/.gitignore
|
||||
docs/Makefile
|
||||
docs/advanced_foreword.rst
|
||||
docs/api.rst
|
||||
docs/appcontext.rst
|
||||
docs/becomingbig.rst
|
||||
docs/blueprints.rst
|
||||
docs/changelog.rst
|
||||
docs/conf.py
|
||||
docs/config.rst
|
||||
docs/contents.rst.inc
|
||||
docs/design.rst
|
||||
docs/errorhandling.rst
|
||||
docs/extensiondev.rst
|
||||
docs/extensions.rst
|
||||
docs/flaskdocext.py
|
||||
docs/flaskext.py
|
||||
docs/flaskstyle.sty
|
||||
docs/foreword.rst
|
||||
docs/htmlfaq.rst
|
||||
docs/index.rst
|
||||
docs/installation.rst
|
||||
docs/latexindex.rst
|
||||
docs/license.rst
|
||||
docs/logo.pdf
|
||||
docs/make.bat
|
||||
docs/python3.rst
|
||||
docs/quickstart.rst
|
||||
docs/reqcontext.rst
|
||||
docs/security.rst
|
||||
docs/shell.rst
|
||||
docs/signals.rst
|
||||
docs/styleguide.rst
|
||||
docs/templating.rst
|
||||
docs/testing.rst
|
||||
docs/unicode.rst
|
||||
docs/upgrading.rst
|
||||
docs/views.rst
|
||||
docs/_static/debugger.png
|
||||
docs/_static/flask.png
|
||||
docs/_static/flaskr.png
|
||||
docs/_static/logo-full.png
|
||||
docs/_static/no.png
|
||||
docs/_static/touch-icon.png
|
||||
docs/_static/yes.png
|
||||
docs/_templates/sidebarintro.html
|
||||
docs/_templates/sidebarlogo.html
|
||||
docs/_themes/.git
|
||||
docs/_themes/.gitignore
|
||||
docs/_themes/LICENSE
|
||||
docs/_themes/README
|
||||
docs/_themes/flask_theme_support.py
|
||||
docs/_themes/flask/layout.html
|
||||
docs/_themes/flask/relations.html
|
||||
docs/_themes/flask/theme.conf
|
||||
docs/_themes/flask/static/flasky.css_t
|
||||
docs/_themes/flask/static/small_flask.css
|
||||
docs/_themes/flask_small/layout.html
|
||||
docs/_themes/flask_small/theme.conf
|
||||
docs/_themes/flask_small/static/flasky.css_t
|
||||
docs/deploying/cgi.rst
|
||||
docs/deploying/fastcgi.rst
|
||||
docs/deploying/index.rst
|
||||
docs/deploying/mod_wsgi.rst
|
||||
docs/deploying/uwsgi.rst
|
||||
docs/deploying/wsgi-standalone.rst
|
||||
docs/patterns/apierrors.rst
|
||||
docs/patterns/appdispatch.rst
|
||||
docs/patterns/appfactories.rst
|
||||
docs/patterns/caching.rst
|
||||
docs/patterns/celery.rst
|
||||
docs/patterns/deferredcallbacks.rst
|
||||
docs/patterns/distribute.rst
|
||||
docs/patterns/errorpages.rst
|
||||
docs/patterns/fabric.rst
|
||||
docs/patterns/favicon.rst
|
||||
docs/patterns/fileuploads.rst
|
||||
docs/patterns/flashing.rst
|
||||
docs/patterns/index.rst
|
||||
docs/patterns/jquery.rst
|
||||
docs/patterns/lazyloading.rst
|
||||
docs/patterns/methodoverrides.rst
|
||||
docs/patterns/mongokit.rst
|
||||
docs/patterns/packages.rst
|
||||
docs/patterns/requestchecksum.rst
|
||||
docs/patterns/sqlalchemy.rst
|
||||
docs/patterns/sqlite3.rst
|
||||
docs/patterns/streaming.rst
|
||||
docs/patterns/templateinheritance.rst
|
||||
docs/patterns/urlprocessors.rst
|
||||
docs/patterns/viewdecorators.rst
|
||||
docs/patterns/wtforms.rst
|
||||
docs/tutorial/css.rst
|
||||
docs/tutorial/dbcon.rst
|
||||
docs/tutorial/dbinit.rst
|
||||
docs/tutorial/folders.rst
|
||||
docs/tutorial/index.rst
|
||||
docs/tutorial/introduction.rst
|
||||
docs/tutorial/schema.rst
|
||||
docs/tutorial/setup.rst
|
||||
docs/tutorial/templates.rst
|
||||
docs/tutorial/testing.rst
|
||||
docs/tutorial/views.rst
|
||||
examples/.DS_Store
|
||||
examples/blueprintexample/blueprintexample.py
|
||||
examples/blueprintexample/blueprintexample_test.py
|
||||
examples/blueprintexample/simple_page/__init__.py
|
||||
examples/blueprintexample/simple_page/simple_page.py
|
||||
examples/blueprintexample/simple_page/templates/pages/hello.html
|
||||
examples/blueprintexample/simple_page/templates/pages/index.html
|
||||
examples/blueprintexample/simple_page/templates/pages/layout.html
|
||||
examples/blueprintexample/simple_page/templates/pages/world.html
|
||||
examples/flaskr/README
|
||||
examples/flaskr/flaskr.py
|
||||
examples/flaskr/flaskr_tests.py
|
||||
examples/flaskr/schema.sql
|
||||
examples/flaskr/static/style.css
|
||||
examples/flaskr/templates/layout.html
|
||||
examples/flaskr/templates/login.html
|
||||
examples/flaskr/templates/show_entries.html
|
||||
examples/jqueryexample/jqueryexample.py
|
||||
examples/jqueryexample/templates/index.html
|
||||
examples/jqueryexample/templates/layout.html
|
||||
examples/minitwit/README
|
||||
examples/minitwit/minitwit.py
|
||||
examples/minitwit/minitwit_tests.py
|
||||
examples/minitwit/schema.sql
|
||||
examples/minitwit/static/style.css
|
||||
examples/minitwit/templates/layout.html
|
||||
examples/minitwit/templates/login.html
|
||||
examples/minitwit/templates/register.html
|
||||
examples/minitwit/templates/timeline.html
|
||||
examples/persona/.DS_Store
|
||||
examples/persona/persona.py
|
||||
examples/persona/static/.DS_Store
|
||||
examples/persona/static/persona.js
|
||||
examples/persona/static/spinner.png
|
||||
examples/persona/static/style.css
|
||||
examples/persona/templates/index.html
|
||||
examples/persona/templates/layout.html
|
||||
flask/__init__.py
|
||||
flask/_compat.py
|
||||
flask/app.py
|
||||
flask/blueprints.py
|
||||
flask/config.py
|
||||
flask/ctx.py
|
||||
flask/debughelpers.py
|
||||
flask/exthook.py
|
||||
flask/globals.py
|
||||
flask/helpers.py
|
||||
flask/json.py
|
||||
flask/logging.py
|
||||
flask/module.py
|
||||
flask/sessions.py
|
||||
flask/signals.py
|
||||
flask/templating.py
|
||||
flask/testing.py
|
||||
flask/views.py
|
||||
flask/wrappers.py
|
||||
flask/ext/__init__.py
|
||||
flask/testsuite/__init__.py
|
||||
flask/testsuite/appctx.py
|
||||
flask/testsuite/basic.py
|
||||
flask/testsuite/blueprints.py
|
||||
flask/testsuite/config.py
|
||||
flask/testsuite/deprecations.py
|
||||
flask/testsuite/examples.py
|
||||
flask/testsuite/ext.py
|
||||
flask/testsuite/helpers.py
|
||||
flask/testsuite/regression.py
|
||||
flask/testsuite/reqctx.py
|
||||
flask/testsuite/signals.py
|
||||
flask/testsuite/subclassing.py
|
||||
flask/testsuite/templating.py
|
||||
flask/testsuite/testing.py
|
||||
flask/testsuite/views.py
|
||||
flask/testsuite/static/index.html
|
||||
flask/testsuite/templates/_macro.html
|
||||
flask/testsuite/templates/context_template.html
|
||||
flask/testsuite/templates/escaping_template.html
|
||||
flask/testsuite/templates/mail.txt
|
||||
flask/testsuite/templates/simple_template.html
|
||||
flask/testsuite/templates/template_filter.html
|
||||
flask/testsuite/templates/template_test.html
|
||||
flask/testsuite/templates/nested/nested.txt
|
||||
flask/testsuite/test_apps/config_module_app.py
|
||||
flask/testsuite/test_apps/flask_newext_simple.py
|
||||
flask/testsuite/test_apps/importerror.py
|
||||
flask/testsuite/test_apps/main_app.py
|
||||
flask/testsuite/test_apps/blueprintapp/__init__.py
|
||||
flask/testsuite/test_apps/blueprintapp/apps/__init__.py
|
||||
flask/testsuite/test_apps/blueprintapp/apps/admin/__init__.py
|
||||
flask/testsuite/test_apps/blueprintapp/apps/admin/static/test.txt
|
||||
flask/testsuite/test_apps/blueprintapp/apps/admin/static/css/test.css
|
||||
flask/testsuite/test_apps/blueprintapp/apps/admin/templates/admin/index.html
|
||||
flask/testsuite/test_apps/blueprintapp/apps/frontend/__init__.py
|
||||
flask/testsuite/test_apps/blueprintapp/apps/frontend/templates/frontend/index.html
|
||||
flask/testsuite/test_apps/config_package_app/__init__.py
|
||||
flask/testsuite/test_apps/flask_broken/__init__.py
|
||||
flask/testsuite/test_apps/flask_broken/b.py
|
||||
flask/testsuite/test_apps/flask_newext_package/__init__.py
|
||||
flask/testsuite/test_apps/flask_newext_package/submodule.py
|
||||
flask/testsuite/test_apps/flaskext/__init__.py
|
||||
flask/testsuite/test_apps/flaskext/oldext_simple.py
|
||||
flask/testsuite/test_apps/flaskext/oldext_package/__init__.py
|
||||
flask/testsuite/test_apps/flaskext/oldext_package/submodule.py
|
||||
flask/testsuite/test_apps/lib/python2.5/site-packages/SiteEgg.egg
|
||||
flask/testsuite/test_apps/lib/python2.5/site-packages/site_app.py
|
||||
flask/testsuite/test_apps/lib/python2.5/site-packages/site_package/__init__.py
|
||||
flask/testsuite/test_apps/moduleapp/__init__.py
|
||||
flask/testsuite/test_apps/moduleapp/apps/__init__.py
|
||||
flask/testsuite/test_apps/moduleapp/apps/admin/__init__.py
|
||||
flask/testsuite/test_apps/moduleapp/apps/admin/static/test.txt
|
||||
flask/testsuite/test_apps/moduleapp/apps/admin/static/css/test.css
|
||||
flask/testsuite/test_apps/moduleapp/apps/admin/templates/index.html
|
||||
flask/testsuite/test_apps/moduleapp/apps/frontend/__init__.py
|
||||
flask/testsuite/test_apps/moduleapp/apps/frontend/templates/index.html
|
||||
flask/testsuite/test_apps/path/installed_package/__init__.py
|
||||
flask/testsuite/test_apps/subdomaintestmodule/__init__.py
|
||||
flask/testsuite/test_apps/subdomaintestmodule/static/hello.txt
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
../flask/__init__.py
|
||||
../flask/_compat.py
|
||||
../flask/app.py
|
||||
../flask/blueprints.py
|
||||
../flask/config.py
|
||||
../flask/ctx.py
|
||||
../flask/debughelpers.py
|
||||
../flask/exthook.py
|
||||
../flask/globals.py
|
||||
../flask/helpers.py
|
||||
../flask/json.py
|
||||
../flask/logging.py
|
||||
../flask/module.py
|
||||
../flask/sessions.py
|
||||
../flask/signals.py
|
||||
../flask/templating.py
|
||||
../flask/testing.py
|
||||
../flask/views.py
|
||||
../flask/wrappers.py
|
||||
../flask/ext/__init__.py
|
||||
../flask/testsuite/__init__.py
|
||||
../flask/testsuite/appctx.py
|
||||
../flask/testsuite/basic.py
|
||||
../flask/testsuite/blueprints.py
|
||||
../flask/testsuite/config.py
|
||||
../flask/testsuite/deprecations.py
|
||||
../flask/testsuite/examples.py
|
||||
../flask/testsuite/ext.py
|
||||
../flask/testsuite/helpers.py
|
||||
../flask/testsuite/regression.py
|
||||
../flask/testsuite/reqctx.py
|
||||
../flask/testsuite/signals.py
|
||||
../flask/testsuite/subclassing.py
|
||||
../flask/testsuite/templating.py
|
||||
../flask/testsuite/testing.py
|
||||
../flask/testsuite/views.py
|
||||
../flask/testsuite/static/index.html
|
||||
../flask/testsuite/templates/_macro.html
|
||||
../flask/testsuite/templates/context_template.html
|
||||
../flask/testsuite/templates/escaping_template.html
|
||||
../flask/testsuite/templates/mail.txt
|
||||
../flask/testsuite/templates/simple_template.html
|
||||
../flask/testsuite/templates/template_filter.html
|
||||
../flask/testsuite/templates/template_test.html
|
||||
../flask/testsuite/templates/nested/nested.txt
|
||||
../flask/testsuite/test_apps/config_module_app.py
|
||||
../flask/testsuite/test_apps/flask_newext_simple.py
|
||||
../flask/testsuite/test_apps/importerror.py
|
||||
../flask/testsuite/test_apps/main_app.py
|
||||
../flask/testsuite/test_apps/blueprintapp/__init__.py
|
||||
../flask/testsuite/test_apps/blueprintapp/apps/__init__.py
|
||||
../flask/testsuite/test_apps/blueprintapp/apps/admin/__init__.py
|
||||
../flask/testsuite/test_apps/blueprintapp/apps/admin/static/test.txt
|
||||
../flask/testsuite/test_apps/blueprintapp/apps/admin/static/css/test.css
|
||||
../flask/testsuite/test_apps/blueprintapp/apps/admin/templates/admin/index.html
|
||||
../flask/testsuite/test_apps/blueprintapp/apps/frontend/__init__.py
|
||||
../flask/testsuite/test_apps/blueprintapp/apps/frontend/templates/frontend/index.html
|
||||
../flask/testsuite/test_apps/config_package_app/__init__.py
|
||||
../flask/testsuite/test_apps/flask_broken/__init__.py
|
||||
../flask/testsuite/test_apps/flask_broken/b.py
|
||||
../flask/testsuite/test_apps/flask_newext_package/__init__.py
|
||||
../flask/testsuite/test_apps/flask_newext_package/submodule.py
|
||||
../flask/testsuite/test_apps/flaskext/__init__.py
|
||||
../flask/testsuite/test_apps/flaskext/oldext_simple.py
|
||||
../flask/testsuite/test_apps/flaskext/oldext_package/__init__.py
|
||||
../flask/testsuite/test_apps/flaskext/oldext_package/submodule.py
|
||||
../flask/testsuite/test_apps/lib/python2.5/site-packages/SiteEgg.egg
|
||||
../flask/testsuite/test_apps/lib/python2.5/site-packages/site_app.py
|
||||
../flask/testsuite/test_apps/lib/python2.5/site-packages/site_package/__init__.py
|
||||
../flask/testsuite/test_apps/moduleapp/__init__.py
|
||||
../flask/testsuite/test_apps/moduleapp/apps/__init__.py
|
||||
../flask/testsuite/test_apps/moduleapp/apps/admin/__init__.py
|
||||
../flask/testsuite/test_apps/moduleapp/apps/admin/static/test.txt
|
||||
../flask/testsuite/test_apps/moduleapp/apps/admin/static/css/test.css
|
||||
../flask/testsuite/test_apps/moduleapp/apps/admin/templates/index.html
|
||||
../flask/testsuite/test_apps/moduleapp/apps/frontend/__init__.py
|
||||
../flask/testsuite/test_apps/moduleapp/apps/frontend/templates/index.html
|
||||
../flask/testsuite/test_apps/path/installed_package/__init__.py
|
||||
../flask/testsuite/test_apps/subdomaintestmodule/__init__.py
|
||||
../flask/testsuite/test_apps/subdomaintestmodule/static/hello.txt
|
||||
../flask/__init__.pyc
|
||||
../flask/_compat.pyc
|
||||
../flask/app.pyc
|
||||
../flask/blueprints.pyc
|
||||
../flask/config.pyc
|
||||
../flask/ctx.pyc
|
||||
../flask/debughelpers.pyc
|
||||
../flask/exthook.pyc
|
||||
../flask/globals.pyc
|
||||
../flask/helpers.pyc
|
||||
../flask/json.pyc
|
||||
../flask/logging.pyc
|
||||
../flask/module.pyc
|
||||
../flask/sessions.pyc
|
||||
../flask/signals.pyc
|
||||
../flask/templating.pyc
|
||||
../flask/testing.pyc
|
||||
../flask/views.pyc
|
||||
../flask/wrappers.pyc
|
||||
../flask/ext/__init__.pyc
|
||||
../flask/testsuite/__init__.pyc
|
||||
../flask/testsuite/appctx.pyc
|
||||
../flask/testsuite/basic.pyc
|
||||
../flask/testsuite/blueprints.pyc
|
||||
../flask/testsuite/config.pyc
|
||||
../flask/testsuite/deprecations.pyc
|
||||
../flask/testsuite/examples.pyc
|
||||
../flask/testsuite/ext.pyc
|
||||
../flask/testsuite/helpers.pyc
|
||||
../flask/testsuite/regression.pyc
|
||||
../flask/testsuite/reqctx.pyc
|
||||
../flask/testsuite/signals.pyc
|
||||
../flask/testsuite/subclassing.pyc
|
||||
../flask/testsuite/templating.pyc
|
||||
../flask/testsuite/testing.pyc
|
||||
../flask/testsuite/views.pyc
|
||||
../flask/testsuite/test_apps/config_module_app.pyc
|
||||
../flask/testsuite/test_apps/flask_newext_simple.pyc
|
||||
../flask/testsuite/test_apps/importerror.pyc
|
||||
../flask/testsuite/test_apps/main_app.pyc
|
||||
../flask/testsuite/test_apps/blueprintapp/__init__.pyc
|
||||
../flask/testsuite/test_apps/blueprintapp/apps/__init__.pyc
|
||||
../flask/testsuite/test_apps/blueprintapp/apps/admin/__init__.pyc
|
||||
../flask/testsuite/test_apps/blueprintapp/apps/frontend/__init__.pyc
|
||||
../flask/testsuite/test_apps/config_package_app/__init__.pyc
|
||||
../flask/testsuite/test_apps/flask_broken/__init__.pyc
|
||||
../flask/testsuite/test_apps/flask_broken/b.pyc
|
||||
../flask/testsuite/test_apps/flask_newext_package/__init__.pyc
|
||||
../flask/testsuite/test_apps/flask_newext_package/submodule.pyc
|
||||
../flask/testsuite/test_apps/flaskext/__init__.pyc
|
||||
../flask/testsuite/test_apps/flaskext/oldext_simple.pyc
|
||||
../flask/testsuite/test_apps/flaskext/oldext_package/__init__.pyc
|
||||
../flask/testsuite/test_apps/flaskext/oldext_package/submodule.pyc
|
||||
../flask/testsuite/test_apps/lib/python2.5/site-packages/site_app.pyc
|
||||
../flask/testsuite/test_apps/lib/python2.5/site-packages/site_package/__init__.pyc
|
||||
../flask/testsuite/test_apps/moduleapp/__init__.pyc
|
||||
../flask/testsuite/test_apps/moduleapp/apps/__init__.pyc
|
||||
../flask/testsuite/test_apps/moduleapp/apps/admin/__init__.pyc
|
||||
../flask/testsuite/test_apps/moduleapp/apps/frontend/__init__.pyc
|
||||
../flask/testsuite/test_apps/path/installed_package/__init__.pyc
|
||||
../flask/testsuite/test_apps/subdomaintestmodule/__init__.pyc
|
||||
./
|
||||
dependency_links.txt
|
||||
not-zip-safe
|
||||
PKG-INFO
|
||||
requires.txt
|
||||
SOURCES.txt
|
||||
top_level.txt
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
Werkzeug>=0.7
|
||||
Jinja2>=2.4
|
||||
itsdangerous>=0.21
|
||||
|
|
@ -0,0 +1 @@
|
|||
flask
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: Flask-Migrate
|
||||
Version: 1.2.0
|
||||
Summary: SQLAlchemy database migrations for Flask applications using Alembic
|
||||
Home-page: http://github.com/miguelgrinberg/flask-migrate/
|
||||
Author: Miguel Grinberg
|
||||
Author-email: miguelgrinberg50@gmail.com
|
||||
License: MIT
|
||||
Description:
|
||||
Flask-Migrate
|
||||
--------------
|
||||
|
||||
SQLAlchemy database migrations for Flask applications using Alembic.
|
||||
|
||||
Platform: any
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
LICENSE
|
||||
MANIFEST.in
|
||||
README.md
|
||||
setup.cfg
|
||||
setup.py
|
||||
Flask_Migrate.egg-info/PKG-INFO
|
||||
Flask_Migrate.egg-info/SOURCES.txt
|
||||
Flask_Migrate.egg-info/dependency_links.txt
|
||||
Flask_Migrate.egg-info/not-zip-safe
|
||||
Flask_Migrate.egg-info/requires.txt
|
||||
Flask_Migrate.egg-info/top_level.txt
|
||||
flask_migrate/__init__.py
|
||||
flask_migrate/templates/flask/README
|
||||
flask_migrate/templates/flask/alembic.ini.mako
|
||||
flask_migrate/templates/flask/env.py
|
||||
flask_migrate/templates/flask/script.py.mako
|
||||
tests/__init__.py
|
||||
tests/__init__.pyc
|
||||
tests/app.py
|
||||
tests/app.pyc
|
||||
tests/app2.py
|
||||
tests/test_migrate.py
|
||||
tests/test_migrate.pyc
|
||||
tests/test_migrate_custom_directory.py
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
../flask_migrate/__init__.py
|
||||
../flask_migrate/templates/flask/README
|
||||
../flask_migrate/templates/flask/alembic.ini.mako
|
||||
../flask_migrate/templates/flask/env.py
|
||||
../flask_migrate/templates/flask/script.py.mako
|
||||
../flask_migrate/__init__.pyc
|
||||
../flask_migrate/templates/flask/env.pyc
|
||||
./
|
||||
dependency_links.txt
|
||||
not-zip-safe
|
||||
PKG-INFO
|
||||
requires.txt
|
||||
SOURCES.txt
|
||||
top_level.txt
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
Flask>=0.9
|
||||
Flask-SQLAlchemy>=1.0
|
||||
alembic>=0.6
|
||||
Flask-Script>=0.6
|
||||
|
|
@ -0,0 +1 @@
|
|||
flask_migrate
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: Flask-SQLAlchemy
|
||||
Version: 1.0
|
||||
Summary: Adds SQLAlchemy support to your Flask application
|
||||
Home-page: http://github.com/mitsuhiko/flask-sqlalchemy
|
||||
Author: Armin Ronacher
|
||||
Author-email: armin.ronacher@active-4.com
|
||||
License: BSD
|
||||
Description:
|
||||
Flask-SQLAlchemy
|
||||
----------------
|
||||
|
||||
Adds SQLAlchemy support to your Flask application.
|
||||
|
||||
Links
|
||||
`````
|
||||
|
||||
* `documentation <http://packages.python.org/Flask-SQLAlchemy>`_
|
||||
* `development version
|
||||
<http://github.com/mitsuhiko/flask-sqlalchemy/zipball/master#egg=Flask-SQLAlchemy-dev>`_
|
||||
|
||||
|
||||
Platform: any
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
CHANGES
|
||||
LICENSE
|
||||
MANIFEST.in
|
||||
README
|
||||
setup.cfg
|
||||
setup.py
|
||||
test_sqlalchemy.py
|
||||
Flask_SQLAlchemy.egg-info/PKG-INFO
|
||||
Flask_SQLAlchemy.egg-info/SOURCES.txt
|
||||
Flask_SQLAlchemy.egg-info/dependency_links.txt
|
||||
Flask_SQLAlchemy.egg-info/not-zip-safe
|
||||
Flask_SQLAlchemy.egg-info/requires.txt
|
||||
Flask_SQLAlchemy.egg-info/top_level.txt
|
||||
docs/Makefile
|
||||
docs/api.rst
|
||||
docs/binds.rst
|
||||
docs/changelog.rst
|
||||
docs/conf.py
|
||||
docs/config.rst
|
||||
docs/contents.rst.inc
|
||||
docs/contexts.rst
|
||||
docs/flaskstyle.sty
|
||||
docs/index.rst
|
||||
docs/logo.pdf
|
||||
docs/make.bat
|
||||
docs/models.rst
|
||||
docs/queries.rst
|
||||
docs/quickstart.rst
|
||||
docs/signals.rst
|
||||
docs/_static/flask-sqlalchemy-small.png
|
||||
docs/_static/flask-sqlalchemy.png
|
||||
docs/_templates/sidebarintro.html
|
||||
docs/_templates/sidebarlogo.html
|
||||
flask_sqlalchemy/__init__.py
|
||||
flask_sqlalchemy/_compat.py
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
../flask_sqlalchemy/__init__.py
|
||||
../flask_sqlalchemy/_compat.py
|
||||
../flask_sqlalchemy/__init__.pyc
|
||||
../flask_sqlalchemy/_compat.pyc
|
||||
./
|
||||
dependency_links.txt
|
||||
not-zip-safe
|
||||
PKG-INFO
|
||||
requires.txt
|
||||
SOURCES.txt
|
||||
top_level.txt
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
setuptools
|
||||
Flask>=0.10
|
||||
SQLAlchemy
|
||||
|
|
@ -0,0 +1 @@
|
|||
flask_sqlalchemy
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: Flask-Script
|
||||
Version: 2.0.3
|
||||
Summary: Scripting support for Flask
|
||||
Home-page: http://github.com/smurfix/flask-script
|
||||
Author: Matthias Urlichs
|
||||
Author-email: matthias@urlichs.de
|
||||
License: BSD
|
||||
Download-URL: https://github.com/smurfix/flask-script/tarball/v2.0.3
|
||||
Description:
|
||||
Flask-Script
|
||||
--------------
|
||||
|
||||
Flask support for writing external scripts.
|
||||
|
||||
Links
|
||||
`````
|
||||
|
||||
* `documentation <http://flask-script.readthedocs.org>`_
|
||||
|
||||
|
||||
|
||||
Platform: any
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
LICENSE
|
||||
MANIFEST.in
|
||||
README.rst
|
||||
setup.cfg
|
||||
setup.py
|
||||
tests.py
|
||||
Flask_Script.egg-info/PKG-INFO
|
||||
Flask_Script.egg-info/SOURCES.txt
|
||||
Flask_Script.egg-info/dependency_links.txt
|
||||
Flask_Script.egg-info/not-zip-safe
|
||||
Flask_Script.egg-info/requires.txt
|
||||
Flask_Script.egg-info/top_level.txt
|
||||
docs/Makefile
|
||||
docs/conf.py
|
||||
docs/index.rst
|
||||
docs/make.bat
|
||||
docs/_static/flask-script.png
|
||||
docs/_static/index.html
|
||||
docs/_themes/README
|
||||
docs/_themes/flask_theme_support.py
|
||||
docs/_themes/flask/theme.conf
|
||||
docs/_themes/flask/static/flasky.css_t
|
||||
docs/_themes/flask_small/layout.html
|
||||
docs/_themes/flask_small/theme.conf
|
||||
docs/_themes/flask_small/static/flasky.css_t
|
||||
flask_script/__init__.py
|
||||
flask_script/_compat.py
|
||||
flask_script/cli.py
|
||||
flask_script/commands.py
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
../flask_script/__init__.py
|
||||
../flask_script/_compat.py
|
||||
../flask_script/cli.py
|
||||
../flask_script/commands.py
|
||||
../flask_script/__init__.pyc
|
||||
../flask_script/_compat.pyc
|
||||
../flask_script/cli.pyc
|
||||
../flask_script/commands.pyc
|
||||
./
|
||||
dependency_links.txt
|
||||
not-zip-safe
|
||||
PKG-INFO
|
||||
requires.txt
|
||||
SOURCES.txt
|
||||
top_level.txt
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1 @@
|
|||
Flask
|
||||
|
|
@ -0,0 +1 @@
|
|||
flask_script
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: Jinja2
|
||||
Version: 2.7.2
|
||||
Summary: A small but fast and easy to use stand-alone template engine written in pure python.
|
||||
Home-page: http://jinja.pocoo.org/
|
||||
Author: Armin Ronacher
|
||||
Author-email: armin.ronacher@active-4.com
|
||||
License: BSD
|
||||
Description:
|
||||
Jinja2
|
||||
~~~~~~
|
||||
|
||||
Jinja2 is a template engine written in pure Python. It provides a
|
||||
`Django`_ inspired non-XML syntax but supports inline expressions and
|
||||
an optional `sandboxed`_ environment.
|
||||
|
||||
Nutshell
|
||||
--------
|
||||
|
||||
Here a small example of a Jinja template::
|
||||
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}Memberlist{% endblock %}
|
||||
{% block content %}
|
||||
<ul>
|
||||
{% for user in users %}
|
||||
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
Philosophy
|
||||
----------
|
||||
|
||||
Application logic is for the controller but don't try to make the life
|
||||
for the template designer too hard by giving him too few functionality.
|
||||
|
||||
For more informations visit the new `Jinja2 webpage`_ and `documentation`_.
|
||||
|
||||
.. _sandboxed: http://en.wikipedia.org/wiki/Sandbox_(computer_security)
|
||||
.. _Django: http://www.djangoproject.com/
|
||||
.. _Jinja2 webpage: http://jinja.pocoo.org/
|
||||
.. _documentation: http://jinja.pocoo.org/2/documentation/
|
||||
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Classifier: Topic :: Text Processing :: Markup :: HTML
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
AUTHORS
|
||||
CHANGES
|
||||
LICENSE
|
||||
MANIFEST.in
|
||||
Makefile
|
||||
README.rst
|
||||
run-tests.py
|
||||
setup.cfg
|
||||
setup.py
|
||||
Jinja2.egg-info/PKG-INFO
|
||||
Jinja2.egg-info/SOURCES.txt
|
||||
Jinja2.egg-info/dependency_links.txt
|
||||
Jinja2.egg-info/entry_points.txt
|
||||
Jinja2.egg-info/not-zip-safe
|
||||
Jinja2.egg-info/requires.txt
|
||||
Jinja2.egg-info/top_level.txt
|
||||
artwork/jinjalogo.svg
|
||||
docs/Makefile
|
||||
docs/api.rst
|
||||
docs/cache_extension.py
|
||||
docs/changelog.rst
|
||||
docs/conf.py
|
||||
docs/contents.rst.inc
|
||||
docs/extensions.rst
|
||||
docs/faq.rst
|
||||
docs/index.rst
|
||||
docs/integration.rst
|
||||
docs/intro.rst
|
||||
docs/jinjaext.py
|
||||
docs/jinjastyle.sty
|
||||
docs/latexindex.rst
|
||||
docs/logo.pdf
|
||||
docs/sandbox.rst
|
||||
docs/switching.rst
|
||||
docs/templates.rst
|
||||
docs/tricks.rst
|
||||
docs/_static/.ignore
|
||||
docs/_static/jinja-small.png
|
||||
docs/_templates/sidebarintro.html
|
||||
docs/_templates/sidebarlogo.html
|
||||
docs/_themes/LICENSE
|
||||
docs/_themes/README
|
||||
docs/_themes/jinja/layout.html
|
||||
docs/_themes/jinja/relations.html
|
||||
docs/_themes/jinja/theme.conf
|
||||
docs/_themes/jinja/static/jinja.css_t
|
||||
examples/bench.py
|
||||
examples/profile.py
|
||||
examples/basic/cycle.py
|
||||
examples/basic/debugger.py
|
||||
examples/basic/inheritance.py
|
||||
examples/basic/test.py
|
||||
examples/basic/test_filter_and_linestatements.py
|
||||
examples/basic/test_loop_filter.py
|
||||
examples/basic/translate.py
|
||||
examples/basic/templates/broken.html
|
||||
examples/basic/templates/subbroken.html
|
||||
examples/rwbench/djangoext.py
|
||||
examples/rwbench/rwbench.py
|
||||
examples/rwbench/django/_form.html
|
||||
examples/rwbench/django/_input_field.html
|
||||
examples/rwbench/django/_textarea.html
|
||||
examples/rwbench/django/index.html
|
||||
examples/rwbench/django/layout.html
|
||||
examples/rwbench/genshi/helpers.html
|
||||
examples/rwbench/genshi/index.html
|
||||
examples/rwbench/genshi/layout.html
|
||||
examples/rwbench/jinja/helpers.html
|
||||
examples/rwbench/jinja/index.html
|
||||
examples/rwbench/jinja/layout.html
|
||||
examples/rwbench/mako/helpers.html
|
||||
examples/rwbench/mako/index.html
|
||||
examples/rwbench/mako/layout.html
|
||||
ext/djangojinja2.py
|
||||
ext/inlinegettext.py
|
||||
ext/jinja.el
|
||||
ext/Vim/jinja.vim
|
||||
ext/django2jinja/django2jinja.py
|
||||
ext/django2jinja/example.py
|
||||
ext/django2jinja/templates/index.html
|
||||
ext/django2jinja/templates/layout.html
|
||||
ext/django2jinja/templates/subtemplate.html
|
||||
jinja2/__init__.py
|
||||
jinja2/_compat.py
|
||||
jinja2/_stringdefs.py
|
||||
jinja2/bccache.py
|
||||
jinja2/compiler.py
|
||||
jinja2/constants.py
|
||||
jinja2/debug.py
|
||||
jinja2/defaults.py
|
||||
jinja2/environment.py
|
||||
jinja2/exceptions.py
|
||||
jinja2/ext.py
|
||||
jinja2/filters.py
|
||||
jinja2/lexer.py
|
||||
jinja2/loaders.py
|
||||
jinja2/meta.py
|
||||
jinja2/nodes.py
|
||||
jinja2/optimizer.py
|
||||
jinja2/parser.py
|
||||
jinja2/runtime.py
|
||||
jinja2/sandbox.py
|
||||
jinja2/tests.py
|
||||
jinja2/utils.py
|
||||
jinja2/visitor.py
|
||||
jinja2/testsuite/__init__.py
|
||||
jinja2/testsuite/api.py
|
||||
jinja2/testsuite/bytecode_cache.py
|
||||
jinja2/testsuite/core_tags.py
|
||||
jinja2/testsuite/debug.py
|
||||
jinja2/testsuite/doctests.py
|
||||
jinja2/testsuite/ext.py
|
||||
jinja2/testsuite/filters.py
|
||||
jinja2/testsuite/imports.py
|
||||
jinja2/testsuite/inheritance.py
|
||||
jinja2/testsuite/lexnparse.py
|
||||
jinja2/testsuite/loader.py
|
||||
jinja2/testsuite/regression.py
|
||||
jinja2/testsuite/security.py
|
||||
jinja2/testsuite/tests.py
|
||||
jinja2/testsuite/utils.py
|
||||
jinja2/testsuite/res/__init__.py
|
||||
jinja2/testsuite/res/templates/broken.html
|
||||
jinja2/testsuite/res/templates/syntaxerror.html
|
||||
jinja2/testsuite/res/templates/test.html
|
||||
jinja2/testsuite/res/templates/foo/test.html
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
[babel.extractors]
|
||||
jinja2 = jinja2.ext:babel_extract[i18n]
|
||||
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
../jinja2/__init__.py
|
||||
../jinja2/_compat.py
|
||||
../jinja2/_stringdefs.py
|
||||
../jinja2/bccache.py
|
||||
../jinja2/compiler.py
|
||||
../jinja2/constants.py
|
||||
../jinja2/debug.py
|
||||
../jinja2/defaults.py
|
||||
../jinja2/environment.py
|
||||
../jinja2/exceptions.py
|
||||
../jinja2/ext.py
|
||||
../jinja2/filters.py
|
||||
../jinja2/lexer.py
|
||||
../jinja2/loaders.py
|
||||
../jinja2/meta.py
|
||||
../jinja2/nodes.py
|
||||
../jinja2/optimizer.py
|
||||
../jinja2/parser.py
|
||||
../jinja2/runtime.py
|
||||
../jinja2/sandbox.py
|
||||
../jinja2/tests.py
|
||||
../jinja2/utils.py
|
||||
../jinja2/visitor.py
|
||||
../jinja2/testsuite/__init__.py
|
||||
../jinja2/testsuite/api.py
|
||||
../jinja2/testsuite/bytecode_cache.py
|
||||
../jinja2/testsuite/core_tags.py
|
||||
../jinja2/testsuite/debug.py
|
||||
../jinja2/testsuite/doctests.py
|
||||
../jinja2/testsuite/ext.py
|
||||
../jinja2/testsuite/filters.py
|
||||
../jinja2/testsuite/imports.py
|
||||
../jinja2/testsuite/inheritance.py
|
||||
../jinja2/testsuite/lexnparse.py
|
||||
../jinja2/testsuite/loader.py
|
||||
../jinja2/testsuite/regression.py
|
||||
../jinja2/testsuite/security.py
|
||||
../jinja2/testsuite/tests.py
|
||||
../jinja2/testsuite/utils.py
|
||||
../jinja2/testsuite/res/__init__.py
|
||||
../jinja2/testsuite/res/templates/broken.html
|
||||
../jinja2/testsuite/res/templates/syntaxerror.html
|
||||
../jinja2/testsuite/res/templates/test.html
|
||||
../jinja2/testsuite/res/templates/foo/test.html
|
||||
../jinja2/__init__.pyc
|
||||
../jinja2/_compat.pyc
|
||||
../jinja2/_stringdefs.pyc
|
||||
../jinja2/bccache.pyc
|
||||
../jinja2/compiler.pyc
|
||||
../jinja2/constants.pyc
|
||||
../jinja2/debug.pyc
|
||||
../jinja2/defaults.pyc
|
||||
../jinja2/environment.pyc
|
||||
../jinja2/exceptions.pyc
|
||||
../jinja2/ext.pyc
|
||||
../jinja2/filters.pyc
|
||||
../jinja2/lexer.pyc
|
||||
../jinja2/loaders.pyc
|
||||
../jinja2/meta.pyc
|
||||
../jinja2/nodes.pyc
|
||||
../jinja2/optimizer.pyc
|
||||
../jinja2/parser.pyc
|
||||
../jinja2/runtime.pyc
|
||||
../jinja2/sandbox.pyc
|
||||
../jinja2/tests.pyc
|
||||
../jinja2/utils.pyc
|
||||
../jinja2/visitor.pyc
|
||||
../jinja2/testsuite/__init__.pyc
|
||||
../jinja2/testsuite/api.pyc
|
||||
../jinja2/testsuite/bytecode_cache.pyc
|
||||
../jinja2/testsuite/core_tags.pyc
|
||||
../jinja2/testsuite/debug.pyc
|
||||
../jinja2/testsuite/doctests.pyc
|
||||
../jinja2/testsuite/ext.pyc
|
||||
../jinja2/testsuite/filters.pyc
|
||||
../jinja2/testsuite/imports.pyc
|
||||
../jinja2/testsuite/inheritance.pyc
|
||||
../jinja2/testsuite/lexnparse.pyc
|
||||
../jinja2/testsuite/loader.pyc
|
||||
../jinja2/testsuite/regression.pyc
|
||||
../jinja2/testsuite/security.pyc
|
||||
../jinja2/testsuite/tests.pyc
|
||||
../jinja2/testsuite/utils.pyc
|
||||
../jinja2/testsuite/res/__init__.pyc
|
||||
./
|
||||
dependency_links.txt
|
||||
entry_points.txt
|
||||
not-zip-safe
|
||||
PKG-INFO
|
||||
requires.txt
|
||||
SOURCES.txt
|
||||
top_level.txt
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
markupsafe
|
||||
|
||||
[i18n]
|
||||
Babel>=0.8
|
||||
|
|
@ -0,0 +1 @@
|
|||
jinja2
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: Mako
|
||||
Version: 0.9.1
|
||||
Summary: A super-fast templating language that borrows the best ideas from the existing templating languages.
|
||||
Home-page: http://www.makotemplates.org/
|
||||
Author: Mike Bayer
|
||||
Author-email: mike@zzzcomputing.com
|
||||
License: MIT
|
||||
Description: =========================
|
||||
Mako Templates for Python
|
||||
=========================
|
||||
|
||||
Mako is a template library written in Python. It provides a familiar, non-XML
|
||||
syntax which compiles into Python modules for maximum performance. Mako's
|
||||
syntax and API borrows from the best ideas of many others, including Django
|
||||
templates, Cheetah, Myghty, and Genshi. Conceptually, Mako is an embedded
|
||||
Python (i.e. Python Server Page) language, which refines the familiar ideas
|
||||
of componentized layout and inheritance to produce one of the most
|
||||
straightforward and flexible models available, while also maintaining close
|
||||
ties to Python calling and scoping semantics.
|
||||
|
||||
Nutshell
|
||||
========
|
||||
|
||||
::
|
||||
|
||||
<%inherit file="base.html"/>
|
||||
<%
|
||||
rows = [[v for v in range(0,10)] for row in range(0,10)]
|
||||
%>
|
||||
<table>
|
||||
% for row in rows:
|
||||
${makerow(row)}
|
||||
% endfor
|
||||
</table>
|
||||
|
||||
<%def name="makerow(row)">
|
||||
<tr>
|
||||
% for name in row:
|
||||
<td>${name}</td>\
|
||||
% endfor
|
||||
</tr>
|
||||
</%def>
|
||||
|
||||
Philosophy
|
||||
===========
|
||||
|
||||
Python is a great scripting language. Don't reinvent the wheel...your templates can handle it !
|
||||
|
||||
Documentation
|
||||
==============
|
||||
|
||||
See documentation for Mako at http://www.makotemplates.org/docs/
|
||||
|
||||
License
|
||||
========
|
||||
|
||||
Mako is licensed under an MIT-style license (see LICENSE).
|
||||
Other incorporated projects may be licensed under different licenses.
|
||||
All licenses allow for non-commercial and commercial use.
|
||||
|
||||
Keywords: templates
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
CHANGES
|
||||
LICENSE
|
||||
MANIFEST.in
|
||||
README.rst
|
||||
distribute_setup.py
|
||||
setup.cfg
|
||||
setup.py
|
||||
Mako.egg-info/PKG-INFO
|
||||
Mako.egg-info/SOURCES.txt
|
||||
Mako.egg-info/dependency_links.txt
|
||||
Mako.egg-info/entry_points.txt
|
||||
Mako.egg-info/not-zip-safe
|
||||
Mako.egg-info/requires.txt
|
||||
Mako.egg-info/top_level.txt
|
||||
doc/caching.html
|
||||
doc/defs.html
|
||||
doc/filtering.html
|
||||
doc/genindex.html
|
||||
doc/index.html
|
||||
doc/inheritance.html
|
||||
doc/namespaces.html
|
||||
doc/runtime.html
|
||||
doc/search.html
|
||||
doc/searchindex.js
|
||||
doc/syntax.html
|
||||
doc/unicode.html
|
||||
doc/usage.html
|
||||
doc/_sources/caching.txt
|
||||
doc/_sources/defs.txt
|
||||
doc/_sources/filtering.txt
|
||||
doc/_sources/index.txt
|
||||
doc/_sources/inheritance.txt
|
||||
doc/_sources/namespaces.txt
|
||||
doc/_sources/runtime.txt
|
||||
doc/_sources/syntax.txt
|
||||
doc/_sources/unicode.txt
|
||||
doc/_sources/usage.txt
|
||||
doc/_static/basic.css
|
||||
doc/_static/comment-bright.png
|
||||
doc/_static/comment-close.png
|
||||
doc/_static/comment.png
|
||||
doc/_static/default.css
|
||||
doc/_static/docs.css
|
||||
doc/_static/doctools.js
|
||||
doc/_static/down-pressed.png
|
||||
doc/_static/down.png
|
||||
doc/_static/file.png
|
||||
doc/_static/jquery.js
|
||||
doc/_static/makoLogo.png
|
||||
doc/_static/minus.png
|
||||
doc/_static/plus.png
|
||||
doc/_static/pygments.css
|
||||
doc/_static/searchtools.js
|
||||
doc/_static/sidebar.js
|
||||
doc/_static/site.css
|
||||
doc/_static/underscore.js
|
||||
doc/_static/up-pressed.png
|
||||
doc/_static/up.png
|
||||
doc/_static/websupport.js
|
||||
doc/build/Makefile
|
||||
doc/build/caching.rst
|
||||
doc/build/conf.py
|
||||
doc/build/defs.rst
|
||||
doc/build/filtering.rst
|
||||
doc/build/index.rst
|
||||
doc/build/inheritance.rst
|
||||
doc/build/namespaces.rst
|
||||
doc/build/runtime.rst
|
||||
doc/build/syntax.rst
|
||||
doc/build/unicode.rst
|
||||
doc/build/usage.rst
|
||||
doc/build/builder/__init__.py
|
||||
doc/build/builder/builders.py
|
||||
doc/build/builder/util.py
|
||||
doc/build/static/docs.css
|
||||
doc/build/static/makoLogo.png
|
||||
doc/build/static/site.css
|
||||
doc/build/templates/base.mako
|
||||
doc/build/templates/genindex.mako
|
||||
doc/build/templates/layout.mako
|
||||
doc/build/templates/page.mako
|
||||
doc/build/templates/rtd_layout.mako
|
||||
doc/build/templates/search.mako
|
||||
examples/bench/basic.py
|
||||
examples/bench/cheetah/footer.tmpl
|
||||
examples/bench/cheetah/header.tmpl
|
||||
examples/bench/cheetah/template.tmpl
|
||||
examples/bench/django/templatetags/__init__.py
|
||||
examples/bench/django/templatetags/bench.py
|
||||
examples/bench/kid/base.kid
|
||||
examples/bench/kid/template.kid
|
||||
examples/bench/myghty/base.myt
|
||||
examples/bench/myghty/template.myt
|
||||
examples/wsgi/run_wsgi.py
|
||||
mako/__init__.py
|
||||
mako/_ast_util.py
|
||||
mako/ast.py
|
||||
mako/cache.py
|
||||
mako/codegen.py
|
||||
mako/compat.py
|
||||
mako/exceptions.py
|
||||
mako/filters.py
|
||||
mako/lexer.py
|
||||
mako/lookup.py
|
||||
mako/parsetree.py
|
||||
mako/pygen.py
|
||||
mako/pyparser.py
|
||||
mako/runtime.py
|
||||
mako/template.py
|
||||
mako/util.py
|
||||
mako/ext/__init__.py
|
||||
mako/ext/autohandler.py
|
||||
mako/ext/babelplugin.py
|
||||
mako/ext/beaker_cache.py
|
||||
mako/ext/preprocessors.py
|
||||
mako/ext/pygmentplugin.py
|
||||
mako/ext/turbogears.py
|
||||
scripts/mako-render
|
||||
test/__init__.py
|
||||
test/sample_module_namespace.py
|
||||
test/test_ast.py
|
||||
test/test_babelplugin.py
|
||||
test/test_block.py
|
||||
test/test_cache.py
|
||||
test/test_call.py
|
||||
test/test_decorators.py
|
||||
test/test_def.py
|
||||
test/test_exceptions.py
|
||||
test/test_filters.py
|
||||
test/test_inheritance.py
|
||||
test/test_lexer.py
|
||||
test/test_lookup.py
|
||||
test/test_loop.py
|
||||
test/test_lru.py
|
||||
test/test_namespace.py
|
||||
test/test_pygen.py
|
||||
test/test_runtime.py
|
||||
test/test_template.py
|
||||
test/test_tgplugin.py
|
||||
test/test_util.py
|
||||
test/util.py
|
||||
test/foo/__init__.py
|
||||
test/foo/test_ns.py
|
||||
test/templates/badbom.html
|
||||
test/templates/bom.html
|
||||
test/templates/bommagic.html
|
||||
test/templates/chs_unicode.html
|
||||
test/templates/chs_unicode_py3k.html
|
||||
test/templates/chs_utf8.html
|
||||
test/templates/crlf.html
|
||||
test/templates/gettext.mako
|
||||
test/templates/index.html
|
||||
test/templates/internationalization.html
|
||||
test/templates/modtest.html
|
||||
test/templates/read_unicode.html
|
||||
test/templates/read_unicode_py3k.html
|
||||
test/templates/runtimeerr.html
|
||||
test/templates/runtimeerr_py3k.html
|
||||
test/templates/unicode.html
|
||||
test/templates/unicode_arguments.html
|
||||
test/templates/unicode_arguments_py3k.html
|
||||
test/templates/unicode_code.html
|
||||
test/templates/unicode_code_py3k.html
|
||||
test/templates/unicode_expr.html
|
||||
test/templates/unicode_expr_py3k.html
|
||||
test/templates/unicode_runtime_error.html
|
||||
test/templates/unicode_syntax_error.html
|
||||
test/templates/foo/modtest.html.py
|
||||
test/templates/othersubdir/foo.html
|
||||
test/templates/subdir/incl.html
|
||||
test/templates/subdir/index.html
|
||||
test/templates/subdir/modtest.html
|
||||
test/templates/subdir/foo/modtest.html.py
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
[python.templating.engines]
|
||||
mako = mako.ext.turbogears:TGPlugin
|
||||
|
||||
[pygments.lexers]
|
||||
mako = mako.ext.pygmentplugin:MakoLexer
|
||||
html+mako = mako.ext.pygmentplugin:MakoHtmlLexer
|
||||
xml+mako = mako.ext.pygmentplugin:MakoXmlLexer
|
||||
js+mako = mako.ext.pygmentplugin:MakoJavascriptLexer
|
||||
css+mako = mako.ext.pygmentplugin:MakoCssLexer
|
||||
|
||||
[babel.extractors]
|
||||
mako = mako.ext.babelplugin:extract
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
../mako/__init__.py
|
||||
../mako/_ast_util.py
|
||||
../mako/ast.py
|
||||
../mako/cache.py
|
||||
../mako/codegen.py
|
||||
../mako/compat.py
|
||||
../mako/exceptions.py
|
||||
../mako/filters.py
|
||||
../mako/lexer.py
|
||||
../mako/lookup.py
|
||||
../mako/parsetree.py
|
||||
../mako/pygen.py
|
||||
../mako/pyparser.py
|
||||
../mako/runtime.py
|
||||
../mako/template.py
|
||||
../mako/util.py
|
||||
../mako/ext/__init__.py
|
||||
../mako/ext/autohandler.py
|
||||
../mako/ext/babelplugin.py
|
||||
../mako/ext/beaker_cache.py
|
||||
../mako/ext/preprocessors.py
|
||||
../mako/ext/pygmentplugin.py
|
||||
../mako/ext/turbogears.py
|
||||
../mako/__init__.pyc
|
||||
../mako/_ast_util.pyc
|
||||
../mako/ast.pyc
|
||||
../mako/cache.pyc
|
||||
../mako/codegen.pyc
|
||||
../mako/compat.pyc
|
||||
../mako/exceptions.pyc
|
||||
../mako/filters.pyc
|
||||
../mako/lexer.pyc
|
||||
../mako/lookup.pyc
|
||||
../mako/parsetree.pyc
|
||||
../mako/pygen.pyc
|
||||
../mako/pyparser.pyc
|
||||
../mako/runtime.pyc
|
||||
../mako/template.pyc
|
||||
../mako/util.pyc
|
||||
../mako/ext/__init__.pyc
|
||||
../mako/ext/autohandler.pyc
|
||||
../mako/ext/babelplugin.pyc
|
||||
../mako/ext/beaker_cache.pyc
|
||||
../mako/ext/preprocessors.pyc
|
||||
../mako/ext/pygmentplugin.pyc
|
||||
../mako/ext/turbogears.pyc
|
||||
./
|
||||
dependency_links.txt
|
||||
entry_points.txt
|
||||
not-zip-safe
|
||||
PKG-INFO
|
||||
requires.txt
|
||||
SOURCES.txt
|
||||
top_level.txt
|
||||
../../../../bin/mako-render
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
MarkupSafe>=0.9.2
|
||||
|
||||
[beaker]
|
||||
Beaker>=1.1
|
||||
|
|
@ -0,0 +1 @@
|
|||
mako
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: MarkupSafe
|
||||
Version: 0.23
|
||||
Summary: Implements a XML/HTML/XHTML Markup safe string for Python
|
||||
Home-page: http://github.com/mitsuhiko/markupsafe
|
||||
Author: Armin Ronacher
|
||||
Author-email: armin.ronacher@active-4.com
|
||||
License: BSD
|
||||
Description: MarkupSafe
|
||||
==========
|
||||
|
||||
Implements a unicode subclass that supports HTML strings:
|
||||
|
||||
>>> from markupsafe import Markup, escape
|
||||
>>> escape("<script>alert(document.cookie);</script>")
|
||||
Markup(u'<script>alert(document.cookie);</script>')
|
||||
>>> tmpl = Markup("<em>%s</em>")
|
||||
>>> tmpl % "Peter > Lustig"
|
||||
Markup(u'<em>Peter > Lustig</em>')
|
||||
|
||||
If you want to make an object unicode that is not yet unicode
|
||||
but don't want to lose the taint information, you can use the
|
||||
`soft_unicode` function. (On Python 3 you can also use `soft_str` which
|
||||
is a different name for the same function).
|
||||
|
||||
>>> from markupsafe import soft_unicode
|
||||
>>> soft_unicode(42)
|
||||
u'42'
|
||||
>>> soft_unicode(Markup('foo'))
|
||||
Markup(u'foo')
|
||||
|
||||
HTML Representations
|
||||
--------------------
|
||||
|
||||
Objects can customize their HTML markup equivalent by overriding
|
||||
the `__html__` function:
|
||||
|
||||
>>> class Foo(object):
|
||||
... def __html__(self):
|
||||
... return '<strong>Nice</strong>'
|
||||
...
|
||||
>>> escape(Foo())
|
||||
Markup(u'<strong>Nice</strong>')
|
||||
>>> Markup(Foo())
|
||||
Markup(u'<strong>Nice</strong>')
|
||||
|
||||
Silent Escapes
|
||||
--------------
|
||||
|
||||
Since MarkupSafe 0.10 there is now also a separate escape function
|
||||
called `escape_silent` that returns an empty string for `None` for
|
||||
consistency with other systems that return empty strings for `None`
|
||||
when escaping (for instance Pylons' webhelpers).
|
||||
|
||||
If you also want to use this for the escape method of the Markup
|
||||
object, you can create your own subclass that does that::
|
||||
|
||||
from markupsafe import Markup, escape_silent as escape
|
||||
|
||||
class SilentMarkup(Markup):
|
||||
__slots__ = ()
|
||||
|
||||
@classmethod
|
||||
def escape(cls, s):
|
||||
return cls(escape(s))
|
||||
|
||||
New-Style String Formatting
|
||||
---------------------------
|
||||
|
||||
Starting with MarkupSafe 0.21 new style string formats from Python 2.6 and
|
||||
3.x are now fully supported. Previously the escape behavior of those
|
||||
functions was spotty at best. The new implementations operates under the
|
||||
following algorithm:
|
||||
|
||||
1. if an object has an ``__html_format__`` method it is called as
|
||||
replacement for ``__format__`` with the format specifier. It either
|
||||
has to return a string or markup object.
|
||||
2. if an object has an ``__html__`` method it is called.
|
||||
3. otherwise the default format system of Python kicks in and the result
|
||||
is HTML escaped.
|
||||
|
||||
Here is how you can implement your own formatting::
|
||||
|
||||
class User(object):
|
||||
|
||||
def __init__(self, id, username):
|
||||
self.id = id
|
||||
self.username = username
|
||||
|
||||
def __html_format__(self, format_spec):
|
||||
if format_spec == 'link':
|
||||
return Markup('<a href="/user/{0}">{1}</a>').format(
|
||||
self.id,
|
||||
self.__html__(),
|
||||
)
|
||||
elif format_spec:
|
||||
raise ValueError('Invalid format spec')
|
||||
return self.__html__()
|
||||
|
||||
def __html__(self):
|
||||
return Markup('<span class=user>{0}</span>').format(self.username)
|
||||
|
||||
And to format that user:
|
||||
|
||||
>>> user = User(1, 'foo')
|
||||
>>> Markup('<p>User: {0:link}').format(user)
|
||||
Markup(u'<p>User: <a href="/user/1"><span class=user>foo</span></a>')
|
||||
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Classifier: Topic :: Text Processing :: Markup :: HTML
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
AUTHORS
|
||||
LICENSE
|
||||
MANIFEST.in
|
||||
README.rst
|
||||
setup.cfg
|
||||
setup.py
|
||||
MarkupSafe.egg-info/PKG-INFO
|
||||
MarkupSafe.egg-info/SOURCES.txt
|
||||
MarkupSafe.egg-info/dependency_links.txt
|
||||
MarkupSafe.egg-info/not-zip-safe
|
||||
MarkupSafe.egg-info/top_level.txt
|
||||
markupsafe/__init__.py
|
||||
markupsafe/_compat.py
|
||||
markupsafe/_constants.py
|
||||
markupsafe/_native.py
|
||||
markupsafe/_speedups.c
|
||||
markupsafe/tests.py
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
../markupsafe/__init__.py
|
||||
../markupsafe/_compat.py
|
||||
../markupsafe/_constants.py
|
||||
../markupsafe/_native.py
|
||||
../markupsafe/tests.py
|
||||
../markupsafe/_speedups.c
|
||||
../markupsafe/__init__.pyc
|
||||
../markupsafe/_compat.pyc
|
||||
../markupsafe/_constants.pyc
|
||||
../markupsafe/_native.pyc
|
||||
../markupsafe/tests.pyc
|
||||
../markupsafe/_speedups.so
|
||||
./
|
||||
dependency_links.txt
|
||||
not-zip-safe
|
||||
PKG-INFO
|
||||
SOURCES.txt
|
||||
top_level.txt
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1 @@
|
|||
markupsafe
|
||||
1423
Darwin/lib/python2.7/site-packages/OpenSSL/SSL.py
Normal file
1423
Darwin/lib/python2.7/site-packages/OpenSSL/SSL.py
Normal file
File diff suppressed because it is too large
Load diff
12
Darwin/lib/python2.7/site-packages/OpenSSL/__init__.py
Normal file
12
Darwin/lib/python2.7/site-packages/OpenSSL/__init__.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Copyright (C) AB Strakt
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
pyOpenSSL - A simple wrapper around the OpenSSL library
|
||||
"""
|
||||
|
||||
from OpenSSL import rand, crypto, SSL
|
||||
from OpenSSL.version import __version__
|
||||
|
||||
__all__ = [
|
||||
'rand', 'crypto', 'SSL', 'tsafe', '__version__']
|
||||
53
Darwin/lib/python2.7/site-packages/OpenSSL/_util.py
Normal file
53
Darwin/lib/python2.7/site-packages/OpenSSL/_util.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
from six import PY3, binary_type, text_type
|
||||
|
||||
from cryptography.hazmat.bindings.openssl.binding import Binding
|
||||
binding = Binding()
|
||||
ffi = binding.ffi
|
||||
lib = binding.lib
|
||||
|
||||
def exception_from_error_queue(exceptionType):
|
||||
def text(charp):
|
||||
return native(ffi.string(charp))
|
||||
|
||||
errors = []
|
||||
while True:
|
||||
error = lib.ERR_get_error()
|
||||
if error == 0:
|
||||
break
|
||||
errors.append((
|
||||
text(lib.ERR_lib_error_string(error)),
|
||||
text(lib.ERR_func_error_string(error)),
|
||||
text(lib.ERR_reason_error_string(error))))
|
||||
|
||||
raise exceptionType(errors)
|
||||
|
||||
|
||||
|
||||
def native(s):
|
||||
"""
|
||||
Convert :py:class:`bytes` or :py:class:`unicode` to the native
|
||||
:py:class:`str` type, using UTF-8 encoding if conversion is necessary.
|
||||
|
||||
:raise UnicodeError: The input string is not UTF-8 decodeable.
|
||||
|
||||
:raise TypeError: The input is neither :py:class:`bytes` nor
|
||||
:py:class:`unicode`.
|
||||
"""
|
||||
if not isinstance(s, (binary_type, text_type)):
|
||||
raise TypeError("%r is neither bytes nor unicode" % s)
|
||||
if PY3:
|
||||
if isinstance(s, binary_type):
|
||||
return s.decode("utf-8")
|
||||
else:
|
||||
if isinstance(s, text_type):
|
||||
return s.encode("utf-8")
|
||||
return s
|
||||
|
||||
|
||||
|
||||
if PY3:
|
||||
def byte_string(s):
|
||||
return s.encode("charmap")
|
||||
else:
|
||||
def byte_string(s):
|
||||
return s
|
||||
2314
Darwin/lib/python2.7/site-packages/OpenSSL/crypto.py
Normal file
2314
Darwin/lib/python2.7/site-packages/OpenSSL/crypto.py
Normal file
File diff suppressed because it is too large
Load diff
180
Darwin/lib/python2.7/site-packages/OpenSSL/rand.py
Normal file
180
Darwin/lib/python2.7/site-packages/OpenSSL/rand.py
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
"""
|
||||
PRNG management routines, thin wrappers.
|
||||
|
||||
See the file RATIONALE for a short explanation of why this module was written.
|
||||
"""
|
||||
|
||||
from functools import partial
|
||||
|
||||
from six import integer_types as _integer_types
|
||||
|
||||
from OpenSSL._util import (
|
||||
ffi as _ffi,
|
||||
lib as _lib,
|
||||
exception_from_error_queue as _exception_from_error_queue)
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
"""
|
||||
An error occurred in an `OpenSSL.rand` API.
|
||||
"""
|
||||
|
||||
_raise_current_error = partial(_exception_from_error_queue, Error)
|
||||
|
||||
_unspecified = object()
|
||||
|
||||
_builtin_bytes = bytes
|
||||
|
||||
def bytes(num_bytes):
|
||||
"""
|
||||
Get some random bytes as a string.
|
||||
|
||||
:param num_bytes: The number of bytes to fetch
|
||||
:return: A string of random bytes
|
||||
"""
|
||||
if not isinstance(num_bytes, _integer_types):
|
||||
raise TypeError("num_bytes must be an integer")
|
||||
|
||||
if num_bytes < 0:
|
||||
raise ValueError("num_bytes must not be negative")
|
||||
|
||||
result_buffer = _ffi.new("char[]", num_bytes)
|
||||
result_code = _lib.RAND_bytes(result_buffer, num_bytes)
|
||||
if result_code == -1:
|
||||
# TODO: No tests for this code path. Triggering a RAND_bytes failure
|
||||
# might involve supplying a custom ENGINE? That's hard.
|
||||
_raise_current_error()
|
||||
|
||||
return _ffi.buffer(result_buffer)[:]
|
||||
|
||||
|
||||
|
||||
def add(buffer, entropy):
|
||||
"""
|
||||
Add data with a given entropy to the PRNG
|
||||
|
||||
:param buffer: Buffer with random data
|
||||
:param entropy: The entropy (in bytes) measurement of the buffer
|
||||
:return: None
|
||||
"""
|
||||
if not isinstance(buffer, _builtin_bytes):
|
||||
raise TypeError("buffer must be a byte string")
|
||||
|
||||
if not isinstance(entropy, int):
|
||||
raise TypeError("entropy must be an integer")
|
||||
|
||||
# TODO Nothing tests this call actually being made, or made properly.
|
||||
_lib.RAND_add(buffer, len(buffer), entropy)
|
||||
|
||||
|
||||
|
||||
def seed(buffer):
|
||||
"""
|
||||
Alias for rand_add, with entropy equal to length
|
||||
|
||||
:param buffer: Buffer with random data
|
||||
:return: None
|
||||
"""
|
||||
if not isinstance(buffer, _builtin_bytes):
|
||||
raise TypeError("buffer must be a byte string")
|
||||
|
||||
# TODO Nothing tests this call actually being made, or made properly.
|
||||
_lib.RAND_seed(buffer, len(buffer))
|
||||
|
||||
|
||||
|
||||
def status():
|
||||
"""
|
||||
Retrieve the status of the PRNG
|
||||
|
||||
:return: True if the PRNG is seeded enough, false otherwise
|
||||
"""
|
||||
return _lib.RAND_status()
|
||||
|
||||
|
||||
|
||||
def egd(path, bytes=_unspecified):
|
||||
"""
|
||||
Query an entropy gathering daemon (EGD) for random data and add it to the
|
||||
PRNG. I haven't found any problems when the socket is missing, the function
|
||||
just returns 0.
|
||||
|
||||
:param path: The path to the EGD socket
|
||||
:param bytes: (optional) The number of bytes to read, default is 255
|
||||
:returns: The number of bytes read (NB: a value of 0 isn't necessarily an
|
||||
error, check rand.status())
|
||||
"""
|
||||
if not isinstance(path, _builtin_bytes):
|
||||
raise TypeError("path must be a byte string")
|
||||
|
||||
if bytes is _unspecified:
|
||||
bytes = 255
|
||||
elif not isinstance(bytes, int):
|
||||
raise TypeError("bytes must be an integer")
|
||||
|
||||
return _lib.RAND_egd_bytes(path, bytes)
|
||||
|
||||
|
||||
|
||||
def cleanup():
|
||||
"""
|
||||
Erase the memory used by the PRNG.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# TODO Nothing tests this call actually being made, or made properly.
|
||||
_lib.RAND_cleanup()
|
||||
|
||||
|
||||
|
||||
def load_file(filename, maxbytes=_unspecified):
|
||||
"""
|
||||
Seed the PRNG with data from a file
|
||||
|
||||
:param filename: The file to read data from
|
||||
:param maxbytes: (optional) The number of bytes to read, default is
|
||||
to read the entire file
|
||||
:return: The number of bytes read
|
||||
"""
|
||||
if not isinstance(filename, _builtin_bytes):
|
||||
raise TypeError("filename must be a string")
|
||||
|
||||
if maxbytes is _unspecified:
|
||||
maxbytes = -1
|
||||
elif not isinstance(maxbytes, int):
|
||||
raise TypeError("maxbytes must be an integer")
|
||||
|
||||
return _lib.RAND_load_file(filename, maxbytes)
|
||||
|
||||
|
||||
|
||||
def write_file(filename):
|
||||
"""
|
||||
Save PRNG state to a file
|
||||
|
||||
:param filename: The file to write data to
|
||||
:return: The number of bytes written
|
||||
"""
|
||||
if not isinstance(filename, _builtin_bytes):
|
||||
raise TypeError("filename must be a string")
|
||||
|
||||
return _lib.RAND_write_file(filename)
|
||||
|
||||
|
||||
# TODO There are no tests for screen at all
|
||||
def screen():
|
||||
"""
|
||||
Add the current contents of the screen to the PRNG state. Availability:
|
||||
Windows.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
_lib.RAND_screen()
|
||||
|
||||
if getattr(_lib, 'RAND_screen', None) is None:
|
||||
del screen
|
||||
|
||||
|
||||
# TODO There are no tests for the RAND strings being loaded, whatever that
|
||||
# means.
|
||||
_lib.ERR_load_RAND_strings()
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Copyright (C) Jean-Paul Calderone
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Package containing unit tests for :py:mod:`OpenSSL`.
|
||||
"""
|
||||
3037
Darwin/lib/python2.7/site-packages/OpenSSL/test/test_crypto.py
Normal file
3037
Darwin/lib/python2.7/site-packages/OpenSSL/test/test_crypto.py
Normal file
File diff suppressed because it is too large
Load diff
203
Darwin/lib/python2.7/site-packages/OpenSSL/test/test_rand.py
Normal file
203
Darwin/lib/python2.7/site-packages/OpenSSL/test/test_rand.py
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
# Copyright (c) Frederick Dean
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Unit tests for :py:obj:`OpenSSL.rand`.
|
||||
"""
|
||||
|
||||
from unittest import main
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
|
||||
from OpenSSL.test.util import TestCase, b
|
||||
from OpenSSL import rand
|
||||
|
||||
|
||||
class RandTests(TestCase):
|
||||
def test_bytes_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.bytes` raises :py:obj:`TypeError` if called with the wrong
|
||||
number of arguments or with a non-:py:obj:`int` argument.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.bytes)
|
||||
self.assertRaises(TypeError, rand.bytes, None)
|
||||
self.assertRaises(TypeError, rand.bytes, 3, None)
|
||||
|
||||
|
||||
def test_insufficientMemory(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.bytes` raises :py:obj:`MemoryError` if more bytes
|
||||
are requested than will fit in memory.
|
||||
"""
|
||||
self.assertRaises(MemoryError, rand.bytes, sys.maxsize)
|
||||
|
||||
|
||||
def test_bytes(self):
|
||||
"""
|
||||
Verify that we can obtain bytes from rand_bytes() and
|
||||
that they are different each time. Test the parameter
|
||||
of rand_bytes() for bad values.
|
||||
"""
|
||||
b1 = rand.bytes(50)
|
||||
self.assertEqual(len(b1), 50)
|
||||
b2 = rand.bytes(num_bytes=50) # parameter by name
|
||||
self.assertNotEqual(b1, b2) # Hip, Hip, Horay! FIPS complaince
|
||||
b3 = rand.bytes(num_bytes=0)
|
||||
self.assertEqual(len(b3), 0)
|
||||
exc = self.assertRaises(ValueError, rand.bytes, -1)
|
||||
self.assertEqual(str(exc), "num_bytes must not be negative")
|
||||
|
||||
|
||||
def test_add_wrong_args(self):
|
||||
"""
|
||||
When called with the wrong number of arguments, or with arguments not of
|
||||
type :py:obj:`str` and :py:obj:`int`, :py:obj:`OpenSSL.rand.add` raises :py:obj:`TypeError`.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.add)
|
||||
self.assertRaises(TypeError, rand.add, b("foo"), None)
|
||||
self.assertRaises(TypeError, rand.add, None, 3)
|
||||
self.assertRaises(TypeError, rand.add, b("foo"), 3, None)
|
||||
|
||||
|
||||
def test_add(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.add` adds entropy to the PRNG.
|
||||
"""
|
||||
rand.add(b('hamburger'), 3)
|
||||
|
||||
|
||||
def test_seed_wrong_args(self):
|
||||
"""
|
||||
When called with the wrong number of arguments, or with a non-:py:obj:`str`
|
||||
argument, :py:obj:`OpenSSL.rand.seed` raises :py:obj:`TypeError`.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.seed)
|
||||
self.assertRaises(TypeError, rand.seed, None)
|
||||
self.assertRaises(TypeError, rand.seed, b("foo"), None)
|
||||
|
||||
|
||||
def test_seed(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.seed` adds entropy to the PRNG.
|
||||
"""
|
||||
rand.seed(b('milk shake'))
|
||||
|
||||
|
||||
def test_status_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.status` raises :py:obj:`TypeError` when called with any
|
||||
arguments.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.status, None)
|
||||
|
||||
|
||||
def test_status(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.status` returns :py:obj:`True` if the PRNG has sufficient
|
||||
entropy, :py:obj:`False` otherwise.
|
||||
"""
|
||||
# It's hard to know what it is actually going to return. Different
|
||||
# OpenSSL random engines decide differently whether they have enough
|
||||
# entropy or not.
|
||||
self.assertTrue(rand.status() in (1, 2))
|
||||
|
||||
|
||||
def test_egd_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.egd` raises :py:obj:`TypeError` when called with the wrong
|
||||
number of arguments or with arguments not of type :py:obj:`str` and :py:obj:`int`.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.egd)
|
||||
self.assertRaises(TypeError, rand.egd, None)
|
||||
self.assertRaises(TypeError, rand.egd, "foo", None)
|
||||
self.assertRaises(TypeError, rand.egd, None, 3)
|
||||
self.assertRaises(TypeError, rand.egd, "foo", 3, None)
|
||||
|
||||
|
||||
def test_egd_missing(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.egd` returns :py:obj:`0` or :py:obj:`-1` if the
|
||||
EGD socket passed to it does not exist.
|
||||
"""
|
||||
result = rand.egd(self.mktemp())
|
||||
expected = (-1, 0)
|
||||
self.assertTrue(
|
||||
result in expected,
|
||||
"%r not in %r" % (result, expected))
|
||||
|
||||
|
||||
def test_egd_missing_and_bytes(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.egd` returns :py:obj:`0` or :py:obj:`-1` if the
|
||||
EGD socket passed to it does not exist even if a size argument is
|
||||
explicitly passed.
|
||||
"""
|
||||
result = rand.egd(self.mktemp(), 1024)
|
||||
expected = (-1, 0)
|
||||
self.assertTrue(
|
||||
result in expected,
|
||||
"%r not in %r" % (result, expected))
|
||||
|
||||
|
||||
def test_cleanup_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.cleanup` raises :py:obj:`TypeError` when called with any
|
||||
arguments.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.cleanup, None)
|
||||
|
||||
|
||||
def test_cleanup(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.cleanup` releases the memory used by the PRNG and returns
|
||||
:py:obj:`None`.
|
||||
"""
|
||||
self.assertIdentical(rand.cleanup(), None)
|
||||
|
||||
|
||||
def test_load_file_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.load_file` raises :py:obj:`TypeError` when called the wrong
|
||||
number of arguments or arguments not of type :py:obj:`str` and :py:obj:`int`.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.load_file)
|
||||
self.assertRaises(TypeError, rand.load_file, "foo", None)
|
||||
self.assertRaises(TypeError, rand.load_file, None, 1)
|
||||
self.assertRaises(TypeError, rand.load_file, "foo", 1, None)
|
||||
|
||||
|
||||
def test_write_file_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.write_file` raises :py:obj:`TypeError` when called with the
|
||||
wrong number of arguments or a non-:py:obj:`str` argument.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.write_file)
|
||||
self.assertRaises(TypeError, rand.write_file, None)
|
||||
self.assertRaises(TypeError, rand.write_file, "foo", None)
|
||||
|
||||
|
||||
def test_files(self):
|
||||
"""
|
||||
Test reading and writing of files via rand functions.
|
||||
"""
|
||||
# Write random bytes to a file
|
||||
tmpfile = self.mktemp()
|
||||
# Make sure it exists (so cleanup definitely succeeds)
|
||||
fObj = open(tmpfile, 'w')
|
||||
fObj.close()
|
||||
try:
|
||||
rand.write_file(tmpfile)
|
||||
# Verify length of written file
|
||||
size = os.stat(tmpfile)[stat.ST_SIZE]
|
||||
self.assertEqual(1024, size)
|
||||
# Read random bytes from file
|
||||
rand.load_file(tmpfile)
|
||||
rand.load_file(tmpfile, 4) # specify a length
|
||||
finally:
|
||||
# Cleanup
|
||||
os.unlink(tmpfile)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
2736
Darwin/lib/python2.7/site-packages/OpenSSL/test/test_ssl.py
Normal file
2736
Darwin/lib/python2.7/site-packages/OpenSSL/test/test_ssl.py
Normal file
File diff suppressed because it is too large
Load diff
302
Darwin/lib/python2.7/site-packages/OpenSSL/test/util.py
Normal file
302
Darwin/lib/python2.7/site-packages/OpenSSL/test/util.py
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
# Copyright (C) Jean-Paul Calderone
|
||||
# Copyright (C) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Helpers for the OpenSSL test suite, largely copied from
|
||||
U{Twisted<http://twistedmatrix.com/>}.
|
||||
"""
|
||||
|
||||
import shutil
|
||||
import traceback
|
||||
import os, os.path
|
||||
from tempfile import mktemp
|
||||
from unittest import TestCase
|
||||
import sys
|
||||
|
||||
from OpenSSL._util import exception_from_error_queue
|
||||
from OpenSSL.crypto import Error
|
||||
|
||||
try:
|
||||
import memdbg
|
||||
except Exception:
|
||||
class _memdbg(object): heap = None
|
||||
memdbg = _memdbg()
|
||||
|
||||
from OpenSSL._util import ffi, lib, byte_string as b
|
||||
|
||||
class TestCase(TestCase):
|
||||
"""
|
||||
:py:class:`TestCase` adds useful testing functionality beyond what is available
|
||||
from the standard library :py:class:`unittest.TestCase`.
|
||||
"""
|
||||
def run(self, result):
|
||||
run = super(TestCase, self).run
|
||||
if memdbg.heap is None:
|
||||
return run(result)
|
||||
|
||||
# Run the test as usual
|
||||
before = set(memdbg.heap)
|
||||
run(result)
|
||||
|
||||
# Clean up some long-lived allocations so they won't be reported as
|
||||
# memory leaks.
|
||||
lib.CRYPTO_cleanup_all_ex_data()
|
||||
lib.ERR_remove_thread_state(ffi.NULL)
|
||||
after = set(memdbg.heap)
|
||||
|
||||
if not after - before:
|
||||
# No leaks, fast succeed
|
||||
return
|
||||
|
||||
if result.wasSuccessful():
|
||||
# If it passed, run it again with memory debugging
|
||||
before = set(memdbg.heap)
|
||||
run(result)
|
||||
|
||||
# Clean up some long-lived allocations so they won't be reported as
|
||||
# memory leaks.
|
||||
lib.CRYPTO_cleanup_all_ex_data()
|
||||
lib.ERR_remove_thread_state(ffi.NULL)
|
||||
|
||||
after = set(memdbg.heap)
|
||||
|
||||
self._reportLeaks(after - before, result)
|
||||
|
||||
|
||||
def _reportLeaks(self, leaks, result):
|
||||
def format_leak(p):
|
||||
stacks = memdbg.heap[p]
|
||||
# Eventually look at multiple stacks for the realloc() case. For
|
||||
# now just look at the original allocation location.
|
||||
(size, python_stack, c_stack) = stacks[0]
|
||||
|
||||
stack = traceback.format_list(python_stack)[:-1]
|
||||
|
||||
# c_stack looks something like this (interesting parts indicated
|
||||
# with inserted arrows not part of the data):
|
||||
#
|
||||
# /home/exarkun/Projects/pyOpenSSL/branches/use-opentls/__pycache__/_cffi__x89095113xb9185b9b.so(+0x12cf) [0x7fe2e20582cf]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyCFunction_Call+0x8b) [0x56265a]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x4d5f52]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyEval_EvalFrameEx+0x753b) [0x4d0e1e]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x4d6419]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x4d6129]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyEval_EvalFrameEx+0x753b) [0x4d0e1e]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyEval_EvalCodeEx+0x1043) [0x4d3726]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x55fd51]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyObject_Call+0x7e) [0x420ee6]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyEval_CallObjectWithKeywords+0x158) [0x4d56ec]
|
||||
# /home/exarkun/.local/lib/python2.7/site-packages/cffi-0.5-py2.7-linux-x86_64.egg/_cffi_backend.so(+0xe96e) [0x7fe2e38be96e]
|
||||
# /usr/lib/x86_64-linux-gnu/libffi.so.6(ffi_closure_unix64_inner+0x1b9) [0x7fe2e36ad819]
|
||||
# /usr/lib/x86_64-linux-gnu/libffi.so.6(ffi_closure_unix64+0x46) [0x7fe2e36adb7c]
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(CRYPTO_malloc+0x64) [0x7fe2e1cef784] <------ end interesting
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(lh_insert+0x16b) [0x7fe2e1d6a24b] .
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(+0x61c18) [0x7fe2e1cf0c18] .
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(+0x625ec) [0x7fe2e1cf15ec] .
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(DSA_new_method+0xe6) [0x7fe2e1d524d6] .
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(DSA_generate_parameters+0x3a) [0x7fe2e1d5364a] <------ begin interesting
|
||||
# /home/exarkun/Projects/opentls/trunk/tls/c/__pycache__/_cffi__x305d4698xb539baaa.so(+0x1f397) [0x7fe2df84d397]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyCFunction_Call+0x8b) [0x56265a]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x4d5f52]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyEval_EvalFrameEx+0x753b) [0x4d0e1e]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x4d6419]
|
||||
# ...
|
||||
#
|
||||
# Notice the stack is upside down compared to a Python traceback.
|
||||
# Identify the start and end of interesting bits and stuff it into the stack we report.
|
||||
|
||||
saved = list(c_stack)
|
||||
|
||||
# Figure the first interesting frame will be after a the cffi-compiled module
|
||||
while c_stack and '/__pycache__/_cffi__' not in c_stack[-1]:
|
||||
c_stack.pop()
|
||||
|
||||
# Figure the last interesting frame will always be CRYPTO_malloc,
|
||||
# since that's where we hooked in to things.
|
||||
while c_stack and 'CRYPTO_malloc' not in c_stack[0] and 'CRYPTO_realloc' not in c_stack[0]:
|
||||
c_stack.pop(0)
|
||||
|
||||
if c_stack:
|
||||
c_stack.reverse()
|
||||
else:
|
||||
c_stack = saved[::-1]
|
||||
stack.extend([frame + "\n" for frame in c_stack])
|
||||
|
||||
stack.insert(0, "Leaked (%s) at:\n")
|
||||
return "".join(stack)
|
||||
|
||||
if leaks:
|
||||
unique_leaks = {}
|
||||
for p in leaks:
|
||||
size = memdbg.heap[p][-1][0]
|
||||
new_leak = format_leak(p)
|
||||
if new_leak not in unique_leaks:
|
||||
unique_leaks[new_leak] = [(size, p)]
|
||||
else:
|
||||
unique_leaks[new_leak].append((size, p))
|
||||
memdbg.free(p)
|
||||
|
||||
for (stack, allocs) in unique_leaks.iteritems():
|
||||
allocs_accum = []
|
||||
for (size, pointer) in allocs:
|
||||
|
||||
addr = int(ffi.cast('uintptr_t', pointer))
|
||||
allocs_accum.append("%d@0x%x" % (size, addr))
|
||||
allocs_report = ", ".join(sorted(allocs_accum))
|
||||
|
||||
result.addError(
|
||||
self,
|
||||
(None, Exception(stack % (allocs_report,)), None))
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Clean up any files or directories created using :py:meth:`TestCase.mktemp`.
|
||||
Subclasses must invoke this method if they override it or the
|
||||
cleanup will not occur.
|
||||
"""
|
||||
if False and self._temporaryFiles is not None:
|
||||
for temp in self._temporaryFiles:
|
||||
if os.path.isdir(temp):
|
||||
shutil.rmtree(temp)
|
||||
elif os.path.exists(temp):
|
||||
os.unlink(temp)
|
||||
try:
|
||||
exception_from_error_queue(Error)
|
||||
except Error:
|
||||
e = sys.exc_info()[1]
|
||||
if e.args != ([],):
|
||||
self.fail("Left over errors in OpenSSL error queue: " + repr(e))
|
||||
|
||||
|
||||
def assertIsInstance(self, instance, classOrTuple, message=None):
|
||||
"""
|
||||
Fail if C{instance} is not an instance of the given class or of
|
||||
one of the given classes.
|
||||
|
||||
@param instance: the object to test the type (first argument of the
|
||||
C{isinstance} call).
|
||||
@type instance: any.
|
||||
@param classOrTuple: the class or classes to test against (second
|
||||
argument of the C{isinstance} call).
|
||||
@type classOrTuple: class, type, or tuple.
|
||||
|
||||
@param message: Custom text to include in the exception text if the
|
||||
assertion fails.
|
||||
"""
|
||||
if not isinstance(instance, classOrTuple):
|
||||
if message is None:
|
||||
suffix = ""
|
||||
else:
|
||||
suffix = ": " + message
|
||||
self.fail("%r is not an instance of %s%s" % (
|
||||
instance, classOrTuple, suffix))
|
||||
|
||||
|
||||
def failUnlessIn(self, containee, container, msg=None):
|
||||
"""
|
||||
Fail the test if :py:data:`containee` is not found in :py:data:`container`.
|
||||
|
||||
:param containee: the value that should be in :py:class:`container`
|
||||
:param container: a sequence type, or in the case of a mapping type,
|
||||
will follow semantics of 'if key in dict.keys()'
|
||||
:param msg: if msg is None, then the failure message will be
|
||||
'%r not in %r' % (first, second)
|
||||
"""
|
||||
if containee not in container:
|
||||
raise self.failureException(msg or "%r not in %r"
|
||||
% (containee, container))
|
||||
return containee
|
||||
assertIn = failUnlessIn
|
||||
|
||||
def failUnlessIdentical(self, first, second, msg=None):
|
||||
"""
|
||||
Fail the test if :py:data:`first` is not :py:data:`second`. This is an
|
||||
obect-identity-equality test, not an object equality
|
||||
(i.e. :py:func:`__eq__`) test.
|
||||
|
||||
:param msg: if msg is None, then the failure message will be
|
||||
'%r is not %r' % (first, second)
|
||||
"""
|
||||
if first is not second:
|
||||
raise self.failureException(msg or '%r is not %r' % (first, second))
|
||||
return first
|
||||
assertIdentical = failUnlessIdentical
|
||||
|
||||
|
||||
def failIfIdentical(self, first, second, msg=None):
|
||||
"""
|
||||
Fail the test if :py:data:`first` is :py:data:`second`. This is an
|
||||
obect-identity-equality test, not an object equality
|
||||
(i.e. :py:func:`__eq__`) test.
|
||||
|
||||
:param msg: if msg is None, then the failure message will be
|
||||
'%r is %r' % (first, second)
|
||||
"""
|
||||
if first is second:
|
||||
raise self.failureException(msg or '%r is %r' % (first, second))
|
||||
return first
|
||||
assertNotIdentical = failIfIdentical
|
||||
|
||||
|
||||
def failUnlessRaises(self, exception, f, *args, **kwargs):
|
||||
"""
|
||||
Fail the test unless calling the function :py:data:`f` with the given
|
||||
:py:data:`args` and :py:data:`kwargs` raises :py:data:`exception`. The
|
||||
failure will report the traceback and call stack of the unexpected
|
||||
exception.
|
||||
|
||||
:param exception: exception type that is to be expected
|
||||
:param f: the function to call
|
||||
|
||||
:return: The raised exception instance, if it is of the given type.
|
||||
:raise self.failureException: Raised if the function call does
|
||||
not raise an exception or if it raises an exception of a
|
||||
different type.
|
||||
"""
|
||||
try:
|
||||
result = f(*args, **kwargs)
|
||||
except exception:
|
||||
inst = sys.exc_info()[1]
|
||||
return inst
|
||||
except:
|
||||
raise self.failureException('%s raised instead of %s'
|
||||
% (sys.exc_info()[0],
|
||||
exception.__name__,
|
||||
))
|
||||
else:
|
||||
raise self.failureException('%s not raised (%r returned)'
|
||||
% (exception.__name__, result))
|
||||
assertRaises = failUnlessRaises
|
||||
|
||||
|
||||
_temporaryFiles = None
|
||||
def mktemp(self):
|
||||
"""
|
||||
Pathetic substitute for twisted.trial.unittest.TestCase.mktemp.
|
||||
"""
|
||||
if self._temporaryFiles is None:
|
||||
self._temporaryFiles = []
|
||||
temp = b(mktemp(dir="."))
|
||||
self._temporaryFiles.append(temp)
|
||||
return temp
|
||||
|
||||
|
||||
# Other stuff
|
||||
def assertConsistentType(self, theType, name, *constructionArgs):
|
||||
"""
|
||||
Perform various assertions about :py:data:`theType` to ensure that it is a
|
||||
well-defined type. This is useful for extension types, where it's
|
||||
pretty easy to do something wacky. If something about the type is
|
||||
unusual, an exception will be raised.
|
||||
|
||||
:param theType: The type object about which to make assertions.
|
||||
:param name: A string giving the name of the type.
|
||||
:param constructionArgs: Positional arguments to use with :py:data:`theType` to
|
||||
create an instance of it.
|
||||
"""
|
||||
self.assertEqual(theType.__name__, name)
|
||||
self.assertTrue(isinstance(theType, type))
|
||||
instance = theType(*constructionArgs)
|
||||
self.assertIdentical(type(instance), theType)
|
||||
28
Darwin/lib/python2.7/site-packages/OpenSSL/tsafe.py
Normal file
28
Darwin/lib/python2.7/site-packages/OpenSSL/tsafe.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
from OpenSSL import SSL
|
||||
_ssl = SSL
|
||||
del SSL
|
||||
|
||||
import threading
|
||||
_RLock = threading.RLock
|
||||
del threading
|
||||
|
||||
class Connection:
|
||||
def __init__(self, *args):
|
||||
self._ssl_conn = apply(_ssl.Connection, args)
|
||||
self._lock = _RLock()
|
||||
|
||||
for f in ('get_context', 'pending', 'send', 'write', 'recv', 'read',
|
||||
'renegotiate', 'bind', 'listen', 'connect', 'accept',
|
||||
'setblocking', 'fileno', 'shutdown', 'close', 'get_cipher_list',
|
||||
'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
|
||||
'makefile', 'get_app_data', 'set_app_data', 'state_string',
|
||||
'sock_shutdown', 'get_peer_certificate', 'get_peer_cert_chain', 'want_read',
|
||||
'want_write', 'set_connect_state', 'set_accept_state',
|
||||
'connect_ex', 'sendall'):
|
||||
exec("""def %s(self, *args):
|
||||
self._lock.acquire()
|
||||
try:
|
||||
return self._ssl_conn.%s(*args)
|
||||
finally:
|
||||
self._lock.release()\n""" % (f, f))
|
||||
|
||||
9
Darwin/lib/python2.7/site-packages/OpenSSL/version.py
Normal file
9
Darwin/lib/python2.7/site-packages/OpenSSL/version.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Copyright (C) AB Strakt
|
||||
# Copyright (C) Jean-Paul Calderone
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
pyOpenSSL - A simple wrapper around the OpenSSL library
|
||||
"""
|
||||
|
||||
__version__ = '0.14'
|
||||
1
Darwin/lib/python2.7/site-packages/PIL.pth
Normal file
1
Darwin/lib/python2.7/site-packages/PIL.pth
Normal file
|
|
@ -0,0 +1 @@
|
|||
PIL
|
||||
504
Darwin/lib/python2.7/site-packages/PIL/ArgImagePlugin.py
Normal file
504
Darwin/lib/python2.7/site-packages/PIL/ArgImagePlugin.py
Normal file
|
|
@ -0,0 +1,504 @@
|
|||
#
|
||||
# THIS IS WORK IN PROGRESS
|
||||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# ARG animation support code
|
||||
#
|
||||
# history:
|
||||
# 1996-12-30 fl Created
|
||||
# 1996-01-06 fl Added safe scripting environment
|
||||
# 1996-01-10 fl Added JHDR, UHDR and sYNC support
|
||||
# 2005-03-02 fl Removed AAPP and ARUN support
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 1997.
|
||||
# Copyright (c) Fredrik Lundh 1996-97.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
__version__ = "0.4"
|
||||
|
||||
import Image, ImageFile, ImagePalette
|
||||
|
||||
from PngImagePlugin import i16, i32, ChunkStream, _MODES
|
||||
|
||||
MAGIC = "\212ARG\r\n\032\n"
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# ARG parser
|
||||
|
||||
class ArgStream(ChunkStream):
|
||||
"Parser callbacks for ARG data"
|
||||
|
||||
def __init__(self, fp):
|
||||
|
||||
ChunkStream.__init__(self, fp)
|
||||
|
||||
self.eof = 0
|
||||
|
||||
self.im = None
|
||||
self.palette = None
|
||||
|
||||
self.__reset()
|
||||
|
||||
def __reset(self):
|
||||
|
||||
# reset decoder state (called on init and sync)
|
||||
|
||||
self.count = 0
|
||||
self.id = None
|
||||
self.action = ("NONE",)
|
||||
|
||||
self.images = {}
|
||||
self.names = {}
|
||||
|
||||
|
||||
def chunk_AHDR(self, offset, bytes):
|
||||
"AHDR -- animation header"
|
||||
|
||||
# assertions
|
||||
if self.count != 0:
|
||||
raise SyntaxError, "misplaced AHDR chunk"
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
self.size = i32(s), i32(s[4:])
|
||||
try:
|
||||
self.mode, self.rawmode = _MODES[(ord(s[8]), ord(s[9]))]
|
||||
except:
|
||||
raise SyntaxError, "unknown ARG mode"
|
||||
|
||||
if Image.DEBUG:
|
||||
print "AHDR size", self.size
|
||||
print "AHDR mode", self.mode, self.rawmode
|
||||
|
||||
return s
|
||||
|
||||
def chunk_AFRM(self, offset, bytes):
|
||||
"AFRM -- next frame follows"
|
||||
|
||||
# assertions
|
||||
if self.count != 0:
|
||||
raise SyntaxError, "misplaced AFRM chunk"
|
||||
|
||||
self.show = 1
|
||||
self.id = 0
|
||||
self.count = 1
|
||||
self.repair = None
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
if len(s) >= 2:
|
||||
self.id = i16(s)
|
||||
if len(s) >= 4:
|
||||
self.count = i16(s[2:4])
|
||||
if len(s) >= 6:
|
||||
self.repair = i16(s[4:6])
|
||||
else:
|
||||
self.repair = None
|
||||
|
||||
if Image.DEBUG:
|
||||
print "AFRM", self.id, self.count
|
||||
|
||||
return s
|
||||
|
||||
def chunk_ADEF(self, offset, bytes):
|
||||
"ADEF -- store image"
|
||||
|
||||
# assertions
|
||||
if self.count != 0:
|
||||
raise SyntaxError, "misplaced ADEF chunk"
|
||||
|
||||
self.show = 0
|
||||
self.id = 0
|
||||
self.count = 1
|
||||
self.repair = None
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
if len(s) >= 2:
|
||||
self.id = i16(s)
|
||||
if len(s) >= 4:
|
||||
self.count = i16(s[2:4])
|
||||
|
||||
if Image.DEBUG:
|
||||
print "ADEF", self.id, self.count
|
||||
|
||||
return s
|
||||
|
||||
def chunk_NAME(self, offset, bytes):
|
||||
"NAME -- name the current image"
|
||||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced NAME chunk"
|
||||
|
||||
name = self.fp.read(bytes)
|
||||
self.names[self.id] = name
|
||||
|
||||
return name
|
||||
|
||||
def chunk_AEND(self, offset, bytes):
|
||||
"AEND -- end of animation"
|
||||
|
||||
if Image.DEBUG:
|
||||
print "AEND"
|
||||
|
||||
self.eof = 1
|
||||
|
||||
raise EOFError, "end of ARG file"
|
||||
|
||||
def __getmodesize(self, s, full=1):
|
||||
|
||||
size = i32(s), i32(s[4:])
|
||||
|
||||
try:
|
||||
mode, rawmode = _MODES[(ord(s[8]), ord(s[9]))]
|
||||
except:
|
||||
raise SyntaxError, "unknown image mode"
|
||||
|
||||
if full:
|
||||
if ord(s[12]):
|
||||
pass # interlace not yet supported
|
||||
if ord(s[11]):
|
||||
raise SyntaxError, "unknown filter category"
|
||||
|
||||
return size, mode, rawmode
|
||||
|
||||
def chunk_PAST(self, offset, bytes):
|
||||
"PAST -- paste one image into another"
|
||||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced PAST chunk"
|
||||
|
||||
if self.repair is not None:
|
||||
# we must repair the target image before we
|
||||
# start pasting
|
||||
|
||||
# brute force; a better solution would be to
|
||||
# update only the dirty rectangles in images[id].
|
||||
# note that if images[id] doesn't exist, it must
|
||||
# be created
|
||||
|
||||
self.images[self.id] = self.images[self.repair].copy()
|
||||
self.repair = None
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
im = self.images[i16(s)]
|
||||
x, y = i32(s[2:6]), i32(s[6:10])
|
||||
bbox = x, y, im.size[0]+x, im.size[1]+y
|
||||
|
||||
if im.mode in ["RGBA"]:
|
||||
# paste with transparency
|
||||
# FIXME: should handle P+transparency as well
|
||||
self.images[self.id].paste(im, bbox, im)
|
||||
else:
|
||||
# paste without transparency
|
||||
self.images[self.id].paste(im, bbox)
|
||||
|
||||
self.action = ("PAST",)
|
||||
self.__store()
|
||||
|
||||
return s
|
||||
|
||||
def chunk_BLNK(self, offset, bytes):
|
||||
"BLNK -- create blank image"
|
||||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced BLNK chunk"
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
size, mode, rawmode = self.__getmodesize(s, 0)
|
||||
|
||||
# store image (FIXME: handle colour)
|
||||
self.action = ("BLNK",)
|
||||
self.im = Image.core.fill(mode, size, 0)
|
||||
self.__store()
|
||||
|
||||
return s
|
||||
|
||||
def chunk_IHDR(self, offset, bytes):
|
||||
"IHDR -- full image follows"
|
||||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced IHDR chunk"
|
||||
|
||||
# image header
|
||||
s = self.fp.read(bytes)
|
||||
size, mode, rawmode = self.__getmodesize(s)
|
||||
|
||||
# decode and store image
|
||||
self.action = ("IHDR",)
|
||||
self.im = Image.core.new(mode, size)
|
||||
self.decoder = Image.core.zip_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
self.data = ""
|
||||
|
||||
return s
|
||||
|
||||
def chunk_DHDR(self, offset, bytes):
|
||||
"DHDR -- delta image follows"
|
||||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced DHDR chunk"
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
|
||||
size, mode, rawmode = self.__getmodesize(s)
|
||||
|
||||
# delta header
|
||||
diff = ord(s[13])
|
||||
offs = i32(s[14:18]), i32(s[18:22])
|
||||
|
||||
bbox = offs + (offs[0]+size[0], offs[1]+size[1])
|
||||
|
||||
if Image.DEBUG:
|
||||
print "DHDR", diff, bbox
|
||||
|
||||
# FIXME: decode and apply image
|
||||
self.action = ("DHDR", diff, bbox)
|
||||
|
||||
# setup decoder
|
||||
self.im = Image.core.new(mode, size)
|
||||
|
||||
self.decoder = Image.core.zip_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
|
||||
self.data = ""
|
||||
|
||||
return s
|
||||
|
||||
def chunk_JHDR(self, offset, bytes):
|
||||
"JHDR -- JPEG image follows"
|
||||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced JHDR chunk"
|
||||
|
||||
# image header
|
||||
s = self.fp.read(bytes)
|
||||
size, mode, rawmode = self.__getmodesize(s, 0)
|
||||
|
||||
# decode and store image
|
||||
self.action = ("JHDR",)
|
||||
self.im = Image.core.new(mode, size)
|
||||
self.decoder = Image.core.jpeg_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
self.data = ""
|
||||
|
||||
return s
|
||||
|
||||
def chunk_UHDR(self, offset, bytes):
|
||||
"UHDR -- uncompressed image data follows (EXPERIMENTAL)"
|
||||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced UHDR chunk"
|
||||
|
||||
# image header
|
||||
s = self.fp.read(bytes)
|
||||
size, mode, rawmode = self.__getmodesize(s, 0)
|
||||
|
||||
# decode and store image
|
||||
self.action = ("UHDR",)
|
||||
self.im = Image.core.new(mode, size)
|
||||
self.decoder = Image.core.raw_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
self.data = ""
|
||||
|
||||
return s
|
||||
|
||||
def chunk_IDAT(self, offset, bytes):
|
||||
"IDAT -- image data block"
|
||||
|
||||
# pass compressed chunks through the decoder
|
||||
s = self.fp.read(bytes)
|
||||
self.data = self.data + s
|
||||
n, e = self.decoder.decode(self.data)
|
||||
if n < 0:
|
||||
# end of image
|
||||
if e < 0:
|
||||
raise IOError, "decoder error %d" % e
|
||||
else:
|
||||
self.data = self.data[n:]
|
||||
|
||||
return s
|
||||
|
||||
def chunk_DEND(self, offset, bytes):
|
||||
return self.chunk_IEND(offset, bytes)
|
||||
|
||||
def chunk_JEND(self, offset, bytes):
|
||||
return self.chunk_IEND(offset, bytes)
|
||||
|
||||
def chunk_UEND(self, offset, bytes):
|
||||
return self.chunk_IEND(offset, bytes)
|
||||
|
||||
def chunk_IEND(self, offset, bytes):
|
||||
"IEND -- end of image"
|
||||
|
||||
# we now have a new image. carry out the operation
|
||||
# defined by the image header.
|
||||
|
||||
# won't need these anymore
|
||||
del self.decoder
|
||||
del self.data
|
||||
|
||||
self.__store()
|
||||
|
||||
return self.fp.read(bytes)
|
||||
|
||||
def __store(self):
|
||||
|
||||
# apply operation
|
||||
cid = self.action[0]
|
||||
|
||||
if cid in ["BLNK", "IHDR", "JHDR", "UHDR"]:
|
||||
# store
|
||||
self.images[self.id] = self.im
|
||||
|
||||
elif cid == "DHDR":
|
||||
# paste
|
||||
cid, mode, bbox = self.action
|
||||
im0 = self.images[self.id]
|
||||
im1 = self.im
|
||||
if mode == 0:
|
||||
im1 = im1.chop_add_modulo(im0.crop(bbox))
|
||||
im0.paste(im1, bbox)
|
||||
|
||||
self.count = self.count - 1
|
||||
|
||||
if self.count == 0 and self.show:
|
||||
self.im = self.images[self.id]
|
||||
raise EOFError # end of this frame
|
||||
|
||||
def chunk_PLTE(self, offset, bytes):
|
||||
"PLTE -- palette data"
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
if self.mode == "P":
|
||||
self.palette = ImagePalette.raw("RGB", s)
|
||||
return s
|
||||
|
||||
def chunk_sYNC(self, offset, bytes):
|
||||
"SYNC -- reset decoder"
|
||||
|
||||
if self.count != 0:
|
||||
raise SyntaxError, "misplaced sYNC chunk"
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
self.__reset()
|
||||
return s
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# ARG reader
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:8] == MAGIC
|
||||
|
||||
##
|
||||
# Image plugin for the experimental Animated Raster Graphics format.
|
||||
|
||||
class ArgImageFile(ImageFile.ImageFile):
|
||||
|
||||
format = "ARG"
|
||||
format_description = "Animated raster graphics"
|
||||
|
||||
def _open(self):
|
||||
|
||||
if Image.warnings:
|
||||
Image.warnings.warn(
|
||||
"The ArgImagePlugin driver is obsolete, and will be removed "
|
||||
"from a future release of PIL. If you rely on this module, "
|
||||
"please contact the PIL authors.",
|
||||
RuntimeWarning
|
||||
)
|
||||
|
||||
if self.fp.read(8) != MAGIC:
|
||||
raise SyntaxError, "not an ARG file"
|
||||
|
||||
self.arg = ArgStream(self.fp)
|
||||
|
||||
# read and process the first chunk (AHDR)
|
||||
|
||||
cid, offset, bytes = self.arg.read()
|
||||
|
||||
if cid != "AHDR":
|
||||
raise SyntaxError, "expected an AHDR chunk"
|
||||
|
||||
s = self.arg.call(cid, offset, bytes)
|
||||
|
||||
self.arg.crc(cid, s)
|
||||
|
||||
# image characteristics
|
||||
self.mode = self.arg.mode
|
||||
self.size = self.arg.size
|
||||
|
||||
def load(self):
|
||||
|
||||
if self.arg.im is None:
|
||||
self.seek(0)
|
||||
|
||||
# image data
|
||||
self.im = self.arg.im
|
||||
self.palette = self.arg.palette
|
||||
|
||||
# set things up for further processing
|
||||
Image.Image.load(self)
|
||||
|
||||
def seek(self, frame):
|
||||
|
||||
if self.arg.eof:
|
||||
raise EOFError, "end of animation"
|
||||
|
||||
self.fp = self.arg.fp
|
||||
|
||||
while 1:
|
||||
|
||||
#
|
||||
# process chunks
|
||||
|
||||
cid, offset, bytes = self.arg.read()
|
||||
|
||||
if self.arg.eof:
|
||||
raise EOFError, "end of animation"
|
||||
|
||||
try:
|
||||
s = self.arg.call(cid, offset, bytes)
|
||||
except EOFError:
|
||||
break
|
||||
|
||||
except "glurk": # AttributeError
|
||||
if Image.DEBUG:
|
||||
print cid, bytes, "(unknown)"
|
||||
s = self.fp.read(bytes)
|
||||
|
||||
self.arg.crc(cid, s)
|
||||
|
||||
self.fp.read(4) # ship extra CRC
|
||||
|
||||
def tell(self):
|
||||
return 0
|
||||
|
||||
def verify(self):
|
||||
"Verify ARG file"
|
||||
|
||||
# back up to first chunk
|
||||
self.fp.seek(8)
|
||||
|
||||
self.arg.verify(self)
|
||||
self.arg.close()
|
||||
|
||||
self.fp = None
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
Image.register_open("ARG", ArgImageFile, _accept)
|
||||
|
||||
Image.register_extension("ARG", ".arg")
|
||||
|
||||
Image.register_mime("ARG", "video/x-arg")
|
||||
133
Darwin/lib/python2.7/site-packages/PIL/BdfFontFile.py
Normal file
133
Darwin/lib/python2.7/site-packages/PIL/BdfFontFile.py
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# bitmap distribution font (bdf) file parser
|
||||
#
|
||||
# history:
|
||||
# 1996-05-16 fl created (as bdf2pil)
|
||||
# 1997-08-25 fl converted to FontFile driver
|
||||
# 2001-05-25 fl removed bogus __init__ call
|
||||
# 2002-11-20 fl robustification (from Kevin Cazabon, Dmitry Vasiliev)
|
||||
# 2003-04-22 fl more robustification (from Graham Dumpleton)
|
||||
#
|
||||
# Copyright (c) 1997-2003 by Secret Labs AB.
|
||||
# Copyright (c) 1997-2003 by Fredrik Lundh.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
import FontFile
|
||||
|
||||
import string
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# parse X Bitmap Distribution Format (BDF)
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
bdf_slant = {
|
||||
"R": "Roman",
|
||||
"I": "Italic",
|
||||
"O": "Oblique",
|
||||
"RI": "Reverse Italic",
|
||||
"RO": "Reverse Oblique",
|
||||
"OT": "Other"
|
||||
}
|
||||
|
||||
bdf_spacing = {
|
||||
"P": "Proportional",
|
||||
"M": "Monospaced",
|
||||
"C": "Cell"
|
||||
}
|
||||
|
||||
def bdf_char(f):
|
||||
|
||||
# skip to STARTCHAR
|
||||
while 1:
|
||||
s = f.readline()
|
||||
if not s:
|
||||
return None
|
||||
if s[:9] == "STARTCHAR":
|
||||
break
|
||||
id = string.strip(s[9:])
|
||||
|
||||
# load symbol properties
|
||||
props = {}
|
||||
while 1:
|
||||
s = f.readline()
|
||||
if not s or s[:6] == "BITMAP":
|
||||
break
|
||||
i = string.find(s, " ")
|
||||
props[s[:i]] = s[i+1:-1]
|
||||
|
||||
# load bitmap
|
||||
bitmap = []
|
||||
while 1:
|
||||
s = f.readline()
|
||||
if not s or s[:7] == "ENDCHAR":
|
||||
break
|
||||
bitmap.append(s[:-1])
|
||||
bitmap = string.join(bitmap, "")
|
||||
|
||||
[x, y, l, d] = map(int, string.split(props["BBX"]))
|
||||
[dx, dy] = map(int, string.split(props["DWIDTH"]))
|
||||
|
||||
bbox = (dx, dy), (l, -d-y, x+l, -d), (0, 0, x, y)
|
||||
|
||||
try:
|
||||
im = Image.fromstring("1", (x, y), bitmap, "hex", "1")
|
||||
except ValueError:
|
||||
# deal with zero-width characters
|
||||
im = Image.new("1", (x, y))
|
||||
|
||||
return id, int(props["ENCODING"]), bbox, im
|
||||
|
||||
##
|
||||
# Font file plugin for the X11 BDF format.
|
||||
|
||||
class BdfFontFile(FontFile.FontFile):
|
||||
|
||||
def __init__(self, fp):
|
||||
|
||||
FontFile.FontFile.__init__(self)
|
||||
|
||||
s = fp.readline()
|
||||
if s[:13] != "STARTFONT 2.1":
|
||||
raise SyntaxError, "not a valid BDF file"
|
||||
|
||||
props = {}
|
||||
comments = []
|
||||
|
||||
while 1:
|
||||
s = fp.readline()
|
||||
if not s or s[:13] == "ENDPROPERTIES":
|
||||
break
|
||||
i = string.find(s, " ")
|
||||
props[s[:i]] = s[i+1:-1]
|
||||
if s[:i] in ["COMMENT", "COPYRIGHT"]:
|
||||
if string.find(s, "LogicalFontDescription") < 0:
|
||||
comments.append(s[i+1:-1])
|
||||
|
||||
font = string.split(props["FONT"], "-")
|
||||
|
||||
font[4] = bdf_slant[string.upper(font[4])]
|
||||
font[11] = bdf_spacing[string.upper(font[11])]
|
||||
|
||||
ascent = int(props["FONT_ASCENT"])
|
||||
descent = int(props["FONT_DESCENT"])
|
||||
|
||||
fontname = string.join(font[1:], ";")
|
||||
|
||||
# print "#", fontname
|
||||
# for i in comments:
|
||||
# print "#", i
|
||||
|
||||
font = []
|
||||
while 1:
|
||||
c = bdf_char(fp)
|
||||
if not c:
|
||||
break
|
||||
id, ch, (xy, dst, src), im = c
|
||||
if ch >= 0 and ch < len(self.glyph):
|
||||
self.glyph[ch] = xy, dst, src, im
|
||||
251
Darwin/lib/python2.7/site-packages/PIL/BmpImagePlugin.py
Normal file
251
Darwin/lib/python2.7/site-packages/PIL/BmpImagePlugin.py
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# BMP file handler
|
||||
#
|
||||
# Windows (and OS/2) native bitmap storage format.
|
||||
#
|
||||
# history:
|
||||
# 1995-09-01 fl Created
|
||||
# 1996-04-30 fl Added save
|
||||
# 1997-08-27 fl Fixed save of 1-bit images
|
||||
# 1998-03-06 fl Load P images as L where possible
|
||||
# 1998-07-03 fl Load P images as 1 where possible
|
||||
# 1998-12-29 fl Handle small palettes
|
||||
# 2002-12-30 fl Fixed load of 1-bit palette images
|
||||
# 2003-04-21 fl Fixed load of 1-bit monochrome images
|
||||
# 2003-04-23 fl Added limited support for BI_BITFIELDS compression
|
||||
#
|
||||
# Copyright (c) 1997-2003 by Secret Labs AB
|
||||
# Copyright (c) 1995-2003 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
|
||||
__version__ = "0.7"
|
||||
|
||||
|
||||
import string
|
||||
import Image, ImageFile, ImagePalette
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Read BMP file
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
|
||||
BIT2MODE = {
|
||||
# bits => mode, rawmode
|
||||
1: ("P", "P;1"),
|
||||
4: ("P", "P;4"),
|
||||
8: ("P", "P"),
|
||||
16: ("RGB", "BGR;15"),
|
||||
24: ("RGB", "BGR"),
|
||||
32: ("RGB", "BGRX")
|
||||
}
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:2] == "BM"
|
||||
|
||||
##
|
||||
# Image plugin for the Windows BMP format.
|
||||
|
||||
class BmpImageFile(ImageFile.ImageFile):
|
||||
|
||||
format = "BMP"
|
||||
format_description = "Windows Bitmap"
|
||||
|
||||
def _bitmap(self, header = 0, offset = 0):
|
||||
|
||||
if header:
|
||||
self.fp.seek(header)
|
||||
|
||||
read = self.fp.read
|
||||
|
||||
# CORE/INFO
|
||||
s = read(4)
|
||||
s = s + ImageFile._safe_read(self.fp, i32(s)-4)
|
||||
|
||||
if len(s) == 12:
|
||||
|
||||
# OS/2 1.0 CORE
|
||||
bits = i16(s[10:])
|
||||
self.size = i16(s[4:]), i16(s[6:])
|
||||
compression = 0
|
||||
lutsize = 3
|
||||
colors = 0
|
||||
direction = -1
|
||||
|
||||
elif len(s) in [40, 64]:
|
||||
|
||||
# WIN 3.1 or OS/2 2.0 INFO
|
||||
bits = i16(s[14:])
|
||||
self.size = i32(s[4:]), i32(s[8:])
|
||||
compression = i32(s[16:])
|
||||
lutsize = 4
|
||||
colors = i32(s[32:])
|
||||
direction = -1
|
||||
if s[11] == '\xff':
|
||||
# upside-down storage
|
||||
self.size = self.size[0], 2**32 - self.size[1]
|
||||
direction = 0
|
||||
|
||||
else:
|
||||
raise IOError("Unsupported BMP header type (%d)" % len(s))
|
||||
|
||||
if not colors:
|
||||
colors = 1 << bits
|
||||
|
||||
# MODE
|
||||
try:
|
||||
self.mode, rawmode = BIT2MODE[bits]
|
||||
except KeyError:
|
||||
raise IOError("Unsupported BMP pixel depth (%d)" % bits)
|
||||
|
||||
if compression == 3:
|
||||
# BI_BITFIELDS compression
|
||||
mask = i32(read(4)), i32(read(4)), i32(read(4))
|
||||
if bits == 32 and mask == (0xff0000, 0x00ff00, 0x0000ff):
|
||||
rawmode = "BGRX"
|
||||
elif bits == 16 and mask == (0x00f800, 0x0007e0, 0x00001f):
|
||||
rawmode = "BGR;16"
|
||||
elif bits == 16 and mask == (0x007c00, 0x0003e0, 0x00001f):
|
||||
rawmode = "BGR;15"
|
||||
else:
|
||||
# print bits, map(hex, mask)
|
||||
raise IOError("Unsupported BMP bitfields layout")
|
||||
elif compression != 0:
|
||||
raise IOError("Unsupported BMP compression (%d)" % compression)
|
||||
|
||||
# LUT
|
||||
if self.mode == "P":
|
||||
palette = []
|
||||
greyscale = 1
|
||||
if colors == 2:
|
||||
indices = (0, 255)
|
||||
else:
|
||||
indices = range(colors)
|
||||
for i in indices:
|
||||
rgb = read(lutsize)[:3]
|
||||
if rgb != chr(i)*3:
|
||||
greyscale = 0
|
||||
palette.append(rgb)
|
||||
if greyscale:
|
||||
if colors == 2:
|
||||
self.mode = rawmode = "1"
|
||||
else:
|
||||
self.mode = rawmode = "L"
|
||||
else:
|
||||
self.mode = "P"
|
||||
self.palette = ImagePalette.raw(
|
||||
"BGR", string.join(palette, "")
|
||||
)
|
||||
|
||||
if not offset:
|
||||
offset = self.fp.tell()
|
||||
|
||||
self.tile = [("raw",
|
||||
(0, 0) + self.size,
|
||||
offset,
|
||||
(rawmode, ((self.size[0]*bits+31)>>3)&(~3), direction))]
|
||||
|
||||
self.info["compression"] = compression
|
||||
|
||||
def _open(self):
|
||||
|
||||
# HEAD
|
||||
s = self.fp.read(14)
|
||||
if s[:2] != "BM":
|
||||
raise SyntaxError("Not a BMP file")
|
||||
offset = i32(s[10:])
|
||||
|
||||
self._bitmap(offset=offset)
|
||||
|
||||
|
||||
class DibImageFile(BmpImageFile):
|
||||
|
||||
format = "DIB"
|
||||
format_description = "Windows Bitmap"
|
||||
|
||||
def _open(self):
|
||||
self._bitmap()
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Write BMP file
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
|
||||
def o32(i):
|
||||
return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
|
||||
|
||||
SAVE = {
|
||||
"1": ("1", 1, 2),
|
||||
"L": ("L", 8, 256),
|
||||
"P": ("P", 8, 256),
|
||||
"RGB": ("BGR", 24, 0),
|
||||
}
|
||||
|
||||
def _save(im, fp, filename, check=0):
|
||||
|
||||
try:
|
||||
rawmode, bits, colors = SAVE[im.mode]
|
||||
except KeyError:
|
||||
raise IOError("cannot write mode %s as BMP" % im.mode)
|
||||
|
||||
if check:
|
||||
return check
|
||||
|
||||
stride = ((im.size[0]*bits+7)/8+3)&(~3)
|
||||
header = 40 # or 64 for OS/2 version 2
|
||||
offset = 14 + header + colors * 4
|
||||
image = stride * im.size[1]
|
||||
|
||||
# bitmap header
|
||||
fp.write("BM" + # file type (magic)
|
||||
o32(offset+image) + # file size
|
||||
o32(0) + # reserved
|
||||
o32(offset)) # image data offset
|
||||
|
||||
# bitmap info header
|
||||
fp.write(o32(header) + # info header size
|
||||
o32(im.size[0]) + # width
|
||||
o32(im.size[1]) + # height
|
||||
o16(1) + # planes
|
||||
o16(bits) + # depth
|
||||
o32(0) + # compression (0=uncompressed)
|
||||
o32(image) + # size of bitmap
|
||||
o32(1) + o32(1) + # resolution
|
||||
o32(colors) + # colors used
|
||||
o32(colors)) # colors important
|
||||
|
||||
fp.write("\000" * (header - 40)) # padding (for OS/2 format)
|
||||
|
||||
if im.mode == "1":
|
||||
for i in (0, 255):
|
||||
fp.write(chr(i) * 4)
|
||||
elif im.mode == "L":
|
||||
for i in range(256):
|
||||
fp.write(chr(i) * 4)
|
||||
elif im.mode == "P":
|
||||
fp.write(im.im.getpalette("RGB", "BGRX"))
|
||||
|
||||
ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, stride, -1))])
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Registry
|
||||
|
||||
Image.register_open(BmpImageFile.format, BmpImageFile, _accept)
|
||||
Image.register_save(BmpImageFile.format, _save)
|
||||
|
||||
Image.register_extension(BmpImageFile.format, ".bmp")
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# BUFR stub adapter
|
||||
#
|
||||
# Copyright (c) 1996-2003 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
|
||||
_handler = None
|
||||
|
||||
##
|
||||
# Install application-specific BUFR image handler.
|
||||
#
|
||||
# @param handler Handler object.
|
||||
|
||||
def register_handler(handler):
|
||||
global _handler
|
||||
_handler = handler
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "BUFR" or prefix[:4] == "ZCZC"
|
||||
|
||||
class BufrStubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
format = "BUFR"
|
||||
format_description = "BUFR"
|
||||
|
||||
def _open(self):
|
||||
|
||||
offset = self.fp.tell()
|
||||
|
||||
if not _accept(self.fp.read(8)):
|
||||
raise SyntaxError("Not a BUFR file")
|
||||
|
||||
self.fp.seek(offset)
|
||||
|
||||
# make something up
|
||||
self.mode = "F"
|
||||
self.size = 1, 1
|
||||
|
||||
loader = self._load()
|
||||
if loader:
|
||||
loader.open(self)
|
||||
|
||||
def _load(self):
|
||||
return _handler
|
||||
|
||||
def _save(im, fp, filename):
|
||||
if _handler is None or not hasattr("_handler", "save"):
|
||||
raise IOError("BUFR save handler not installed")
|
||||
_handler.save(im, fp, filename)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Registry
|
||||
|
||||
Image.register_open(BufrStubImageFile.format, BufrStubImageFile, _accept)
|
||||
Image.register_save(BufrStubImageFile.format, _save)
|
||||
|
||||
Image.register_extension(BufrStubImageFile.format, ".bufr")
|
||||
116
Darwin/lib/python2.7/site-packages/PIL/ContainerIO.py
Normal file
116
Darwin/lib/python2.7/site-packages/PIL/ContainerIO.py
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# a class to read from a container file
|
||||
#
|
||||
# History:
|
||||
# 1995-06-18 fl Created
|
||||
# 1995-09-07 fl Added readline(), readlines()
|
||||
#
|
||||
# Copyright (c) 1997-2001 by Secret Labs AB
|
||||
# Copyright (c) 1995 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
##
|
||||
# A file object that provides read access to a part of an existing
|
||||
# file (for example a TAR file).
|
||||
|
||||
class ContainerIO:
|
||||
|
||||
##
|
||||
# Create file object.
|
||||
#
|
||||
# @param file Existing file.
|
||||
# @param offset Start of region, in bytes.
|
||||
# @param length Size of region, in bytes.
|
||||
|
||||
def __init__(self, file, offset, length):
|
||||
self.fh = file
|
||||
self.pos = 0
|
||||
self.offset = offset
|
||||
self.length = length
|
||||
self.fh.seek(offset)
|
||||
|
||||
##
|
||||
# Always false.
|
||||
|
||||
def isatty(self):
|
||||
return 0
|
||||
|
||||
##
|
||||
# Move file pointer.
|
||||
#
|
||||
# @param offset Offset in bytes.
|
||||
# @param mode Starting position. Use 0 for beginning of region, 1
|
||||
# for current offset, and 2 for end of region. You cannot move
|
||||
# the pointer outside the defined region.
|
||||
|
||||
def seek(self, offset, mode = 0):
|
||||
if mode == 1:
|
||||
self.pos = self.pos + offset
|
||||
elif mode == 2:
|
||||
self.pos = self.length + offset
|
||||
else:
|
||||
self.pos = offset
|
||||
# clamp
|
||||
self.pos = max(0, min(self.pos, self.length))
|
||||
self.fh.seek(self.offset + self.pos)
|
||||
|
||||
##
|
||||
# Get current file pointer.
|
||||
#
|
||||
# @return Offset from start of region, in bytes.
|
||||
|
||||
def tell(self):
|
||||
return self.pos
|
||||
|
||||
##
|
||||
# Read data.
|
||||
#
|
||||
# @def read(bytes=0)
|
||||
# @param bytes Number of bytes to read. If omitted or zero,
|
||||
# read until end of region.
|
||||
# @return An 8-bit string.
|
||||
|
||||
def read(self, n = 0):
|
||||
if n:
|
||||
n = min(n, self.length - self.pos)
|
||||
else:
|
||||
n = self.length - self.pos
|
||||
if not n: # EOF
|
||||
return ""
|
||||
self.pos = self.pos + n
|
||||
return self.fh.read(n)
|
||||
|
||||
##
|
||||
# Read a line of text.
|
||||
#
|
||||
# @return An 8-bit string.
|
||||
|
||||
def readline(self):
|
||||
s = ""
|
||||
while 1:
|
||||
c = self.read(1)
|
||||
if not c:
|
||||
break
|
||||
s = s + c
|
||||
if c == "\n":
|
||||
break
|
||||
return s
|
||||
|
||||
##
|
||||
# Read multiple lines of text.
|
||||
#
|
||||
# @return A list of 8-bit strings.
|
||||
|
||||
def readlines(self):
|
||||
l = []
|
||||
while 1:
|
||||
s = self.readline()
|
||||
if not s:
|
||||
break
|
||||
l.append(s)
|
||||
return l
|
||||
88
Darwin/lib/python2.7/site-packages/PIL/CurImagePlugin.py
Normal file
88
Darwin/lib/python2.7/site-packages/PIL/CurImagePlugin.py
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# Windows Cursor support for PIL
|
||||
#
|
||||
# notes:
|
||||
# uses BmpImagePlugin.py to read the bitmap data.
|
||||
#
|
||||
# history:
|
||||
# 96-05-27 fl Created
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 1997.
|
||||
# Copyright (c) Fredrik Lundh 1996.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
|
||||
__version__ = "0.1"
|
||||
|
||||
import Image, BmpImagePlugin
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "\0\0\2\0"
|
||||
|
||||
##
|
||||
# Image plugin for Windows Cursor files.
|
||||
|
||||
class CurImageFile(BmpImagePlugin.BmpImageFile):
|
||||
|
||||
format = "CUR"
|
||||
format_description = "Windows Cursor"
|
||||
|
||||
def _open(self):
|
||||
|
||||
offset = self.fp.tell()
|
||||
|
||||
# check magic
|
||||
s = self.fp.read(6)
|
||||
if not _accept(s):
|
||||
raise SyntaxError, "not an CUR file"
|
||||
|
||||
# pick the largest cursor in the file
|
||||
m = ""
|
||||
for i in range(i16(s[4:])):
|
||||
s = self.fp.read(16)
|
||||
if not m:
|
||||
m = s
|
||||
elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]):
|
||||
m = s
|
||||
#print "width", ord(s[0])
|
||||
#print "height", ord(s[1])
|
||||
#print "colors", ord(s[2])
|
||||
#print "reserved", ord(s[3])
|
||||
#print "hotspot x", i16(s[4:])
|
||||
#print "hotspot y", i16(s[6:])
|
||||
#print "bytes", i32(s[8:])
|
||||
#print "offset", i32(s[12:])
|
||||
|
||||
# load as bitmap
|
||||
self._bitmap(i32(m[12:]) + offset)
|
||||
|
||||
# patch up the bitmap height
|
||||
self.size = self.size[0], self.size[1]/2
|
||||
d, e, o, a = self.tile[0]
|
||||
self.tile[0] = d, (0,0)+self.size, o, a
|
||||
|
||||
return
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
Image.register_open("CUR", CurImageFile, _accept)
|
||||
|
||||
Image.register_extension("CUR", ".cur")
|
||||
78
Darwin/lib/python2.7/site-packages/PIL/DcxImagePlugin.py
Normal file
78
Darwin/lib/python2.7/site-packages/PIL/DcxImagePlugin.py
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# DCX file handling
|
||||
#
|
||||
# DCX is a container file format defined by Intel, commonly used
|
||||
# for fax applications. Each DCX file consists of a directory
|
||||
# (a list of file offsets) followed by a set of (usually 1-bit)
|
||||
# PCX files.
|
||||
#
|
||||
# History:
|
||||
# 1995-09-09 fl Created
|
||||
# 1996-03-20 fl Properly derived from PcxImageFile.
|
||||
# 1998-07-15 fl Renamed offset attribute to avoid name clash
|
||||
# 2002-07-30 fl Fixed file handling
|
||||
#
|
||||
# Copyright (c) 1997-98 by Secret Labs AB.
|
||||
# Copyright (c) 1995-96 by Fredrik Lundh.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
__version__ = "0.2"
|
||||
|
||||
import Image
|
||||
|
||||
from PcxImagePlugin import PcxImageFile
|
||||
|
||||
MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then?
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
def _accept(prefix):
|
||||
return i32(prefix) == MAGIC
|
||||
|
||||
##
|
||||
# Image plugin for the Intel DCX format.
|
||||
|
||||
class DcxImageFile(PcxImageFile):
|
||||
|
||||
format = "DCX"
|
||||
format_description = "Intel DCX"
|
||||
|
||||
def _open(self):
|
||||
|
||||
# Header
|
||||
s = self.fp.read(4)
|
||||
if i32(s) != MAGIC:
|
||||
raise SyntaxError, "not a DCX file"
|
||||
|
||||
# Component directory
|
||||
self._offset = []
|
||||
for i in range(1024):
|
||||
offset = i32(self.fp.read(4))
|
||||
if not offset:
|
||||
break
|
||||
self._offset.append(offset)
|
||||
|
||||
self.__fp = self.fp
|
||||
self.seek(0)
|
||||
|
||||
def seek(self, frame):
|
||||
if frame >= len(self._offset):
|
||||
raise EOFError("attempt to seek outside DCX directory")
|
||||
self.frame = frame
|
||||
self.fp = self.__fp
|
||||
self.fp.seek(self._offset[frame])
|
||||
PcxImageFile._open(self)
|
||||
|
||||
def tell(self):
|
||||
return self.frame
|
||||
|
||||
|
||||
Image.register_open("DCX", DcxImageFile, _accept)
|
||||
|
||||
Image.register_extension("DCX", ".dcx")
|
||||
349
Darwin/lib/python2.7/site-packages/PIL/EpsImagePlugin.py
Normal file
349
Darwin/lib/python2.7/site-packages/PIL/EpsImagePlugin.py
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# EPS file handling
|
||||
#
|
||||
# History:
|
||||
# 1995-09-01 fl Created (0.1)
|
||||
# 1996-05-18 fl Don't choke on "atend" fields, Ghostscript interface (0.2)
|
||||
# 1996-08-22 fl Don't choke on floating point BoundingBox values
|
||||
# 1996-08-23 fl Handle files from Macintosh (0.3)
|
||||
# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4)
|
||||
# 2003-09-07 fl Check gs.close status (from Federico Di Gregorio) (0.5)
|
||||
#
|
||||
# Copyright (c) 1997-2003 by Secret Labs AB.
|
||||
# Copyright (c) 1995-2003 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
__version__ = "0.5"
|
||||
|
||||
import re, string
|
||||
import Image, ImageFile
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
def o32(i):
|
||||
return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
|
||||
|
||||
split = re.compile(r"^%%([^:]*):[ \t]*(.*)[ \t]*$")
|
||||
field = re.compile(r"^%[%!\w]([^:]*)[ \t]*$")
|
||||
|
||||
def Ghostscript(tile, size, fp):
|
||||
"""Render an image using Ghostscript (Unix only)"""
|
||||
|
||||
# Unpack decoder tile
|
||||
decoder, tile, offset, data = tile[0]
|
||||
length, bbox = data
|
||||
|
||||
import tempfile, os
|
||||
|
||||
file = tempfile.mktemp()
|
||||
|
||||
# Build ghostscript command
|
||||
command = ["gs",
|
||||
"-q", # quite mode
|
||||
"-g%dx%d" % size, # set output geometry (pixels)
|
||||
"-dNOPAUSE -dSAFER", # don't pause between pages, safe mode
|
||||
"-sDEVICE=ppmraw", # ppm driver
|
||||
"-sOutputFile=%s" % file,# output file
|
||||
"- >/dev/null 2>/dev/null"]
|
||||
|
||||
command = string.join(command)
|
||||
|
||||
# push data through ghostscript
|
||||
try:
|
||||
gs = os.popen(command, "w")
|
||||
# adjust for image origin
|
||||
if bbox[0] != 0 or bbox[1] != 0:
|
||||
gs.write("%d %d translate\n" % (-bbox[0], -bbox[1]))
|
||||
fp.seek(offset)
|
||||
while length > 0:
|
||||
s = fp.read(8192)
|
||||
if not s:
|
||||
break
|
||||
length = length - len(s)
|
||||
gs.write(s)
|
||||
status = gs.close()
|
||||
if status:
|
||||
raise IOError("gs failed (status %d)" % status)
|
||||
im = Image.core.open_ppm(file)
|
||||
finally:
|
||||
try: os.unlink(file)
|
||||
except: pass
|
||||
|
||||
return im
|
||||
|
||||
|
||||
class PSFile:
|
||||
"""Wrapper that treats either CR or LF as end of line."""
|
||||
def __init__(self, fp):
|
||||
self.fp = fp
|
||||
self.char = None
|
||||
def __getattr__(self, id):
|
||||
v = getattr(self.fp, id)
|
||||
setattr(self, id, v)
|
||||
return v
|
||||
def seek(self, offset, whence=0):
|
||||
self.char = None
|
||||
self.fp.seek(offset, whence)
|
||||
def tell(self):
|
||||
pos = self.fp.tell()
|
||||
if self.char:
|
||||
pos = pos - 1
|
||||
return pos
|
||||
def readline(self):
|
||||
s = ""
|
||||
if self.char:
|
||||
c = self.char
|
||||
self.char = None
|
||||
else:
|
||||
c = self.fp.read(1)
|
||||
while c not in "\r\n":
|
||||
s = s + c
|
||||
c = self.fp.read(1)
|
||||
if c == "\r":
|
||||
self.char = self.fp.read(1)
|
||||
if self.char == "\n":
|
||||
self.char = None
|
||||
return s + "\n"
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "%!PS" or i32(prefix) == 0xC6D3D0C5L
|
||||
|
||||
##
|
||||
# Image plugin for Encapsulated Postscript. This plugin supports only
|
||||
# a few variants of this format.
|
||||
|
||||
class EpsImageFile(ImageFile.ImageFile):
|
||||
"""EPS File Parser for the Python Imaging Library"""
|
||||
|
||||
format = "EPS"
|
||||
format_description = "Encapsulated Postscript"
|
||||
|
||||
def _open(self):
|
||||
|
||||
# FIXME: should check the first 512 bytes to see if this
|
||||
# really is necessary (platform-dependent, though...)
|
||||
|
||||
fp = PSFile(self.fp)
|
||||
|
||||
# HEAD
|
||||
s = fp.read(512)
|
||||
if s[:4] == "%!PS":
|
||||
offset = 0
|
||||
fp.seek(0, 2)
|
||||
length = fp.tell()
|
||||
elif i32(s) == 0xC6D3D0C5L:
|
||||
offset = i32(s[4:])
|
||||
length = i32(s[8:])
|
||||
fp.seek(offset)
|
||||
else:
|
||||
raise SyntaxError, "not an EPS file"
|
||||
|
||||
fp.seek(offset)
|
||||
|
||||
box = None
|
||||
|
||||
self.mode = "RGB"
|
||||
self.size = 1, 1 # FIXME: huh?
|
||||
|
||||
#
|
||||
# Load EPS header
|
||||
|
||||
s = fp.readline()
|
||||
|
||||
while s:
|
||||
|
||||
if len(s) > 255:
|
||||
raise SyntaxError, "not an EPS file"
|
||||
|
||||
if s[-2:] == '\r\n':
|
||||
s = s[:-2]
|
||||
elif s[-1:] == '\n':
|
||||
s = s[:-1]
|
||||
|
||||
try:
|
||||
m = split.match(s)
|
||||
except re.error, v:
|
||||
raise SyntaxError, "not an EPS file"
|
||||
|
||||
if m:
|
||||
k, v = m.group(1, 2)
|
||||
self.info[k] = v
|
||||
if k == "BoundingBox":
|
||||
try:
|
||||
# Note: The DSC spec says that BoundingBox
|
||||
# fields should be integers, but some drivers
|
||||
# put floating point values there anyway.
|
||||
box = map(int, map(float, string.split(v)))
|
||||
self.size = box[2] - box[0], box[3] - box[1]
|
||||
self.tile = [("eps", (0,0) + self.size, offset,
|
||||
(length, box))]
|
||||
except:
|
||||
pass
|
||||
|
||||
else:
|
||||
|
||||
m = field.match(s)
|
||||
|
||||
if m:
|
||||
k = m.group(1)
|
||||
if k == "EndComments":
|
||||
break
|
||||
if k[:8] == "PS-Adobe":
|
||||
self.info[k[:8]] = k[9:]
|
||||
else:
|
||||
self.info[k] = ""
|
||||
else:
|
||||
raise IOError, "bad EPS header"
|
||||
|
||||
s = fp.readline()
|
||||
|
||||
if s[:1] != "%":
|
||||
break
|
||||
|
||||
|
||||
#
|
||||
# Scan for an "ImageData" descriptor
|
||||
|
||||
while s[0] == "%":
|
||||
|
||||
if len(s) > 255:
|
||||
raise SyntaxError, "not an EPS file"
|
||||
|
||||
if s[-2:] == '\r\n':
|
||||
s = s[:-2]
|
||||
elif s[-1:] == '\n':
|
||||
s = s[:-1]
|
||||
|
||||
if s[:11] == "%ImageData:":
|
||||
|
||||
[x, y, bi, mo, z3, z4, en, id] =\
|
||||
string.split(s[11:], maxsplit=7)
|
||||
|
||||
x = int(x); y = int(y)
|
||||
|
||||
bi = int(bi)
|
||||
mo = int(mo)
|
||||
|
||||
en = int(en)
|
||||
|
||||
if en == 1:
|
||||
decoder = "eps_binary"
|
||||
elif en == 2:
|
||||
decoder = "eps_hex"
|
||||
else:
|
||||
break
|
||||
if bi != 8:
|
||||
break
|
||||
if mo == 1:
|
||||
self.mode = "L"
|
||||
elif mo == 2:
|
||||
self.mode = "LAB"
|
||||
elif mo == 3:
|
||||
self.mode = "RGB"
|
||||
else:
|
||||
break
|
||||
|
||||
if id[:1] == id[-1:] == '"':
|
||||
id = id[1:-1]
|
||||
|
||||
# Scan forward to the actual image data
|
||||
while 1:
|
||||
s = fp.readline()
|
||||
if not s:
|
||||
break
|
||||
if s[:len(id)] == id:
|
||||
self.size = x, y
|
||||
self.tile2 = [(decoder,
|
||||
(0, 0, x, y),
|
||||
fp.tell(),
|
||||
0)]
|
||||
return
|
||||
|
||||
s = fp.readline()
|
||||
if not s:
|
||||
break
|
||||
|
||||
if not box:
|
||||
raise IOError, "cannot determine EPS bounding box"
|
||||
|
||||
def load(self):
|
||||
# Load EPS via Ghostscript
|
||||
if not self.tile:
|
||||
return
|
||||
self.im = Ghostscript(self.tile, self.size, self.fp)
|
||||
self.mode = self.im.mode
|
||||
self.size = self.im.size
|
||||
self.tile = []
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def _save(im, fp, filename, eps=1):
|
||||
"""EPS Writer for the Python Imaging Library."""
|
||||
|
||||
#
|
||||
# make sure image data is available
|
||||
im.load()
|
||||
|
||||
#
|
||||
# determine postscript image mode
|
||||
if im.mode == "L":
|
||||
operator = (8, 1, "image")
|
||||
elif im.mode == "RGB":
|
||||
operator = (8, 3, "false 3 colorimage")
|
||||
elif im.mode == "CMYK":
|
||||
operator = (8, 4, "false 4 colorimage")
|
||||
else:
|
||||
raise ValueError, "image mode is not supported"
|
||||
|
||||
if eps:
|
||||
#
|
||||
# write EPS header
|
||||
fp.write("%!PS-Adobe-3.0 EPSF-3.0\n")
|
||||
fp.write("%%Creator: PIL 0.1 EpsEncode\n")
|
||||
#fp.write("%%CreationDate: %s"...)
|
||||
fp.write("%%%%BoundingBox: 0 0 %d %d\n" % im.size)
|
||||
fp.write("%%Pages: 1\n")
|
||||
fp.write("%%EndComments\n")
|
||||
fp.write("%%Page: 1 1\n")
|
||||
fp.write("%%ImageData: %d %d " % im.size)
|
||||
fp.write("%d %d 0 1 1 \"%s\"\n" % operator)
|
||||
|
||||
#
|
||||
# image header
|
||||
fp.write("gsave\n")
|
||||
fp.write("10 dict begin\n")
|
||||
fp.write("/buf %d string def\n" % (im.size[0] * operator[1]))
|
||||
fp.write("%d %d scale\n" % im.size)
|
||||
fp.write("%d %d 8\n" % im.size) # <= bits
|
||||
fp.write("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1]))
|
||||
fp.write("{ currentfile buf readhexstring pop } bind\n")
|
||||
fp.write("%s\n" % operator[2])
|
||||
|
||||
ImageFile._save(im, fp, [("eps", (0,0)+im.size, 0, None)])
|
||||
|
||||
fp.write("\n%%%%EndBinary\n")
|
||||
fp.write("grestore end\n")
|
||||
fp.flush()
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
Image.register_open(EpsImageFile.format, EpsImageFile, _accept)
|
||||
|
||||
Image.register_save(EpsImageFile.format, _save)
|
||||
|
||||
Image.register_extension(EpsImageFile.format, ".ps")
|
||||
Image.register_extension(EpsImageFile.format, ".eps")
|
||||
|
||||
Image.register_mime(EpsImageFile.format, "application/postscript")
|
||||
157
Darwin/lib/python2.7/site-packages/PIL/ExifTags.py
Normal file
157
Darwin/lib/python2.7/site-packages/PIL/ExifTags.py
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# EXIF tags
|
||||
#
|
||||
# Copyright (c) 2003 by Secret Labs AB
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
##
|
||||
# This module provides constants and clear-text names for various
|
||||
# well-known EXIF tags.
|
||||
##
|
||||
|
||||
##
|
||||
# Maps EXIF tags to tag names.
|
||||
|
||||
TAGS = {
|
||||
|
||||
# possibly incomplete
|
||||
0x0100: "ImageWidth",
|
||||
0x0101: "ImageLength",
|
||||
0x0102: "BitsPerSample",
|
||||
0x0103: "Compression",
|
||||
0x0106: "PhotometricInterpretation",
|
||||
0x010e: "ImageDescription",
|
||||
0x010f: "Make",
|
||||
0x0110: "Model",
|
||||
0x0111: "StripOffsets",
|
||||
0x0112: "Orientation",
|
||||
0x0115: "SamplesPerPixel",
|
||||
0x0116: "RowsPerStrip",
|
||||
0x0117: "StripByteConunts",
|
||||
0x011a: "XResolution",
|
||||
0x011a: "XResolution",
|
||||
0x011b: "YResolution",
|
||||
0x011b: "YResolution",
|
||||
0x011c: "PlanarConfiguration",
|
||||
0x0128: "ResolutionUnit",
|
||||
0x0128: "ResolutionUnit",
|
||||
0x012d: "TransferFunction",
|
||||
0x0131: "Software",
|
||||
0x0132: "DateTime",
|
||||
0x013b: "Artist",
|
||||
0x013e: "WhitePoint",
|
||||
0x013f: "PrimaryChromaticities",
|
||||
0x0201: "JpegIFOffset",
|
||||
0x0202: "JpegIFByteCount",
|
||||
0x0211: "YCbCrCoefficients",
|
||||
0x0211: "YCbCrCoefficients",
|
||||
0x0212: "YCbCrSubSampling",
|
||||
0x0213: "YCbCrPositioning",
|
||||
0x0213: "YCbCrPositioning",
|
||||
0x0214: "ReferenceBlackWhite",
|
||||
0x0214: "ReferenceBlackWhite",
|
||||
0x1000: "RelatedImageFileFormat",
|
||||
0x1001: "RelatedImageLength",
|
||||
0x1001: "RelatedImageWidth",
|
||||
0x828d: "CFARepeatPatternDim",
|
||||
0x828e: "CFAPattern",
|
||||
0x828f: "BatteryLevel",
|
||||
0x8298: "Copyright",
|
||||
0x829a: "ExposureTime",
|
||||
0x829d: "FNumber",
|
||||
0x8769: "ExifOffset",
|
||||
0x8773: "InterColorProfile",
|
||||
0x8822: "ExposureProgram",
|
||||
0x8824: "SpectralSensitivity",
|
||||
0x8825: "GPSInfo",
|
||||
0x8827: "ISOSpeedRatings",
|
||||
0x8828: "OECF",
|
||||
0x8829: "Interlace",
|
||||
0x882a: "TimeZoneOffset",
|
||||
0x882b: "SelfTimerMode",
|
||||
0x9000: "ExifVersion",
|
||||
0x9003: "DateTimeOriginal",
|
||||
0x9004: "DateTimeDigitized",
|
||||
0x9101: "ComponentsConfiguration",
|
||||
0x9102: "CompressedBitsPerPixel",
|
||||
0x9201: "ShutterSpeedValue",
|
||||
0x9202: "ApertureValue",
|
||||
0x9203: "BrightnessValue",
|
||||
0x9204: "ExposureBiasValue",
|
||||
0x9205: "MaxApertureValue",
|
||||
0x9206: "SubjectDistance",
|
||||
0x9207: "MeteringMode",
|
||||
0x9208: "LightSource",
|
||||
0x9209: "Flash",
|
||||
0x920a: "FocalLength",
|
||||
0x920b: "FlashEnergy",
|
||||
0x920c: "SpatialFrequencyResponse",
|
||||
0x920d: "Noise",
|
||||
0x9211: "ImageNumber",
|
||||
0x9212: "SecurityClassification",
|
||||
0x9213: "ImageHistory",
|
||||
0x9214: "SubjectLocation",
|
||||
0x9215: "ExposureIndex",
|
||||
0x9216: "TIFF/EPStandardID",
|
||||
0x927c: "MakerNote",
|
||||
0x9286: "UserComment",
|
||||
0x9290: "SubsecTime",
|
||||
0x9291: "SubsecTimeOriginal",
|
||||
0x9292: "SubsecTimeDigitized",
|
||||
0xa000: "FlashPixVersion",
|
||||
0xa001: "ColorSpace",
|
||||
0xa002: "ExifImageWidth",
|
||||
0xa003: "ExifImageHeight",
|
||||
0xa004: "RelatedSoundFile",
|
||||
0xa005: "ExifInteroperabilityOffset",
|
||||
0xa20b: "FlashEnergy",
|
||||
0xa20c: "SpatialFrequencyResponse",
|
||||
0xa20e: "FocalPlaneXResolution",
|
||||
0xa20f: "FocalPlaneYResolution",
|
||||
0xa210: "FocalPlaneResolutionUnit",
|
||||
0xa214: "SubjectLocation",
|
||||
0xa215: "ExposureIndex",
|
||||
0xa217: "SensingMethod",
|
||||
0xa300: "FileSource",
|
||||
0xa301: "SceneType",
|
||||
0xa302: "CFAPattern",
|
||||
|
||||
}
|
||||
|
||||
##
|
||||
# Maps EXIF GSP tags to tag names.
|
||||
|
||||
GPSTAGS = {
|
||||
0: "GPSVersionID",
|
||||
1: "GPSLatitudeRef",
|
||||
2: "GPSLatitude",
|
||||
3: "GPSLongitudeRef",
|
||||
4: "GPSLongitude",
|
||||
5: "GPSAltitudeRef",
|
||||
6: "GPSAltitude",
|
||||
7: "GPSTimeStamp",
|
||||
8: "GPSSatellites",
|
||||
9: "GPSStatus",
|
||||
10: "GPSMeasureMode",
|
||||
11: "GPSDOP",
|
||||
12: "GPSSpeedRef",
|
||||
13: "GPSSpeed",
|
||||
14: "GPSTrackRef",
|
||||
15: "GPSTrack",
|
||||
16: "GPSImgDirectionRef",
|
||||
17: "GPSImgDirection",
|
||||
18: "GPSMapDatum",
|
||||
19: "GPSDestLatitudeRef",
|
||||
20: "GPSDestLatitude",
|
||||
21: "GPSDestLongitudeRef",
|
||||
22: "GPSDestLongitude",
|
||||
23: "GPSDestBearingRef",
|
||||
24: "GPSDestBearing",
|
||||
25: "GPSDestDistanceRef",
|
||||
26: "GPSDestDistance"
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# FITS stub adapter
|
||||
#
|
||||
# Copyright (c) 1998-2003 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
|
||||
_handler = None
|
||||
|
||||
##
|
||||
# Install application-specific FITS image handler.
|
||||
#
|
||||
# @param handler Handler object.
|
||||
|
||||
def register_handler(handler):
|
||||
global _handler
|
||||
_handler = handler
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:6] == "SIMPLE"
|
||||
|
||||
class FITSStubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
format = "FITS"
|
||||
format_description = "FITS"
|
||||
|
||||
def _open(self):
|
||||
|
||||
offset = self.fp.tell()
|
||||
|
||||
if not _accept(self.fp.read(6)):
|
||||
raise SyntaxError("Not a FITS file")
|
||||
|
||||
# FIXME: add more sanity checks here; mandatory header items
|
||||
# include SIMPLE, BITPIX, NAXIS, etc.
|
||||
|
||||
self.fp.seek(offset)
|
||||
|
||||
# make something up
|
||||
self.mode = "F"
|
||||
self.size = 1, 1
|
||||
|
||||
loader = self._load()
|
||||
if loader:
|
||||
loader.open(self)
|
||||
|
||||
def _load(self):
|
||||
return _handler
|
||||
|
||||
|
||||
def _save(im, fp, filename):
|
||||
if _handler is None or not hasattr("_handler", "save"):
|
||||
raise IOError("FITS save handler not installed")
|
||||
_handler.save(im, fp, filename)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Registry
|
||||
|
||||
Image.register_open(FITSStubImageFile.format, FITSStubImageFile, _accept)
|
||||
Image.register_save(FITSStubImageFile.format, _save)
|
||||
|
||||
Image.register_extension(FITSStubImageFile.format, ".fit")
|
||||
Image.register_extension(FITSStubImageFile.format, ".fits")
|
||||
142
Darwin/lib/python2.7/site-packages/PIL/FliImagePlugin.py
Normal file
142
Darwin/lib/python2.7/site-packages/PIL/FliImagePlugin.py
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# FLI/FLC file handling.
|
||||
#
|
||||
# History:
|
||||
# 95-09-01 fl Created
|
||||
# 97-01-03 fl Fixed parser, setup decoder tile
|
||||
# 98-07-15 fl Renamed offset attribute to avoid name clash
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 1997-98.
|
||||
# Copyright (c) Fredrik Lundh 1995-97.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
|
||||
__version__ = "0.2"
|
||||
|
||||
import Image, ImageFile, ImagePalette
|
||||
import string
|
||||
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
#
|
||||
# decoder
|
||||
|
||||
def _accept(prefix):
|
||||
return i16(prefix[4:6]) in [0xAF11, 0xAF12]
|
||||
|
||||
##
|
||||
# Image plugin for the FLI/FLC animation format. Use the <b>seek</b>
|
||||
# method to load individual frames.
|
||||
|
||||
class FliImageFile(ImageFile.ImageFile):
|
||||
|
||||
format = "FLI"
|
||||
format_description = "Autodesk FLI/FLC Animation"
|
||||
|
||||
def _open(self):
|
||||
|
||||
# HEAD
|
||||
s = self.fp.read(128)
|
||||
magic = i16(s[4:6])
|
||||
if magic not in [0xAF11, 0xAF12]:
|
||||
raise SyntaxError, "not an FLI/FLC file"
|
||||
|
||||
# image characteristics
|
||||
self.mode = "P"
|
||||
self.size = i16(s[8:10]), i16(s[10:12])
|
||||
|
||||
# animation speed
|
||||
duration = i32(s[16:20])
|
||||
if magic == 0xAF11:
|
||||
duration = (duration * 1000) / 70
|
||||
self.info["duration"] = duration
|
||||
|
||||
# look for palette
|
||||
palette = map(lambda a: (a,a,a), range(256))
|
||||
|
||||
s = self.fp.read(16)
|
||||
|
||||
self.__offset = 128
|
||||
|
||||
if i16(s[4:6]) == 0xF100:
|
||||
# prefix chunk; ignore it
|
||||
self.__offset = self.__offset + i32(s)
|
||||
s = self.fp.read(16)
|
||||
|
||||
if i16(s[4:6]) == 0xF1FA:
|
||||
# look for palette chunk
|
||||
s = self.fp.read(6)
|
||||
if i16(s[4:6]) == 11:
|
||||
self._palette(palette, 2)
|
||||
elif i16(s[4:6]) == 4:
|
||||
self._palette(palette, 0)
|
||||
|
||||
palette = map(lambda (r,g,b): chr(r)+chr(g)+chr(b), palette)
|
||||
self.palette = ImagePalette.raw("RGB", string.join(palette, ""))
|
||||
|
||||
# set things up to decode first frame
|
||||
self.frame = -1
|
||||
self.__fp = self.fp
|
||||
|
||||
self.seek(0)
|
||||
|
||||
def _palette(self, palette, shift):
|
||||
# load palette
|
||||
|
||||
i = 0
|
||||
for e in range(i16(self.fp.read(2))):
|
||||
s = self.fp.read(2)
|
||||
i = i + ord(s[0])
|
||||
n = ord(s[1])
|
||||
if n == 0:
|
||||
n = 256
|
||||
s = self.fp.read(n * 3)
|
||||
for n in range(0, len(s), 3):
|
||||
r = ord(s[n]) << shift
|
||||
g = ord(s[n+1]) << shift
|
||||
b = ord(s[n+2]) << shift
|
||||
palette[i] = (r, g, b)
|
||||
i = i + 1
|
||||
|
||||
def seek(self, frame):
|
||||
|
||||
if frame != self.frame + 1:
|
||||
raise ValueError, "cannot seek to frame %d" % frame
|
||||
self.frame = frame
|
||||
|
||||
# move to next frame
|
||||
self.fp = self.__fp
|
||||
self.fp.seek(self.__offset)
|
||||
|
||||
s = self.fp.read(4)
|
||||
if not s:
|
||||
raise EOFError
|
||||
|
||||
framesize = i32(s)
|
||||
|
||||
self.decodermaxblock = framesize
|
||||
self.tile = [("fli", (0,0)+self.size, self.__offset, None)]
|
||||
|
||||
self.__offset = self.__offset + framesize
|
||||
|
||||
def tell(self):
|
||||
|
||||
return self.frame
|
||||
|
||||
#
|
||||
# registry
|
||||
|
||||
Image.register_open("FLI", FliImageFile, _accept)
|
||||
|
||||
Image.register_extension("FLI", ".fli")
|
||||
Image.register_extension("FLI", ".flc")
|
||||
146
Darwin/lib/python2.7/site-packages/PIL/FontFile.py
Normal file
146
Darwin/lib/python2.7/site-packages/PIL/FontFile.py
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# base class for raster font file parsers
|
||||
#
|
||||
# history:
|
||||
# 1997-06-05 fl created
|
||||
# 1997-08-19 fl restrict image width
|
||||
#
|
||||
# Copyright (c) 1997-1998 by Secret Labs AB
|
||||
# Copyright (c) 1997-1998 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import os
|
||||
import Image
|
||||
|
||||
import marshal
|
||||
|
||||
try:
|
||||
import zlib
|
||||
except ImportError:
|
||||
zlib = None
|
||||
|
||||
WIDTH = 800
|
||||
|
||||
def puti16(fp, values):
|
||||
# write network order (big-endian) 16-bit sequence
|
||||
for v in values:
|
||||
if v < 0:
|
||||
v = v + 65536
|
||||
fp.write(chr(v>>8&255) + chr(v&255))
|
||||
|
||||
##
|
||||
# Base class for raster font file handlers.
|
||||
|
||||
class FontFile:
|
||||
|
||||
bitmap = None
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.info = {}
|
||||
self.glyph = [None] * 256
|
||||
|
||||
def __getitem__(self, ix):
|
||||
return self.glyph[ix]
|
||||
|
||||
def compile(self):
|
||||
"Create metrics and bitmap"
|
||||
|
||||
if self.bitmap:
|
||||
return
|
||||
|
||||
# create bitmap large enough to hold all data
|
||||
h = w = maxwidth = 0
|
||||
lines = 1
|
||||
for glyph in self:
|
||||
if glyph:
|
||||
d, dst, src, im = glyph
|
||||
h = max(h, src[3] - src[1])
|
||||
w = w + (src[2] - src[0])
|
||||
if w > WIDTH:
|
||||
lines = lines + 1
|
||||
w = (src[2] - src[0])
|
||||
maxwidth = max(maxwidth, w)
|
||||
|
||||
xsize = maxwidth
|
||||
ysize = lines * h
|
||||
|
||||
if xsize == 0 and ysize == 0:
|
||||
return ""
|
||||
|
||||
self.ysize = h
|
||||
|
||||
# paste glyphs into bitmap
|
||||
self.bitmap = Image.new("1", (xsize, ysize))
|
||||
self.metrics = [None] * 256
|
||||
x = y = 0
|
||||
for i in range(256):
|
||||
glyph = self[i]
|
||||
if glyph:
|
||||
d, dst, src, im = glyph
|
||||
xx, yy = src[2] - src[0], src[3] - src[1]
|
||||
x0, y0 = x, y
|
||||
x = x + xx
|
||||
if x > WIDTH:
|
||||
x, y = 0, y + h
|
||||
x0, y0 = x, y
|
||||
x = xx
|
||||
s = src[0] + x0, src[1] + y0, src[2] + x0, src[3] + y0
|
||||
self.bitmap.paste(im.crop(src), s)
|
||||
# print chr(i), dst, s
|
||||
self.metrics[i] = d, dst, s
|
||||
|
||||
|
||||
def save1(self, filename):
|
||||
"Save font in version 1 format"
|
||||
|
||||
self.compile()
|
||||
|
||||
# font data
|
||||
self.bitmap.save(os.path.splitext(filename)[0] + ".pbm", "PNG")
|
||||
|
||||
# font metrics
|
||||
fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
|
||||
fp.write("PILfont\n")
|
||||
fp.write(";;;;;;%d;\n" % self.ysize) # HACK!!!
|
||||
fp.write("DATA\n")
|
||||
for id in range(256):
|
||||
m = self.metrics[id]
|
||||
if not m:
|
||||
puti16(fp, [0] * 10)
|
||||
else:
|
||||
puti16(fp, m[0] + m[1] + m[2])
|
||||
fp.close()
|
||||
|
||||
|
||||
def save2(self, filename):
|
||||
"Save font in version 2 format"
|
||||
|
||||
# THIS IS WORK IN PROGRESS
|
||||
|
||||
self.compile()
|
||||
|
||||
data = marshal.dumps((self.metrics, self.info))
|
||||
|
||||
if zlib:
|
||||
data = "z" + zlib.compress(data, 9)
|
||||
else:
|
||||
data = "u" + data
|
||||
|
||||
fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
|
||||
|
||||
fp.write("PILfont2\n" + self.name + "\n" + "DATA\n")
|
||||
|
||||
fp.write(data)
|
||||
|
||||
self.bitmap.save(fp, "PNG")
|
||||
|
||||
fp.close()
|
||||
|
||||
|
||||
save = save1 # for now
|
||||
224
Darwin/lib/python2.7/site-packages/PIL/FpxImagePlugin.py
Normal file
224
Darwin/lib/python2.7/site-packages/PIL/FpxImagePlugin.py
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
#
|
||||
# THIS IS WORK IN PROGRESS
|
||||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# FlashPix support for PIL
|
||||
#
|
||||
# History:
|
||||
# 97-01-25 fl Created (reads uncompressed RGB images only)
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 1997.
|
||||
# Copyright (c) Fredrik Lundh 1997.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
|
||||
__version__ = "0.1"
|
||||
|
||||
|
||||
import Image, ImageFile
|
||||
from OleFileIO import *
|
||||
|
||||
|
||||
# we map from colour field tuples to (mode, rawmode) descriptors
|
||||
MODES = {
|
||||
# opacity
|
||||
(0x00007ffe): ("A", "L"),
|
||||
# monochrome
|
||||
(0x00010000,): ("L", "L"),
|
||||
(0x00018000, 0x00017ffe): ("RGBA", "LA"),
|
||||
# photo YCC
|
||||
(0x00020000, 0x00020001, 0x00020002): ("RGB", "YCC;P"),
|
||||
(0x00028000, 0x00028001, 0x00028002, 0x00027ffe): ("RGBA", "YCCA;P"),
|
||||
# standard RGB (NIFRGB)
|
||||
(0x00030000, 0x00030001, 0x00030002): ("RGB","RGB"),
|
||||
(0x00038000, 0x00038001, 0x00038002, 0x00037ffe): ("RGBA","RGBA"),
|
||||
}
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:8] == MAGIC
|
||||
|
||||
##
|
||||
# Image plugin for the FlashPix images.
|
||||
|
||||
class FpxImageFile(ImageFile.ImageFile):
|
||||
|
||||
format = "FPX"
|
||||
format_description = "FlashPix"
|
||||
|
||||
def _open(self):
|
||||
#
|
||||
# read the OLE directory and see if this is a likely
|
||||
# to be a FlashPix file
|
||||
|
||||
try:
|
||||
self.ole = OleFileIO(self.fp)
|
||||
except IOError:
|
||||
raise SyntaxError, "not an FPX file; invalid OLE file"
|
||||
|
||||
if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B":
|
||||
raise SyntaxError, "not an FPX file; bad root CLSID"
|
||||
|
||||
self._open_index(1)
|
||||
|
||||
def _open_index(self, index = 1):
|
||||
#
|
||||
# get the Image Contents Property Set
|
||||
|
||||
prop = self.ole.getproperties([
|
||||
"Data Object Store %06d" % index,
|
||||
"\005Image Contents"
|
||||
])
|
||||
|
||||
# size (highest resolution)
|
||||
|
||||
self.size = prop[0x1000002], prop[0x1000003]
|
||||
|
||||
size = max(self.size)
|
||||
i = 1
|
||||
while size > 64:
|
||||
size = size / 2
|
||||
i = i + 1
|
||||
self.maxid = i - 1
|
||||
|
||||
# mode. instead of using a single field for this, flashpix
|
||||
# requires you to specify the mode for each channel in each
|
||||
# resolution subimage, and leaves it to the decoder to make
|
||||
# sure that they all match. for now, we'll cheat and assume
|
||||
# that this is always the case.
|
||||
|
||||
id = self.maxid << 16
|
||||
|
||||
s = prop[0x2000002|id]
|
||||
|
||||
colors = []
|
||||
for i in range(i32(s, 4)):
|
||||
# note: for now, we ignore the "uncalibrated" flag
|
||||
colors.append(i32(s, 8+i*4) & 0x7fffffff)
|
||||
|
||||
self.mode, self.rawmode = MODES[tuple(colors)]
|
||||
|
||||
# load JPEG tables, if any
|
||||
self.jpeg = {}
|
||||
for i in range(256):
|
||||
id = 0x3000001|(i << 16)
|
||||
if prop.has_key(id):
|
||||
self.jpeg[i] = prop[id]
|
||||
|
||||
# print len(self.jpeg), "tables loaded"
|
||||
|
||||
self._open_subimage(1, self.maxid)
|
||||
|
||||
def _open_subimage(self, index = 1, subimage = 0):
|
||||
#
|
||||
# setup tile descriptors for a given subimage
|
||||
|
||||
stream = [
|
||||
"Data Object Store %06d" % index,
|
||||
"Resolution %04d" % subimage,
|
||||
"Subimage 0000 Header"
|
||||
]
|
||||
|
||||
fp = self.ole.openstream(stream)
|
||||
|
||||
# skip prefix
|
||||
p = fp.read(28)
|
||||
|
||||
# header stream
|
||||
s = fp.read(36)
|
||||
|
||||
size = i32(s, 4), i32(s, 8)
|
||||
tilecount = i32(s, 12)
|
||||
tilesize = i32(s, 16), i32(s, 20)
|
||||
channels = i32(s, 24)
|
||||
offset = i32(s, 28)
|
||||
length = i32(s, 32)
|
||||
|
||||
# print size, self.mode, self.rawmode
|
||||
|
||||
if size != self.size:
|
||||
raise IOError, "subimage mismatch"
|
||||
|
||||
# get tile descriptors
|
||||
fp.seek(28 + offset)
|
||||
s = fp.read(i32(s, 12) * length)
|
||||
|
||||
x = y = 0
|
||||
xsize, ysize = size
|
||||
xtile, ytile = tilesize
|
||||
self.tile = []
|
||||
|
||||
for i in range(0, len(s), length):
|
||||
|
||||
compression = i32(s, i+8)
|
||||
|
||||
if compression == 0:
|
||||
self.tile.append(("raw", (x,y,x+xtile,y+ytile),
|
||||
i32(s, i) + 28, (self.rawmode)))
|
||||
|
||||
elif compression == 1:
|
||||
|
||||
# FIXME: the fill decoder is not implemented
|
||||
self.tile.append(("fill", (x,y,x+xtile,y+ytile),
|
||||
i32(s, i) + 28, (self.rawmode, s[12:16])))
|
||||
|
||||
elif compression == 2:
|
||||
|
||||
internal_color_conversion = ord(s[14])
|
||||
jpeg_tables = ord(s[15])
|
||||
rawmode = self.rawmode
|
||||
|
||||
if internal_color_conversion:
|
||||
# The image is stored as usual (usually YCbCr).
|
||||
if rawmode == "RGBA":
|
||||
# For "RGBA", data is stored as YCbCrA based on
|
||||
# negative RGB. The following trick works around
|
||||
# this problem :
|
||||
jpegmode, rawmode = "YCbCrK", "CMYK"
|
||||
else:
|
||||
jpegmode = None # let the decoder decide
|
||||
|
||||
else:
|
||||
# The image is stored as defined by rawmode
|
||||
jpegmode = rawmode
|
||||
|
||||
self.tile.append(("jpeg", (x,y,x+xtile,y+ytile),
|
||||
i32(s, i) + 28, (rawmode, jpegmode)))
|
||||
|
||||
# FIXME: jpeg tables are tile dependent; the prefix
|
||||
# data must be placed in the tile descriptor itself!
|
||||
|
||||
if jpeg_tables:
|
||||
self.tile_prefix = self.jpeg[jpeg_tables]
|
||||
|
||||
else:
|
||||
raise IOError, "unknown/invalid compression"
|
||||
|
||||
x = x + xtile
|
||||
if x >= xsize:
|
||||
x, y = 0, y + ytile
|
||||
if y >= ysize:
|
||||
break # isn't really required
|
||||
|
||||
self.stream = stream
|
||||
self.fp = None
|
||||
|
||||
def load(self):
|
||||
|
||||
if not self.fp:
|
||||
self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"])
|
||||
|
||||
ImageFile.ImageFile.load(self)
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
Image.register_open("FPX", FpxImageFile, _accept)
|
||||
|
||||
Image.register_extension("FPX", ".fpx")
|
||||
70
Darwin/lib/python2.7/site-packages/PIL/GbrImagePlugin.py
Normal file
70
Darwin/lib/python2.7/site-packages/PIL/GbrImagePlugin.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# load a GIMP brush file
|
||||
#
|
||||
# History:
|
||||
# 96-03-14 fl Created
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 1997.
|
||||
# Copyright (c) Fredrik Lundh 1996.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24L)
|
||||
|
||||
def _accept(prefix):
|
||||
return i32(prefix) >= 20 and i32(prefix[4:8]) == 1
|
||||
|
||||
##
|
||||
# Image plugin for the GIMP brush format.
|
||||
|
||||
class GbrImageFile(ImageFile.ImageFile):
|
||||
|
||||
format = "GBR"
|
||||
format_description = "GIMP brush file"
|
||||
|
||||
def _open(self):
|
||||
|
||||
header_size = i32(self.fp.read(4))
|
||||
version = i32(self.fp.read(4))
|
||||
if header_size < 20 or version != 1:
|
||||
raise SyntaxError, "not a GIMP brush"
|
||||
|
||||
width = i32(self.fp.read(4))
|
||||
height = i32(self.fp.read(4))
|
||||
bytes = i32(self.fp.read(4))
|
||||
if width <= 0 or height <= 0 or bytes != 1:
|
||||
raise SyntaxError, "not a GIMP brush"
|
||||
|
||||
comment = self.fp.read(header_size - 20)[:-1]
|
||||
|
||||
self.mode = "L"
|
||||
self.size = width, height
|
||||
|
||||
self.info["comment"] = comment
|
||||
|
||||
# Since the brush is so small, we read the data immediately
|
||||
self.data = self.fp.read(width * height)
|
||||
|
||||
def load(self):
|
||||
|
||||
if not self.data:
|
||||
return
|
||||
|
||||
# create an image out of the brush data block
|
||||
self.im = Image.core.new(self.mode, self.size)
|
||||
self.im.fromstring(self.data)
|
||||
self.data = ""
|
||||
|
||||
#
|
||||
# registry
|
||||
|
||||
Image.register_open("GBR", GbrImageFile, _accept)
|
||||
|
||||
Image.register_extension("GBR", ".gbr")
|
||||
85
Darwin/lib/python2.7/site-packages/PIL/GdImageFile.py
Normal file
85
Darwin/lib/python2.7/site-packages/PIL/GdImageFile.py
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# GD file handling
|
||||
#
|
||||
# History:
|
||||
# 1996-04-12 fl Created
|
||||
#
|
||||
# Copyright (c) 1997 by Secret Labs AB.
|
||||
# Copyright (c) 1996 by Fredrik Lundh.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
|
||||
# NOTE: This format cannot be automatically recognized, so the
|
||||
# class is not registered for use with Image.open(). To open a
|
||||
# gd file, use the GdImageFile.open() function instead.
|
||||
|
||||
# THE GD FORMAT IS NOT DESIGNED FOR DATA INTERCHANGE. This
|
||||
# implementation is provided for convenience and demonstrational
|
||||
# purposes only.
|
||||
|
||||
|
||||
__version__ = "0.1"
|
||||
|
||||
import ImageFile, ImagePalette
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
|
||||
##
|
||||
# Image plugin for the GD uncompressed format. Note that this format
|
||||
# is not supported by the standard <b>Image.open</b> function. To use
|
||||
# this plugin, you have to import the <b>GdImageFile</b> module and
|
||||
# use the <b>GdImageFile.open</b> function.
|
||||
|
||||
class GdImageFile(ImageFile.ImageFile):
|
||||
|
||||
format = "GD"
|
||||
format_description = "GD uncompressed images"
|
||||
|
||||
def _open(self):
|
||||
|
||||
# Header
|
||||
s = self.fp.read(775)
|
||||
|
||||
self.mode = "L" # FIXME: "P"
|
||||
self.size = i16(s[0:2]), i16(s[2:4])
|
||||
|
||||
# transparency index
|
||||
tindex = i16(s[5:7])
|
||||
if tindex < 256:
|
||||
self.info["transparent"] = tindex
|
||||
|
||||
self.palette = ImagePalette.raw("RGB", s[7:])
|
||||
|
||||
self.tile = [("raw", (0,0)+self.size, 775, ("L", 0, -1))]
|
||||
|
||||
##
|
||||
# Load texture from a GD image file.
|
||||
#
|
||||
# @param filename GD file name, or an opened file handle.
|
||||
# @param mode Optional mode. In this version, if the mode argument
|
||||
# is given, it must be "r".
|
||||
# @return An image instance.
|
||||
# @exception IOError If the image could not be read.
|
||||
|
||||
def open(fp, mode = "r"):
|
||||
|
||||
if mode != "r":
|
||||
raise ValueError("bad mode")
|
||||
|
||||
if type(fp) == type(""):
|
||||
import __builtin__
|
||||
filename = fp
|
||||
fp = __builtin__.open(fp, "rb")
|
||||
else:
|
||||
filename = ""
|
||||
|
||||
try:
|
||||
return GdImageFile(fp, filename)
|
||||
except SyntaxError:
|
||||
raise IOError("cannot identify this image file")
|
||||
407
Darwin/lib/python2.7/site-packages/PIL/GifImagePlugin.py
Normal file
407
Darwin/lib/python2.7/site-packages/PIL/GifImagePlugin.py
Normal file
|
|
@ -0,0 +1,407 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# GIF file handling
|
||||
#
|
||||
# History:
|
||||
# 1995-09-01 fl Created
|
||||
# 1996-12-14 fl Added interlace support
|
||||
# 1996-12-30 fl Added animation support
|
||||
# 1997-01-05 fl Added write support, fixed local colour map bug
|
||||
# 1997-02-23 fl Make sure to load raster data in getdata()
|
||||
# 1997-07-05 fl Support external decoder (0.4)
|
||||
# 1998-07-09 fl Handle all modes when saving (0.5)
|
||||
# 1998-07-15 fl Renamed offset attribute to avoid name clash
|
||||
# 2001-04-16 fl Added rewind support (seek to frame 0) (0.6)
|
||||
# 2001-04-17 fl Added palette optimization (0.7)
|
||||
# 2002-06-06 fl Added transparency support for save (0.8)
|
||||
# 2004-02-24 fl Disable interlacing for small images
|
||||
#
|
||||
# Copyright (c) 1997-2004 by Secret Labs AB
|
||||
# Copyright (c) 1995-2004 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
|
||||
__version__ = "0.9"
|
||||
|
||||
|
||||
import Image, ImageFile, ImagePalette
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Helpers
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Identify/read GIF files
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:6] in ["GIF87a", "GIF89a"]
|
||||
|
||||
##
|
||||
# Image plugin for GIF images. This plugin supports both GIF87 and
|
||||
# GIF89 images.
|
||||
|
||||
class GifImageFile(ImageFile.ImageFile):
|
||||
|
||||
format = "GIF"
|
||||
format_description = "Compuserve GIF"
|
||||
|
||||
global_palette = None
|
||||
|
||||
def data(self):
|
||||
s = self.fp.read(1)
|
||||
if s and ord(s):
|
||||
return self.fp.read(ord(s))
|
||||
return None
|
||||
|
||||
def _open(self):
|
||||
|
||||
# Screen
|
||||
s = self.fp.read(13)
|
||||
if s[:6] not in ["GIF87a", "GIF89a"]:
|
||||
raise SyntaxError, "not a GIF file"
|
||||
|
||||
self.info["version"] = s[:6]
|
||||
|
||||
self.size = i16(s[6:]), i16(s[8:])
|
||||
|
||||
self.tile = []
|
||||
|
||||
flags = ord(s[10])
|
||||
|
||||
bits = (flags & 7) + 1
|
||||
|
||||
if flags & 128:
|
||||
# get global palette
|
||||
self.info["background"] = ord(s[11])
|
||||
# check if palette contains colour indices
|
||||
p = self.fp.read(3<<bits)
|
||||
for i in range(0, len(p), 3):
|
||||
if not (chr(i/3) == p[i] == p[i+1] == p[i+2]):
|
||||
p = ImagePalette.raw("RGB", p)
|
||||
self.global_palette = self.palette = p
|
||||
break
|
||||
|
||||
self.__fp = self.fp # FIXME: hack
|
||||
self.__rewind = self.fp.tell()
|
||||
self.seek(0) # get ready to read first frame
|
||||
|
||||
def seek(self, frame):
|
||||
|
||||
if frame == 0:
|
||||
# rewind
|
||||
self.__offset = 0
|
||||
self.dispose = None
|
||||
self.__frame = -1
|
||||
self.__fp.seek(self.__rewind)
|
||||
|
||||
if frame != self.__frame + 1:
|
||||
raise ValueError, "cannot seek to frame %d" % frame
|
||||
self.__frame = frame
|
||||
|
||||
self.tile = []
|
||||
|
||||
self.fp = self.__fp
|
||||
if self.__offset:
|
||||
# backup to last frame
|
||||
self.fp.seek(self.__offset)
|
||||
while self.data():
|
||||
pass
|
||||
self.__offset = 0
|
||||
|
||||
if self.dispose:
|
||||
self.im = self.dispose
|
||||
self.dispose = None
|
||||
|
||||
self.palette = self.global_palette
|
||||
|
||||
while 1:
|
||||
|
||||
s = self.fp.read(1)
|
||||
if not s or s == ";":
|
||||
break
|
||||
|
||||
elif s == "!":
|
||||
#
|
||||
# extensions
|
||||
#
|
||||
s = self.fp.read(1)
|
||||
block = self.data()
|
||||
if ord(s) == 249:
|
||||
#
|
||||
# graphic control extension
|
||||
#
|
||||
flags = ord(block[0])
|
||||
if flags & 1:
|
||||
self.info["transparency"] = ord(block[3])
|
||||
self.info["duration"] = i16(block[1:3]) * 10
|
||||
try:
|
||||
# disposal methods
|
||||
if flags & 8:
|
||||
# replace with background colour
|
||||
self.dispose = Image.core.fill("P", self.size,
|
||||
self.info["background"])
|
||||
elif flags & 16:
|
||||
# replace with previous contents
|
||||
self.dispose = self.im.copy()
|
||||
except (AttributeError, KeyError):
|
||||
pass
|
||||
elif ord(s) == 255:
|
||||
#
|
||||
# application extension
|
||||
#
|
||||
self.info["extension"] = block, self.fp.tell()
|
||||
if block[:11] == "NETSCAPE2.0":
|
||||
block = self.data()
|
||||
if len(block) >= 3 and ord(block[0]) == 1:
|
||||
self.info["loop"] = i16(block[1:3])
|
||||
while self.data():
|
||||
pass
|
||||
|
||||
elif s == ",":
|
||||
#
|
||||
# local image
|
||||
#
|
||||
s = self.fp.read(9)
|
||||
|
||||
# extent
|
||||
x0, y0 = i16(s[0:]), i16(s[2:])
|
||||
x1, y1 = x0 + i16(s[4:]), y0 + i16(s[6:])
|
||||
flags = ord(s[8])
|
||||
|
||||
interlace = (flags & 64) != 0
|
||||
|
||||
if flags & 128:
|
||||
bits = (flags & 7) + 1
|
||||
self.palette =\
|
||||
ImagePalette.raw("RGB", self.fp.read(3<<bits))
|
||||
|
||||
# image data
|
||||
bits = ord(self.fp.read(1))
|
||||
self.__offset = self.fp.tell()
|
||||
self.tile = [("gif",
|
||||
(x0, y0, x1, y1),
|
||||
self.__offset,
|
||||
(bits, interlace))]
|
||||
break
|
||||
|
||||
else:
|
||||
pass
|
||||
# raise IOError, "illegal GIF tag `%x`" % ord(s)
|
||||
|
||||
if not self.tile:
|
||||
# self.__fp = None
|
||||
raise EOFError, "no more images in GIF file"
|
||||
|
||||
self.mode = "L"
|
||||
if self.palette:
|
||||
self.mode = "P"
|
||||
|
||||
def tell(self):
|
||||
return self.__frame
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Write GIF files
|
||||
|
||||
try:
|
||||
import _imaging_gif
|
||||
except ImportError:
|
||||
_imaging_gif = None
|
||||
|
||||
RAWMODE = {
|
||||
"1": "L",
|
||||
"L": "L",
|
||||
"P": "P",
|
||||
}
|
||||
|
||||
def _save(im, fp, filename):
|
||||
|
||||
if _imaging_gif:
|
||||
# call external driver
|
||||
try:
|
||||
_imaging_gif.save(im, fp, filename)
|
||||
return
|
||||
except IOError:
|
||||
pass # write uncompressed file
|
||||
|
||||
try:
|
||||
rawmode = RAWMODE[im.mode]
|
||||
imOut = im
|
||||
except KeyError:
|
||||
# convert on the fly (EXPERIMENTAL -- I'm not sure PIL
|
||||
# should automatically convert images on save...)
|
||||
if Image.getmodebase(im.mode) == "RGB":
|
||||
imOut = im.convert("P")
|
||||
rawmode = "P"
|
||||
else:
|
||||
imOut = im.convert("L")
|
||||
rawmode = "L"
|
||||
|
||||
# header
|
||||
for s in getheader(imOut, im.encoderinfo):
|
||||
fp.write(s)
|
||||
|
||||
flags = 0
|
||||
|
||||
try:
|
||||
interlace = im.encoderinfo["interlace"]
|
||||
except KeyError:
|
||||
interlace = 1
|
||||
|
||||
# workaround for @PIL153
|
||||
if min(im.size) < 16:
|
||||
interlace = 0
|
||||
|
||||
if interlace:
|
||||
flags = flags | 64
|
||||
|
||||
try:
|
||||
transparency = im.encoderinfo["transparency"]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
# transparency extension block
|
||||
fp.write("!" +
|
||||
chr(249) + # extension intro
|
||||
chr(4) + # length
|
||||
chr(1) + # transparency info present
|
||||
o16(0) + # duration
|
||||
chr(int(transparency)) # transparency index
|
||||
+ chr(0))
|
||||
|
||||
# local image header
|
||||
fp.write("," +
|
||||
o16(0) + o16(0) + # bounding box
|
||||
o16(im.size[0]) + # size
|
||||
o16(im.size[1]) +
|
||||
chr(flags) + # flags
|
||||
chr(8)) # bits
|
||||
|
||||
imOut.encoderconfig = (8, interlace)
|
||||
|
||||
ImageFile._save(imOut, fp, [("gif", (0,0)+im.size, 0, rawmode)])
|
||||
|
||||
fp.write("\0") # end of image data
|
||||
|
||||
fp.write(";") # end of file
|
||||
|
||||
try:
|
||||
fp.flush()
|
||||
except: pass
|
||||
|
||||
def _save_netpbm(im, fp, filename):
|
||||
|
||||
#
|
||||
# If you need real GIF compression and/or RGB quantization, you
|
||||
# can use the external NETPBM/PBMPLUS utilities. See comments
|
||||
# below for information on how to enable this.
|
||||
|
||||
import os
|
||||
file = im._dump()
|
||||
if im.mode != "RGB":
|
||||
os.system("ppmtogif %s >%s" % (file, filename))
|
||||
else:
|
||||
os.system("ppmquant 256 %s | ppmtogif >%s" % (file, filename))
|
||||
try: os.unlink(file)
|
||||
except: pass
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# GIF utilities
|
||||
|
||||
def getheader(im, info=None):
|
||||
"""Return a list of strings representing a GIF header"""
|
||||
|
||||
optimize = info and info.get("optimize", 0)
|
||||
|
||||
s = [
|
||||
"GIF87a" + # magic
|
||||
o16(im.size[0]) + # size
|
||||
o16(im.size[1]) +
|
||||
chr(7 + 128) + # flags: bits + palette
|
||||
chr(0) + # background
|
||||
chr(0) # reserved/aspect
|
||||
]
|
||||
|
||||
if optimize:
|
||||
# minimize color palette
|
||||
i = 0
|
||||
maxcolor = 0
|
||||
for count in im.histogram():
|
||||
if count:
|
||||
maxcolor = i
|
||||
i = i + 1
|
||||
else:
|
||||
maxcolor = 256
|
||||
|
||||
# global palette
|
||||
if im.mode == "P":
|
||||
# colour palette
|
||||
s.append(im.im.getpalette("RGB")[:maxcolor*3])
|
||||
else:
|
||||
# greyscale
|
||||
for i in range(maxcolor):
|
||||
s.append(chr(i) * 3)
|
||||
|
||||
return s
|
||||
|
||||
def getdata(im, offset = (0, 0), **params):
|
||||
"""Return a list of strings representing this image.
|
||||
The first string is a local image header, the rest contains
|
||||
encoded image data."""
|
||||
|
||||
class collector:
|
||||
data = []
|
||||
def write(self, data):
|
||||
self.data.append(data)
|
||||
|
||||
im.load() # make sure raster data is available
|
||||
|
||||
fp = collector()
|
||||
|
||||
try:
|
||||
im.encoderinfo = params
|
||||
|
||||
# local image header
|
||||
fp.write("," +
|
||||
o16(offset[0]) + # offset
|
||||
o16(offset[1]) +
|
||||
o16(im.size[0]) + # size
|
||||
o16(im.size[1]) +
|
||||
chr(0) + # flags
|
||||
chr(8)) # bits
|
||||
|
||||
ImageFile._save(im, fp, [("gif", (0,0)+im.size, 0, RAWMODE[im.mode])])
|
||||
|
||||
fp.write("\0") # end of image data
|
||||
|
||||
finally:
|
||||
del im.encoderinfo
|
||||
|
||||
return fp.data
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Registry
|
||||
|
||||
Image.register_open(GifImageFile.format, GifImageFile, _accept)
|
||||
Image.register_save(GifImageFile.format, _save)
|
||||
Image.register_extension(GifImageFile.format, ".gif")
|
||||
Image.register_mime(GifImageFile.format, "image/gif")
|
||||
|
||||
#
|
||||
# Uncomment the following line if you wish to use NETPBM/PBMPLUS
|
||||
# instead of the built-in "uncompressed" GIF encoder
|
||||
|
||||
# Image.register_save(GifImageFile.format, _save_netpbm)
|
||||
124
Darwin/lib/python2.7/site-packages/PIL/GimpGradientFile.py
Normal file
124
Darwin/lib/python2.7/site-packages/PIL/GimpGradientFile.py
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
#
|
||||
# Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# stuff to read (and render) GIMP gradient files
|
||||
#
|
||||
# History:
|
||||
# 97-08-23 fl Created
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 1997.
|
||||
# Copyright (c) Fredrik Lundh 1997.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from math import pi, log, sin, sqrt
|
||||
import string
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Stuff to translate curve segments to palette values (derived from
|
||||
# the corresponding code in GIMP, written by Federico Mena Quintero.
|
||||
# See the GIMP distribution for more information.)
|
||||
#
|
||||
|
||||
EPSILON = 1e-10
|
||||
|
||||
def linear(middle, pos):
|
||||
if pos <= middle:
|
||||
if middle < EPSILON:
|
||||
return 0.0
|
||||
else:
|
||||
return 0.5 * pos / middle
|
||||
else:
|
||||
pos = pos - middle
|
||||
middle = 1.0 - middle
|
||||
if middle < EPSILON:
|
||||
return 1.0
|
||||
else:
|
||||
return 0.5 + 0.5 * pos / middle
|
||||
|
||||
def curved(middle, pos):
|
||||
return pos ** (log(0.5) / log(max(middle, EPSILON)))
|
||||
|
||||
def sine(middle, pos):
|
||||
return (sin((-pi / 2.0) + pi * linear(middle, pos)) + 1.0) / 2.0
|
||||
|
||||
def sphere_increasing(middle, pos):
|
||||
return sqrt(1.0 - (linear(middle, pos) - 1.0) ** 2)
|
||||
|
||||
def sphere_decreasing(middle, pos):
|
||||
return 1.0 - sqrt(1.0 - linear(middle, pos) ** 2)
|
||||
|
||||
SEGMENTS = [ linear, curved, sine, sphere_increasing, sphere_decreasing ]
|
||||
|
||||
class GradientFile:
|
||||
|
||||
gradient = None
|
||||
|
||||
def getpalette(self, entries = 256):
|
||||
|
||||
palette = []
|
||||
|
||||
ix = 0
|
||||
x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix]
|
||||
|
||||
for i in range(entries):
|
||||
|
||||
x = i / float(entries-1)
|
||||
|
||||
while x1 < x:
|
||||
ix = ix + 1
|
||||
x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix]
|
||||
|
||||
w = x1 - x0
|
||||
|
||||
if w < EPSILON:
|
||||
scale = segment(0.5, 0.5)
|
||||
else:
|
||||
scale = segment((xm - x0) / w, (x - x0) / w)
|
||||
|
||||
# expand to RGBA
|
||||
r = chr(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5))
|
||||
g = chr(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5))
|
||||
b = chr(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5))
|
||||
a = chr(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5))
|
||||
|
||||
# add to palette
|
||||
palette.append(r + g + b + a)
|
||||
|
||||
return string.join(palette, ""), "RGBA"
|
||||
|
||||
##
|
||||
# File handler for GIMP's gradient format.
|
||||
|
||||
class GimpGradientFile(GradientFile):
|
||||
|
||||
def __init__(self, fp):
|
||||
|
||||
if fp.readline()[:13] != "GIMP Gradient":
|
||||
raise SyntaxError, "not a GIMP gradient file"
|
||||
|
||||
count = int(fp.readline())
|
||||
|
||||
gradient = []
|
||||
|
||||
for i in range(count):
|
||||
|
||||
s = string.split(fp.readline())
|
||||
w = map(float, s[:11])
|
||||
|
||||
x0, x1 = w[0], w[2]
|
||||
xm = w[1]
|
||||
rgb0 = w[3:7]
|
||||
rgb1 = w[7:11]
|
||||
|
||||
segment = SEGMENTS[int(s[11])]
|
||||
cspace = int(s[12])
|
||||
|
||||
if cspace != 0:
|
||||
raise IOError, "cannot handle HSV colour space"
|
||||
|
||||
gradient.append((x0, x1, xm, rgb0, rgb1, segment))
|
||||
|
||||
self.gradient = gradient
|
||||
61
Darwin/lib/python2.7/site-packages/PIL/GimpPaletteFile.py
Normal file
61
Darwin/lib/python2.7/site-packages/PIL/GimpPaletteFile.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#
|
||||
# Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# stuff to read GIMP palette files
|
||||
#
|
||||
# History:
|
||||
# 1997-08-23 fl Created
|
||||
# 2004-09-07 fl Support GIMP 2.0 palette files.
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 1997-2004. All rights reserved.
|
||||
# Copyright (c) Fredrik Lundh 1997-2004.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import re, string
|
||||
|
||||
##
|
||||
# File handler for GIMP's palette format.
|
||||
|
||||
class GimpPaletteFile:
|
||||
|
||||
rawmode = "RGB"
|
||||
|
||||
def __init__(self, fp):
|
||||
|
||||
self.palette = map(lambda i: chr(i)*3, range(256))
|
||||
|
||||
if fp.readline()[:12] != "GIMP Palette":
|
||||
raise SyntaxError, "not a GIMP palette file"
|
||||
|
||||
i = 0
|
||||
|
||||
while i <= 255:
|
||||
|
||||
s = fp.readline()
|
||||
|
||||
if not s:
|
||||
break
|
||||
# skip fields and comment lines
|
||||
if re.match("\w+:|#", s):
|
||||
continue
|
||||
if len(s) > 100:
|
||||
raise SyntaxError, "bad palette file"
|
||||
|
||||
v = tuple(map(int, string.split(s)[:3]))
|
||||
if len(v) != 3:
|
||||
raise ValueError, "bad palette entry"
|
||||
|
||||
if 0 <= i <= 255:
|
||||
self.palette[i] = chr(v[0]) + chr(v[1]) + chr(v[2])
|
||||
|
||||
i = i + 1
|
||||
|
||||
self.palette = string.join(self.palette, "")
|
||||
|
||||
|
||||
def getpalette(self):
|
||||
|
||||
return self.palette, self.rawmode
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# GRIB stub adapter
|
||||
#
|
||||
# Copyright (c) 1996-2003 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
|
||||
_handler = None
|
||||
|
||||
##
|
||||
# Install application-specific GRIB image handler.
|
||||
#
|
||||
# @param handler Handler object.
|
||||
|
||||
def register_handler(handler):
|
||||
global _handler
|
||||
_handler = handler
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[0:4] == "GRIB" and prefix[7] == chr(1)
|
||||
|
||||
class GribStubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
format = "GRIB"
|
||||
format_description = "GRIB"
|
||||
|
||||
def _open(self):
|
||||
|
||||
offset = self.fp.tell()
|
||||
|
||||
if not _accept(self.fp.read(8)):
|
||||
raise SyntaxError("Not a GRIB file")
|
||||
|
||||
self.fp.seek(offset)
|
||||
|
||||
# make something up
|
||||
self.mode = "F"
|
||||
self.size = 1, 1
|
||||
|
||||
loader = self._load()
|
||||
if loader:
|
||||
loader.open(self)
|
||||
|
||||
def _load(self):
|
||||
return _handler
|
||||
|
||||
def _save(im, fp, filename):
|
||||
if _handler is None or not hasattr("_handler", "save"):
|
||||
raise IOError("GRIB save handler not installed")
|
||||
_handler.save(im, fp, filename)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Registry
|
||||
|
||||
Image.register_open(GribStubImageFile.format, GribStubImageFile, _accept)
|
||||
Image.register_save(GribStubImageFile.format, _save)
|
||||
|
||||
Image.register_extension(GribStubImageFile.format, ".grib")
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# HDF5 stub adapter
|
||||
#
|
||||
# Copyright (c) 2000-2003 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
|
||||
_handler = None
|
||||
|
||||
##
|
||||
# Install application-specific HDF5 image handler.
|
||||
#
|
||||
# @param handler Handler object.
|
||||
|
||||
def register_handler(handler):
|
||||
global _handler
|
||||
_handler = handler
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:8] == "\x89HDF\r\n\x1a\n"
|
||||
|
||||
class HDF5StubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
format = "HDF5"
|
||||
format_description = "HDF5"
|
||||
|
||||
def _open(self):
|
||||
|
||||
offset = self.fp.tell()
|
||||
|
||||
if not _accept(self.fp.read(8)):
|
||||
raise SyntaxError("Not an HDF file")
|
||||
|
||||
self.fp.seek(offset)
|
||||
|
||||
# make something up
|
||||
self.mode = "F"
|
||||
self.size = 1, 1
|
||||
|
||||
loader = self._load()
|
||||
if loader:
|
||||
loader.open(self)
|
||||
|
||||
def _load(self):
|
||||
return _handler
|
||||
|
||||
|
||||
def _save(im, fp, filename):
|
||||
if _handler is None or not hasattr("_handler", "save"):
|
||||
raise IOError("HDF5 save handler not installed")
|
||||
_handler.save(im, fp, filename)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Registry
|
||||
|
||||
Image.register_open(HDF5StubImageFile.format, HDF5StubImageFile, _accept)
|
||||
Image.register_save(HDF5StubImageFile.format, _save)
|
||||
|
||||
Image.register_extension(HDF5StubImageFile.format, ".h5")
|
||||
Image.register_extension(HDF5StubImageFile.format, ".hdf")
|
||||
211
Darwin/lib/python2.7/site-packages/PIL/IcnsImagePlugin.py
Normal file
211
Darwin/lib/python2.7/site-packages/PIL/IcnsImagePlugin.py
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# Mac OS X icns file decoder, based on icns.py by Bob Ippolito.
|
||||
#
|
||||
# history:
|
||||
# 2004-10-09 fl Turned into a PIL plugin; removed 2.3 dependencies.
|
||||
#
|
||||
# Copyright (c) 2004 by Bob Ippolito.
|
||||
# Copyright (c) 2004 by Secret Labs.
|
||||
# Copyright (c) 2004 by Fredrik Lundh.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
import string, struct
|
||||
|
||||
HEADERSIZE = 8
|
||||
|
||||
def nextheader(fobj):
|
||||
return struct.unpack('>4sI', fobj.read(HEADERSIZE))
|
||||
|
||||
def read_32t(fobj, (start, length), (width, height)):
|
||||
# The 128x128 icon seems to have an extra header for some reason.
|
||||
fobj.seek(start)
|
||||
sig = fobj.read(4)
|
||||
if sig != '\x00\x00\x00\x00':
|
||||
raise SyntaxError, 'Unknown signature, expecting 0x00000000'
|
||||
return read_32(fobj, (start + 4, length - 4), (width, height))
|
||||
|
||||
def read_32(fobj, (start, length), size):
|
||||
"""
|
||||
Read a 32bit RGB icon resource. Seems to be either uncompressed or
|
||||
an RLE packbits-like scheme.
|
||||
"""
|
||||
fobj.seek(start)
|
||||
sizesq = size[0] * size[1]
|
||||
if length == sizesq * 3:
|
||||
# uncompressed ("RGBRGBGB")
|
||||
indata = fobj.read(length)
|
||||
im = Image.frombuffer("RGB", size, indata, "raw", "RGB", 0, 1)
|
||||
else:
|
||||
# decode image
|
||||
im = Image.new("RGB", size, None)
|
||||
for band_ix in range(3):
|
||||
data = []
|
||||
bytesleft = sizesq
|
||||
while bytesleft > 0:
|
||||
byte = fobj.read(1)
|
||||
if not byte:
|
||||
break
|
||||
byte = ord(byte)
|
||||
if byte & 0x80:
|
||||
blocksize = byte - 125
|
||||
byte = fobj.read(1)
|
||||
for i in range(blocksize):
|
||||
data.append(byte)
|
||||
else:
|
||||
blocksize = byte + 1
|
||||
data.append(fobj.read(blocksize))
|
||||
bytesleft = bytesleft - blocksize
|
||||
if bytesleft <= 0:
|
||||
break
|
||||
if bytesleft != 0:
|
||||
raise SyntaxError(
|
||||
"Error reading channel [%r left]" % bytesleft
|
||||
)
|
||||
band = Image.frombuffer(
|
||||
"L", size, string.join(data, ""), "raw", "L", 0, 1
|
||||
)
|
||||
im.im.putband(band.im, band_ix)
|
||||
return {"RGB": im}
|
||||
|
||||
def read_mk(fobj, (start, length), size):
|
||||
# Alpha masks seem to be uncompressed
|
||||
fobj.seek(start)
|
||||
band = Image.frombuffer(
|
||||
"L", size, fobj.read(size[0]*size[1]), "raw", "L", 0, 1
|
||||
)
|
||||
return {"A": band}
|
||||
|
||||
class IcnsFile:
|
||||
|
||||
SIZES = {
|
||||
(128, 128): [
|
||||
('it32', read_32t),
|
||||
('t8mk', read_mk),
|
||||
],
|
||||
(48, 48): [
|
||||
('ih32', read_32),
|
||||
('h8mk', read_mk),
|
||||
],
|
||||
(32, 32): [
|
||||
('il32', read_32),
|
||||
('l8mk', read_mk),
|
||||
],
|
||||
(16, 16): [
|
||||
('is32', read_32),
|
||||
('s8mk', read_mk),
|
||||
],
|
||||
}
|
||||
|
||||
def __init__(self, fobj):
|
||||
"""
|
||||
fobj is a file-like object as an icns resource
|
||||
"""
|
||||
# signature : (start, length)
|
||||
self.dct = dct = {}
|
||||
self.fobj = fobj
|
||||
sig, filesize = nextheader(fobj)
|
||||
if sig != 'icns':
|
||||
raise SyntaxError, 'not an icns file'
|
||||
i = HEADERSIZE
|
||||
while i < filesize:
|
||||
sig, blocksize = nextheader(fobj)
|
||||
i = i + HEADERSIZE
|
||||
blocksize = blocksize - HEADERSIZE
|
||||
dct[sig] = (i, blocksize)
|
||||
fobj.seek(blocksize, 1)
|
||||
i = i + blocksize
|
||||
|
||||
def itersizes(self):
|
||||
sizes = []
|
||||
for size, fmts in self.SIZES.items():
|
||||
for (fmt, reader) in fmts:
|
||||
if self.dct.has_key(fmt):
|
||||
sizes.append(size)
|
||||
break
|
||||
return sizes
|
||||
|
||||
def bestsize(self):
|
||||
sizes = self.itersizes()
|
||||
if not sizes:
|
||||
raise SyntaxError, "No 32bit icon resources found"
|
||||
return max(sizes)
|
||||
|
||||
def dataforsize(self, size):
|
||||
"""
|
||||
Get an icon resource as {channel: array}. Note that
|
||||
the arrays are bottom-up like windows bitmaps and will likely
|
||||
need to be flipped or transposed in some way.
|
||||
"""
|
||||
dct = {}
|
||||
for code, reader in self.SIZES[size]:
|
||||
desc = self.dct.get(code)
|
||||
if desc is not None:
|
||||
dct.update(reader(self.fobj, desc, size))
|
||||
return dct
|
||||
|
||||
def getimage(self, size=None):
|
||||
if size is None:
|
||||
size = self.bestsize()
|
||||
channels = self.dataforsize(size)
|
||||
im = channels.get("RGB").copy()
|
||||
try:
|
||||
im.putalpha(channels["A"])
|
||||
except KeyError:
|
||||
pass
|
||||
return im
|
||||
|
||||
##
|
||||
# Image plugin for Mac OS icons.
|
||||
|
||||
class IcnsImageFile(ImageFile.ImageFile):
|
||||
"""
|
||||
PIL read-only image support for Mac OS .icns files.
|
||||
Chooses the best resolution, but will possibly load
|
||||
a different size image if you mutate the size attribute
|
||||
before calling 'load'.
|
||||
|
||||
The info dictionary has a key 'sizes' that is a list
|
||||
of sizes that the icns file has.
|
||||
"""
|
||||
|
||||
format = "ICNS"
|
||||
format_description = "Mac OS icns resource"
|
||||
|
||||
def _open(self):
|
||||
self.icns = IcnsFile(self.fp)
|
||||
self.mode = 'RGBA'
|
||||
self.size = self.icns.bestsize()
|
||||
self.info['sizes'] = self.icns.itersizes()
|
||||
# Just use this to see if it's loaded or not yet.
|
||||
self.tile = ('',)
|
||||
|
||||
def load(self):
|
||||
Image.Image.load(self)
|
||||
if not self.tile:
|
||||
return
|
||||
self.load_prepare()
|
||||
# This is likely NOT the best way to do it, but whatever.
|
||||
im = self.icns.getimage(self.size)
|
||||
self.im = im.im
|
||||
self.mode = im.mode
|
||||
self.size = im.size
|
||||
self.fp = None
|
||||
self.icns = None
|
||||
self.tile = ()
|
||||
self.load_end()
|
||||
|
||||
|
||||
Image.register_open("ICNS", IcnsImageFile, lambda x: x[:4] == 'icns')
|
||||
Image.register_extension("ICNS", '.icns')
|
||||
|
||||
if __name__ == '__main__':
|
||||
import os, sys
|
||||
im = Image.open(open(sys.argv[1], "rb"))
|
||||
im.save("out.png")
|
||||
os.startfile("out.png")
|
||||
86
Darwin/lib/python2.7/site-packages/PIL/IcoImagePlugin.py
Normal file
86
Darwin/lib/python2.7/site-packages/PIL/IcoImagePlugin.py
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# Windows Icon support for PIL
|
||||
#
|
||||
# Notes:
|
||||
# uses BmpImagePlugin.py to read the bitmap data.
|
||||
#
|
||||
# History:
|
||||
# 96-05-27 fl Created
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 1997.
|
||||
# Copyright (c) Fredrik Lundh 1996.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
|
||||
__version__ = "0.1"
|
||||
|
||||
import Image, BmpImagePlugin
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "\0\0\1\0"
|
||||
|
||||
##
|
||||
# Image plugin for Windows Icon files.
|
||||
|
||||
class IcoImageFile(BmpImagePlugin.BmpImageFile):
|
||||
|
||||
format = "ICO"
|
||||
format_description = "Windows Icon"
|
||||
|
||||
def _open(self):
|
||||
|
||||
# check magic
|
||||
s = self.fp.read(6)
|
||||
if not _accept(s):
|
||||
raise SyntaxError, "not an ICO file"
|
||||
|
||||
# pick the largest icon in the file
|
||||
m = ""
|
||||
for i in range(i16(s[4:])):
|
||||
s = self.fp.read(16)
|
||||
if not m:
|
||||
m = s
|
||||
elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]):
|
||||
m = s
|
||||
#print "width", ord(s[0])
|
||||
#print "height", ord(s[1])
|
||||
#print "colors", ord(s[2])
|
||||
#print "reserved", ord(s[3])
|
||||
#print "planes", i16(s[4:])
|
||||
#print "bitcount", i16(s[6:])
|
||||
#print "bytes", i32(s[8:])
|
||||
#print "offset", i32(s[12:])
|
||||
|
||||
# load as bitmap
|
||||
self._bitmap(i32(m[12:]))
|
||||
|
||||
# patch up the bitmap height
|
||||
self.size = self.size[0], self.size[1]/2
|
||||
d, e, o, a = self.tile[0]
|
||||
self.tile[0] = d, (0,0)+self.size, o, a
|
||||
|
||||
return
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
Image.register_open("ICO", IcoImageFile, _accept)
|
||||
|
||||
Image.register_extension("ICO", ".ico")
|
||||
336
Darwin/lib/python2.7/site-packages/PIL/ImImagePlugin.py
Normal file
336
Darwin/lib/python2.7/site-packages/PIL/ImImagePlugin.py
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# IFUNC IM file handling for PIL
|
||||
#
|
||||
# history:
|
||||
# 1995-09-01 fl Created.
|
||||
# 1997-01-03 fl Save palette images
|
||||
# 1997-01-08 fl Added sequence support
|
||||
# 1997-01-23 fl Added P and RGB save support
|
||||
# 1997-05-31 fl Read floating point images
|
||||
# 1997-06-22 fl Save floating point images
|
||||
# 1997-08-27 fl Read and save 1-bit images
|
||||
# 1998-06-25 fl Added support for RGB+LUT images
|
||||
# 1998-07-02 fl Added support for YCC images
|
||||
# 1998-07-15 fl Renamed offset attribute to avoid name clash
|
||||
# 1998-12-29 fl Added I;16 support
|
||||
# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7)
|
||||
# 2003-09-26 fl Added LA/PA support
|
||||
#
|
||||
# Copyright (c) 1997-2003 by Secret Labs AB.
|
||||
# Copyright (c) 1995-2001 by Fredrik Lundh.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
|
||||
__version__ = "0.7"
|
||||
|
||||
import re, string
|
||||
import Image, ImageFile, ImagePalette
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Standard tags
|
||||
|
||||
COMMENT = "Comment"
|
||||
DATE = "Date"
|
||||
EQUIPMENT = "Digitalization equipment"
|
||||
FRAMES = "File size (no of images)"
|
||||
LUT = "Lut"
|
||||
NAME = "Name"
|
||||
SCALE = "Scale (x,y)"
|
||||
SIZE = "Image size (x*y)"
|
||||
MODE = "Image type"
|
||||
|
||||
TAGS = { COMMENT:0, DATE:0, EQUIPMENT:0, FRAMES:0, LUT:0, NAME:0,
|
||||
SCALE:0, SIZE:0, MODE:0 }
|
||||
|
||||
OPEN = {
|
||||
# ifunc93/p3cfunc formats
|
||||
"0 1 image": ("1", "1"),
|
||||
"L 1 image": ("1", "1"),
|
||||
"Greyscale image": ("L", "L"),
|
||||
"Grayscale image": ("L", "L"),
|
||||
"RGB image": ("RGB", "RGB;L"),
|
||||
"RLB image": ("RGB", "RLB"),
|
||||
"RYB image": ("RGB", "RLB"),
|
||||
"B1 image": ("1", "1"),
|
||||
"B2 image": ("P", "P;2"),
|
||||
"B4 image": ("P", "P;4"),
|
||||
"X 24 image": ("RGB", "RGB"),
|
||||
"L 32 S image": ("I", "I;32"),
|
||||
"L 32 F image": ("F", "F;32"),
|
||||
# old p3cfunc formats
|
||||
"RGB3 image": ("RGB", "RGB;T"),
|
||||
"RYB3 image": ("RGB", "RYB;T"),
|
||||
# extensions
|
||||
"LA image": ("LA", "LA;L"),
|
||||
"RGBA image": ("RGBA", "RGBA;L"),
|
||||
"RGBX image": ("RGBX", "RGBX;L"),
|
||||
"CMYK image": ("CMYK", "CMYK;L"),
|
||||
"YCC image": ("YCbCr", "YCbCr;L"),
|
||||
}
|
||||
|
||||
# ifunc95 extensions
|
||||
for i in ["8", "8S", "16", "16S", "32", "32F"]:
|
||||
OPEN["L %s image" % i] = ("F", "F;%s" % i)
|
||||
OPEN["L*%s image" % i] = ("F", "F;%s" % i)
|
||||
for i in ["16", "16L", "16B"]:
|
||||
OPEN["L %s image" % i] = ("I;%s" % i, "I;%s" % i)
|
||||
OPEN["L*%s image" % i] = ("I;%s" % i, "I;%s" % i)
|
||||
for i in ["32S"]:
|
||||
OPEN["L %s image" % i] = ("I", "I;%s" % i)
|
||||
OPEN["L*%s image" % i] = ("I", "I;%s" % i)
|
||||
for i in range(2, 33):
|
||||
OPEN["L*%s image" % i] = ("F", "F;%s" % i)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Read IM directory
|
||||
|
||||
split = re.compile(r"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$")
|
||||
|
||||
def number(s):
|
||||
try:
|
||||
return int(s)
|
||||
except ValueError:
|
||||
return float(s)
|
||||
|
||||
##
|
||||
# Image plugin for the IFUNC IM file format.
|
||||
|
||||
class ImImageFile(ImageFile.ImageFile):
|
||||
|
||||
format = "IM"
|
||||
format_description = "IFUNC Image Memory"
|
||||
|
||||
def _open(self):
|
||||
|
||||
# Quick rejection: if there's not an LF among the first
|
||||
# 100 bytes, this is (probably) not a text header.
|
||||
|
||||
if not "\n" in self.fp.read(100):
|
||||
raise SyntaxError, "not an IM file"
|
||||
self.fp.seek(0)
|
||||
|
||||
n = 0
|
||||
|
||||
# Default values
|
||||
self.info[MODE] = "L"
|
||||
self.info[SIZE] = (512, 512)
|
||||
self.info[FRAMES] = 1
|
||||
|
||||
self.rawmode = "L"
|
||||
|
||||
while 1:
|
||||
|
||||
s = self.fp.read(1)
|
||||
|
||||
# Some versions of IFUNC uses \n\r instead of \r\n...
|
||||
if s == "\r":
|
||||
continue
|
||||
|
||||
if not s or s[0] == chr(0) or s[0] == chr(26):
|
||||
break
|
||||
|
||||
# FIXME: this may read whole file if not a text file
|
||||
s = s + self.fp.readline()
|
||||
|
||||
if len(s) > 100:
|
||||
raise SyntaxError, "not an IM file"
|
||||
|
||||
if s[-2:] == '\r\n':
|
||||
s = s[:-2]
|
||||
elif s[-1:] == '\n':
|
||||
s = s[:-1]
|
||||
|
||||
try:
|
||||
m = split.match(s)
|
||||
except re.error, v:
|
||||
raise SyntaxError, "not an IM file"
|
||||
|
||||
if m:
|
||||
|
||||
k, v = m.group(1,2)
|
||||
|
||||
# Convert value as appropriate
|
||||
if k in [FRAMES, SCALE, SIZE]:
|
||||
v = string.replace(v, "*", ",")
|
||||
v = tuple(map(number, string.split(v, ",")))
|
||||
if len(v) == 1:
|
||||
v = v[0]
|
||||
elif k == MODE and OPEN.has_key(v):
|
||||
v, self.rawmode = OPEN[v]
|
||||
|
||||
# Add to dictionary. Note that COMMENT tags are
|
||||
# combined into a list of strings.
|
||||
if k == COMMENT:
|
||||
if self.info.has_key(k):
|
||||
self.info[k].append(v)
|
||||
else:
|
||||
self.info[k] = [v]
|
||||
else:
|
||||
self.info[k] = v
|
||||
|
||||
if TAGS.has_key(k):
|
||||
n = n + 1
|
||||
|
||||
else:
|
||||
|
||||
raise SyntaxError, "Syntax error in IM header: " + s
|
||||
|
||||
if not n:
|
||||
raise SyntaxError, "Not an IM file"
|
||||
|
||||
# Basic attributes
|
||||
self.size = self.info[SIZE]
|
||||
self.mode = self.info[MODE]
|
||||
|
||||
# Skip forward to start of image data
|
||||
while s and s[0] != chr(26):
|
||||
s = self.fp.read(1)
|
||||
if not s:
|
||||
raise SyntaxError, "File truncated"
|
||||
|
||||
if self.info.has_key(LUT):
|
||||
# convert lookup table to palette or lut attribute
|
||||
palette = self.fp.read(768)
|
||||
greyscale = 1 # greyscale palette
|
||||
linear = 1 # linear greyscale palette
|
||||
for i in range(256):
|
||||
if palette[i] == palette[i+256] == palette[i+512]:
|
||||
if palette[i] != chr(i):
|
||||
linear = 0
|
||||
else:
|
||||
greyscale = 0
|
||||
if self.mode == "L" or self.mode == "LA":
|
||||
if greyscale:
|
||||
if not linear:
|
||||
self.lut = map(ord, palette[:256])
|
||||
else:
|
||||
if self.mode == "L":
|
||||
self.mode = self.rawmode = "P"
|
||||
elif self.mode == "LA":
|
||||
self.mode = self.rawmode = "PA"
|
||||
self.palette = ImagePalette.raw("RGB;L", palette)
|
||||
elif self.mode == "RGB":
|
||||
if not greyscale or not linear:
|
||||
self.lut = map(ord, palette)
|
||||
|
||||
self.frame = 0
|
||||
|
||||
self.__offset = offs = self.fp.tell()
|
||||
|
||||
self.__fp = self.fp # FIXME: hack
|
||||
|
||||
if self.rawmode[:2] == "F;":
|
||||
|
||||
# ifunc95 formats
|
||||
try:
|
||||
# use bit decoder (if necessary)
|
||||
bits = int(self.rawmode[2:])
|
||||
if bits not in [8, 16, 32]:
|
||||
self.tile = [("bit", (0,0)+self.size, offs,
|
||||
(bits, 8, 3, 0, -1))]
|
||||
return
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if self.rawmode in ["RGB;T", "RYB;T"]:
|
||||
# Old LabEye/3PC files. Would be very surprised if anyone
|
||||
# ever stumbled upon such a file ;-)
|
||||
size = self.size[0] * self.size[1]
|
||||
self.tile = [("raw", (0,0)+self.size, offs, ("G", 0, -1)),
|
||||
("raw", (0,0)+self.size, offs+size, ("R", 0, -1)),
|
||||
("raw", (0,0)+self.size, offs+2*size, ("B", 0, -1))]
|
||||
else:
|
||||
# LabEye/IFUNC files
|
||||
self.tile = [("raw", (0,0)+self.size, offs, (self.rawmode, 0, -1))]
|
||||
|
||||
def seek(self, frame):
|
||||
|
||||
if frame < 0 or frame >= self.info[FRAMES]:
|
||||
raise EOFError, "seek outside sequence"
|
||||
|
||||
if self.frame == frame:
|
||||
return
|
||||
|
||||
self.frame = frame
|
||||
|
||||
if self.mode == "1":
|
||||
bits = 1
|
||||
else:
|
||||
bits = 8 * len(self.mode)
|
||||
|
||||
size = ((self.size[0] * bits + 7) / 8) * self.size[1]
|
||||
offs = self.__offset + frame * size
|
||||
|
||||
self.fp = self.__fp
|
||||
|
||||
self.tile = [("raw", (0,0)+self.size, offs, (self.rawmode, 0, -1))]
|
||||
|
||||
def tell(self):
|
||||
|
||||
return self.frame
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Save IM files
|
||||
|
||||
SAVE = {
|
||||
# mode: (im type, raw mode)
|
||||
"1": ("0 1", "1"),
|
||||
"L": ("Greyscale", "L"),
|
||||
"LA": ("LA", "LA;L"),
|
||||
"P": ("Greyscale", "P"),
|
||||
"PA": ("LA", "PA;L"),
|
||||
"I": ("L 32S", "I;32S"),
|
||||
"I;16": ("L 16", "I;16"),
|
||||
"I;16L": ("L 16L", "I;16L"),
|
||||
"I;16B": ("L 16B", "I;16B"),
|
||||
"F": ("L 32F", "F;32F"),
|
||||
"RGB": ("RGB", "RGB;L"),
|
||||
"RGBA": ("RGBA", "RGBA;L"),
|
||||
"RGBX": ("RGBX", "RGBX;L"),
|
||||
"CMYK": ("CMYK", "CMYK;L"),
|
||||
"YCbCr": ("YCC", "YCbCr;L")
|
||||
}
|
||||
|
||||
def _save(im, fp, filename, check=0):
|
||||
|
||||
try:
|
||||
type, rawmode = SAVE[im.mode]
|
||||
except KeyError:
|
||||
raise ValueError, "Cannot save %s images as IM" % im.mode
|
||||
|
||||
try:
|
||||
frames = im.encoderinfo["frames"]
|
||||
except KeyError:
|
||||
frames = 1
|
||||
|
||||
if check:
|
||||
return check
|
||||
|
||||
fp.write("Image type: %s image\r\n" % type)
|
||||
if filename:
|
||||
fp.write("Name: %s\r\n" % filename)
|
||||
fp.write("Image size (x*y): %d*%d\r\n" % im.size)
|
||||
fp.write("File size (no of images): %d\r\n" % frames)
|
||||
if im.mode == "P":
|
||||
fp.write("Lut: 1\r\n")
|
||||
fp.write("\000" * (511-fp.tell()) + "\032")
|
||||
if im.mode == "P":
|
||||
fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes
|
||||
ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, -1))])
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Registry
|
||||
|
||||
Image.register_open("IM", ImImageFile)
|
||||
Image.register_save("IM", _save)
|
||||
|
||||
Image.register_extension("IM", ".im")
|
||||
2127
Darwin/lib/python2.7/site-packages/PIL/Image.py
Normal file
2127
Darwin/lib/python2.7/site-packages/PIL/Image.py
Normal file
File diff suppressed because it is too large
Load diff
302
Darwin/lib/python2.7/site-packages/PIL/ImageChops.py
Normal file
302
Darwin/lib/python2.7/site-packages/PIL/ImageChops.py
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# standard channel operations
|
||||
#
|
||||
# History:
|
||||
# 1996-03-24 fl Created
|
||||
# 1996-08-13 fl Added logical operations (for "1" images)
|
||||
# 2000-10-12 fl Added offset method (from Image.py)
|
||||
#
|
||||
# Copyright (c) 1997-2000 by Secret Labs AB
|
||||
# Copyright (c) 1996-2000 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
|
||||
##
|
||||
# The <b>ImageChops</b> module contains a number of arithmetical image
|
||||
# operations, called <i>channel operations</i> ("chops"). These can be
|
||||
# used for various purposes, including special effects, image
|
||||
# compositions, algorithmic painting, and more.
|
||||
# <p>
|
||||
# At this time, channel operations are only implemented for 8-bit
|
||||
# images (e.g. "L" and "RGB").
|
||||
# <p>
|
||||
# Most channel operations take one or two image arguments and returns
|
||||
# a new image. Unless otherwise noted, the result of a channel
|
||||
# operation is always clipped to the range 0 to MAX (which is 255 for
|
||||
# all modes supported by the operations in this module).
|
||||
##
|
||||
|
||||
##
|
||||
# Return an image with the same size as the given image, but filled
|
||||
# with the given pixel value.
|
||||
#
|
||||
# @param image Reference image.
|
||||
# @param value Pixel value.
|
||||
# @return An image object.
|
||||
|
||||
def constant(image, value):
|
||||
"Fill a channel with a given grey level"
|
||||
|
||||
return Image.new("L", image.size, value)
|
||||
|
||||
##
|
||||
# Copy image.
|
||||
#
|
||||
# @param image Source image.
|
||||
# @return A copy of the source image.
|
||||
|
||||
def duplicate(image):
|
||||
"Create a copy of a channel"
|
||||
|
||||
return image.copy()
|
||||
|
||||
##
|
||||
# Inverts an image
|
||||
# (MAX - image).
|
||||
#
|
||||
# @param image Source image.
|
||||
# @return An image object.
|
||||
|
||||
def invert(image):
|
||||
"Invert a channel"
|
||||
|
||||
image.load()
|
||||
return image._new(image.im.chop_invert())
|
||||
|
||||
##
|
||||
# Compare images, and return lighter pixel value
|
||||
# (max(image1, image2)).
|
||||
# <p>
|
||||
# Compares the two images, pixel by pixel, and returns a new image
|
||||
# containing the lighter values.
|
||||
#
|
||||
# @param image1 First image.
|
||||
# @param image1 Second image.
|
||||
# @return An image object.
|
||||
|
||||
def lighter(image1, image2):
|
||||
"Select the lighter pixels from each image"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_lighter(image2.im))
|
||||
|
||||
##
|
||||
# Compare images, and return darker pixel value
|
||||
# (min(image1, image2)).
|
||||
# <p>
|
||||
# Compares the two images, pixel by pixel, and returns a new image
|
||||
# containing the darker values.
|
||||
#
|
||||
# @param image1 First image.
|
||||
# @param image1 Second image.
|
||||
# @return An image object.
|
||||
|
||||
def darker(image1, image2):
|
||||
"Select the darker pixels from each image"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_darker(image2.im))
|
||||
|
||||
##
|
||||
# Calculate absolute difference
|
||||
# (abs(image1 - image2)).
|
||||
# <p>
|
||||
# Returns the absolute value of the difference between the two images.
|
||||
#
|
||||
# @param image1 First image.
|
||||
# @param image1 Second image.
|
||||
# @return An image object.
|
||||
|
||||
def difference(image1, image2):
|
||||
"Subtract one image from another"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_difference(image2.im))
|
||||
|
||||
##
|
||||
# Superimpose positive images
|
||||
# (image1 * image2 / MAX).
|
||||
# <p>
|
||||
# Superimposes two images on top of each other. If you multiply an
|
||||
# image with a solid black image, the result is black. If you multiply
|
||||
# with a solid white image, the image is unaffected.
|
||||
#
|
||||
# @param image1 First image.
|
||||
# @param image1 Second image.
|
||||
# @return An image object.
|
||||
|
||||
def multiply(image1, image2):
|
||||
"Superimpose two positive images"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_multiply(image2.im))
|
||||
|
||||
##
|
||||
# Superimpose negative images
|
||||
# (MAX - ((MAX - image1) * (MAX - image2) / MAX)).
|
||||
# <p>
|
||||
# Superimposes two inverted images on top of each other.
|
||||
#
|
||||
# @param image1 First image.
|
||||
# @param image1 Second image.
|
||||
# @return An image object.
|
||||
|
||||
def screen(image1, image2):
|
||||
"Superimpose two negative images"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_screen(image2.im))
|
||||
|
||||
##
|
||||
# Add images
|
||||
# ((image1 + image2) / scale + offset).
|
||||
# <p>
|
||||
# Adds two images, dividing the result by scale and adding the
|
||||
# offset. If omitted, scale defaults to 1.0, and offset to 0.0.
|
||||
#
|
||||
# @param image1 First image.
|
||||
# @param image1 Second image.
|
||||
# @return An image object.
|
||||
|
||||
def add(image1, image2, scale=1.0, offset=0):
|
||||
"Add two images"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_add(image2.im, scale, offset))
|
||||
|
||||
##
|
||||
# Subtract images
|
||||
# ((image1 - image2) / scale + offset).
|
||||
# <p>
|
||||
# Subtracts two images, dividing the result by scale and adding the
|
||||
# offset. If omitted, scale defaults to 1.0, and offset to 0.0.
|
||||
#
|
||||
# @param image1 First image.
|
||||
# @param image1 Second image.
|
||||
# @return An image object.
|
||||
|
||||
def subtract(image1, image2, scale=1.0, offset=0):
|
||||
"Subtract two images"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_subtract(image2.im, scale, offset))
|
||||
|
||||
##
|
||||
# Add images without clipping
|
||||
# ((image1 + image2) % MAX).
|
||||
# <p>
|
||||
# Adds two images, without clipping the result.
|
||||
#
|
||||
# @param image1 First image.
|
||||
# @param image1 Second image.
|
||||
# @return An image object.
|
||||
|
||||
def add_modulo(image1, image2):
|
||||
"Add two images without clipping"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_add_modulo(image2.im))
|
||||
|
||||
##
|
||||
# Subtract images without clipping
|
||||
# ((image1 - image2) % MAX).
|
||||
# <p>
|
||||
# Subtracts two images, without clipping the result.
|
||||
#
|
||||
# @param image1 First image.
|
||||
# @param image1 Second image.
|
||||
# @return An image object.
|
||||
|
||||
def subtract_modulo(image1, image2):
|
||||
"Subtract two images without clipping"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_subtract_modulo(image2.im))
|
||||
|
||||
##
|
||||
# Logical AND
|
||||
# (image1 and image2).
|
||||
|
||||
def logical_and(image1, image2):
|
||||
"Logical and between two images"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_and(image2.im))
|
||||
|
||||
##
|
||||
# Logical OR
|
||||
# (image1 or image2).
|
||||
|
||||
def logical_or(image1, image2):
|
||||
"Logical or between two images"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_or(image2.im))
|
||||
|
||||
##
|
||||
# Logical XOR
|
||||
# (image1 xor image2).
|
||||
|
||||
def logical_xor(image1, image2):
|
||||
"Logical xor between two images"
|
||||
|
||||
image1.load()
|
||||
image2.load()
|
||||
return image1._new(image1.im.chop_xor(image2.im))
|
||||
|
||||
##
|
||||
# Blend images using constant transparency weight.
|
||||
# <p>
|
||||
# Same as the <b>blend</b> function in the <b>Image</b> module.
|
||||
|
||||
def blend(image1, image2, alpha):
|
||||
"Blend two images using a constant transparency weight"
|
||||
|
||||
return Image.blend(image1, image2, alpha)
|
||||
|
||||
##
|
||||
# Create composite using transparency mask.
|
||||
# <p>
|
||||
# Same as the <b>composite</b> function in the <b>Image</b> module.
|
||||
|
||||
def composite(image1, image2, mask):
|
||||
"Create composite image by blending images using a transparency mask"
|
||||
|
||||
return Image.composite(image1, image2, mask)
|
||||
|
||||
##
|
||||
# Offset image data.
|
||||
# <p>
|
||||
# Returns a copy of the image where data has been offset by the given
|
||||
# distances. Data wraps around the edges. If yoffset is omitted, it
|
||||
# is assumed to be equal to xoffset.
|
||||
#
|
||||
# @param image Source image.
|
||||
# @param xoffset The horizontal distance.
|
||||
# @param yoffset The vertical distance. If omitted, both
|
||||
# distances are set to the same value.
|
||||
# @return An Image object.
|
||||
|
||||
def offset(image, xoffset, yoffset=None):
|
||||
"Offset image in horizontal and/or vertical direction"
|
||||
if yoffset is None:
|
||||
yoffset = xoffset
|
||||
image.load()
|
||||
return image._new(image.im.offset(xoffset, yoffset))
|
||||
786
Darwin/lib/python2.7/site-packages/PIL/ImageCms.py
Normal file
786
Darwin/lib/python2.7/site-packages/PIL/ImageCms.py
Normal file
|
|
@ -0,0 +1,786 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# optional color managment support, based on Kevin Cazabon's PyCMS
|
||||
# library.
|
||||
#
|
||||
# History:
|
||||
# 2009-03-08 fl Added to PIL.
|
||||
#
|
||||
# Copyright (C) 2002-2003 Kevin Cazabon
|
||||
# Copyright (c) 2009 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution. See
|
||||
# below for the original description.
|
||||
#
|
||||
|
||||
DESCRIPTION = """
|
||||
pyCMS
|
||||
|
||||
a Python / PIL interface to the littleCMS ICC Color Management System
|
||||
Copyright (C) 2002-2003 Kevin Cazabon
|
||||
kevin@cazabon.com
|
||||
http://www.cazabon.com
|
||||
|
||||
pyCMS home page: http://www.cazabon.com/pyCMS
|
||||
littleCMS home page: http://www.littlecms.com
|
||||
(littleCMS is Copyright (C) 1998-2001 Marti Maria)
|
||||
|
||||
Originally released under LGPL. Graciously donated to PIL in
|
||||
March 2009, for distribution under the standard PIL license
|
||||
|
||||
The pyCMS.py module provides a "clean" interface between Python/PIL and
|
||||
pyCMSdll, taking care of some of the more complex handling of the direct
|
||||
pyCMSdll functions, as well as error-checking and making sure that all
|
||||
relevant data is kept together.
|
||||
|
||||
While it is possible to call pyCMSdll functions directly, it's not highly
|
||||
recommended.
|
||||
|
||||
Version History:
|
||||
|
||||
0.1.0 pil mod March 10, 2009
|
||||
|
||||
Renamed display profile to proof profile. The proof
|
||||
profile is the profile of the device that is being
|
||||
simulated, not the profile of the device which is
|
||||
actually used to display/print the final simulation
|
||||
(that'd be the output profile) - also see LCMSAPI.txt
|
||||
input colorspace -> using 'renderingIntent' -> proof
|
||||
colorspace -> using 'proofRenderingIntent' -> output
|
||||
colorspace
|
||||
|
||||
Added LCMS FLAGS support.
|
||||
Added FLAGS["SOFTPROOFING"] as default flag for
|
||||
buildProofTransform (otherwise the proof profile/intent
|
||||
would be ignored).
|
||||
|
||||
0.1.0 pil March 2009 - added to PIL, as PIL.ImageCms
|
||||
|
||||
0.0.2 alpha Jan 6, 2002
|
||||
|
||||
Added try/except statements arount type() checks of
|
||||
potential CObjects... Python won't let you use type()
|
||||
on them, and raises a TypeError (stupid, if you ask me!)
|
||||
|
||||
Added buildProofTransformFromOpenProfiles() function.
|
||||
Additional fixes in DLL, see DLL code for details.
|
||||
|
||||
0.0.1 alpha first public release, Dec. 26, 2002
|
||||
|
||||
Known to-do list with current version (of Python interface, not pyCMSdll):
|
||||
|
||||
none
|
||||
|
||||
"""
|
||||
|
||||
VERSION = "0.1.0 pil"
|
||||
|
||||
# --------------------------------------------------------------------.
|
||||
|
||||
import Image
|
||||
import _imagingcms
|
||||
|
||||
core = _imagingcms
|
||||
|
||||
#
|
||||
# intent/direction values
|
||||
|
||||
INTENT_PERCEPTUAL = 0
|
||||
INTENT_RELATIVE_COLORIMETRIC = 1
|
||||
INTENT_SATURATION = 2
|
||||
INTENT_ABSOLUTE_COLORIMETRIC = 3
|
||||
|
||||
DIRECTION_INPUT = 0
|
||||
DIRECTION_OUTPUT = 1
|
||||
DIRECTION_PROOF = 2
|
||||
|
||||
#
|
||||
# flags
|
||||
|
||||
FLAGS = {
|
||||
"MATRIXINPUT": 1,
|
||||
"MATRIXOUTPUT": 2,
|
||||
"MATRIXONLY": (1|2),
|
||||
"NOWHITEONWHITEFIXUP": 4, # Don't hot fix scum dot
|
||||
"NOPRELINEARIZATION": 16, # Don't create prelinearization tables on precalculated transforms (internal use)
|
||||
"GUESSDEVICECLASS": 32, # Guess device class (for transform2devicelink)
|
||||
"NOTCACHE": 64, # Inhibit 1-pixel cache
|
||||
"NOTPRECALC": 256,
|
||||
"NULLTRANSFORM": 512, # Don't transform anyway
|
||||
"HIGHRESPRECALC": 1024, # Use more memory to give better accurancy
|
||||
"LOWRESPRECALC": 2048, # Use less memory to minimize resouces
|
||||
"WHITEBLACKCOMPENSATION": 8192,
|
||||
"BLACKPOINTCOMPENSATION": 8192,
|
||||
"GAMUTCHECK": 4096, # Out of Gamut alarm
|
||||
"SOFTPROOFING": 16384, # Do softproofing
|
||||
"PRESERVEBLACK": 32768, # Black preservation
|
||||
"NODEFAULTRESOURCEDEF": 16777216, # CRD special
|
||||
"GRIDPOINTS": lambda n: ((n) & 0xFF) << 16 # Gridpoints
|
||||
}
|
||||
|
||||
_MAX_FLAG = 0
|
||||
for flag in FLAGS.values():
|
||||
if isinstance(flag, type(0)):
|
||||
_MAX_FLAG = _MAX_FLAG | flag
|
||||
|
||||
# --------------------------------------------------------------------.
|
||||
# Experimental PIL-level API
|
||||
# --------------------------------------------------------------------.
|
||||
|
||||
##
|
||||
# Profile.
|
||||
|
||||
class ImageCmsProfile:
|
||||
|
||||
def __init__(self, profile):
|
||||
# accepts a string (filename), a file-like object, or a low-level
|
||||
# profile object
|
||||
if Image.isStringType(profile):
|
||||
self._set(core.profile_open(profile), profile)
|
||||
elif hasattr(profile, "read"):
|
||||
self._set(core.profile_fromstring(profile.read()))
|
||||
else:
|
||||
self._set(profile) # assume it's already a profile
|
||||
|
||||
def _set(self, profile, filename=None):
|
||||
self.profile = profile
|
||||
self.filename = filename
|
||||
if profile:
|
||||
self.product_name = profile.product_name
|
||||
self.product_info = profile.product_info
|
||||
else:
|
||||
self.product_name = None
|
||||
self.product_info = None
|
||||
|
||||
##
|
||||
# Transform. This can be used with the procedural API, or with the
|
||||
# standard {@link Image.point} method.
|
||||
|
||||
class ImageCmsTransform(Image.ImagePointHandler):
|
||||
|
||||
def __init__(self, input, output, input_mode, output_mode,
|
||||
intent=INTENT_PERCEPTUAL,
|
||||
proof=None, proof_intent=INTENT_ABSOLUTE_COLORIMETRIC, flags=0):
|
||||
if proof is None:
|
||||
self.transform = core.buildTransform(
|
||||
input.profile, output.profile,
|
||||
input_mode, output_mode,
|
||||
intent,
|
||||
flags
|
||||
)
|
||||
else:
|
||||
self.transform = core.buildProofTransform(
|
||||
input.profile, output.profile, proof.profile,
|
||||
input_mode, output_mode,
|
||||
intent, proof_intent,
|
||||
flags
|
||||
)
|
||||
# Note: inputMode and outputMode are for pyCMS compatibility only
|
||||
self.input_mode = self.inputMode = input_mode
|
||||
self.output_mode = self.outputMode = output_mode
|
||||
|
||||
def point(self, im):
|
||||
return self.apply(im)
|
||||
|
||||
def apply(self, im, imOut=None):
|
||||
im.load()
|
||||
if imOut is None:
|
||||
imOut = Image.new(self.output_mode, im.size, None)
|
||||
result = self.transform.apply(im.im.id, imOut.im.id)
|
||||
return imOut
|
||||
|
||||
def apply_in_place(self, im):
|
||||
im.load()
|
||||
if im.mode != self.output_mode:
|
||||
raise ValueError("mode mismatch") # wrong output mode
|
||||
result = self.transform.apply(im.im.id, im.im.id)
|
||||
return im
|
||||
|
||||
##
|
||||
# (experimental) Fetches the profile for the current display device.
|
||||
# Returns None if the profile is not known.
|
||||
|
||||
def get_display_profile(handle=None):
|
||||
import sys
|
||||
if sys.platform == "win32":
|
||||
import ImageWin
|
||||
if isinstance(handle, ImageWin.HDC):
|
||||
profile = core.get_display_profile_win32(handle, 1)
|
||||
else:
|
||||
profile = core.get_display_profile_win32(handle or 0)
|
||||
else:
|
||||
try:
|
||||
get = _imagingcms.get_display_profile
|
||||
except AttributeError:
|
||||
return None
|
||||
else:
|
||||
profile = get()
|
||||
return ImageCmsProfile(profile)
|
||||
|
||||
# --------------------------------------------------------------------.
|
||||
# pyCMS compatible layer
|
||||
# --------------------------------------------------------------------.
|
||||
|
||||
##
|
||||
# (pyCMS) Exception class. This is used for all errors in the pyCMS API.
|
||||
|
||||
class PyCMSError(Exception):
|
||||
pass
|
||||
|
||||
##
|
||||
# (pyCMS) Applies an ICC transformation to a given image, mapping from
|
||||
# inputProfile to outputProfile.
|
||||
|
||||
def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PERCEPTUAL, outputMode=None, inPlace=0, flags=0):
|
||||
"""
|
||||
ImageCms.profileToProfile(im, inputProfile, outputProfile,
|
||||
[renderingIntent], [outputMode], [inPlace])
|
||||
|
||||
Returns either None or a new PIL image object, depending on value of
|
||||
inPlace (see below).
|
||||
|
||||
im = an open PIL image object (i.e. Image.new(...) or
|
||||
Image.open(...), etc.)
|
||||
inputProfile = string, as a valid filename path to the ICC input
|
||||
profile you wish to use for this image, or a profile object
|
||||
outputProfile = string, as a valid filename path to the ICC output
|
||||
profile you wish to use for this image, or a profile object
|
||||
renderingIntent = integer (0-3) specifying the rendering intent you
|
||||
wish to use for the transform
|
||||
INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
|
||||
INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
|
||||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
|
||||
see the pyCMS documentation for details on rendering intents and
|
||||
what they do.
|
||||
outputMode = a valid PIL mode for the output image (i.e. "RGB", "CMYK",
|
||||
etc.). Note: if rendering the image "inPlace", outputMode MUST be
|
||||
the same mode as the input, or omitted completely. If omitted, the
|
||||
outputMode will be the same as the mode of the input image (im.mode)
|
||||
inPlace = BOOL (1 = TRUE, None or 0 = FALSE). If TRUE, the original
|
||||
image is modified in-place, and None is returned. If FALSE
|
||||
(default), a new Image object is returned with the transform
|
||||
applied.
|
||||
flags = integer (0-...) specifying additional flags
|
||||
|
||||
If the input or output profiles specified are not valid filenames, a
|
||||
PyCMSError will be raised. If inPlace == TRUE and outputMode != im.mode,
|
||||
a PyCMSError will be raised. If an error occurs during application of
|
||||
the profiles, a PyCMSError will be raised. If outputMode is not a mode
|
||||
supported by the outputProfile (or by pyCMS), a PyCMSError will be
|
||||
raised.
|
||||
|
||||
This function applies an ICC transformation to im from inputProfile's
|
||||
color space to outputProfile's color space using the specified rendering
|
||||
intent to decide how to handle out-of-gamut colors.
|
||||
|
||||
OutputMode can be used to specify that a color mode conversion is to
|
||||
be done using these profiles, but the specified profiles must be able
|
||||
to handle that mode. I.e., if converting im from RGB to CMYK using
|
||||
profiles, the input profile must handle RGB data, and the output
|
||||
profile must handle CMYK data.
|
||||
|
||||
"""
|
||||
|
||||
if outputMode is None:
|
||||
outputMode = im.mode
|
||||
|
||||
if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
|
||||
raise PyCMSError("renderingIntent must be an integer between 0 and 3")
|
||||
|
||||
if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
|
||||
raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
|
||||
try:
|
||||
if not isinstance(inputProfile, ImageCmsProfile):
|
||||
inputProfile = ImageCmsProfile(inputProfile)
|
||||
if not isinstance(outputProfile, ImageCmsProfile):
|
||||
outputProfile = ImageCmsProfile(outputProfile)
|
||||
transform = ImageCmsTransform(
|
||||
inputProfile, outputProfile, im.mode, outputMode, renderingIntent, flags=flags
|
||||
)
|
||||
if inPlace:
|
||||
transform.apply_in_place(im)
|
||||
imOut = None
|
||||
else:
|
||||
imOut = transform.apply(im)
|
||||
except (IOError, TypeError, ValueError), v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
return imOut
|
||||
|
||||
##
|
||||
# (pyCMS) Opens an ICC profile file.
|
||||
|
||||
def getOpenProfile(profileFilename):
|
||||
"""
|
||||
ImageCms.getOpenProfile(profileFilename)
|
||||
|
||||
Returns a CmsProfile class object.
|
||||
|
||||
profileFilename = string, as a valid filename path to the ICC profile
|
||||
you wish to open, or a file-like object.
|
||||
|
||||
The PyCMSProfile object can be passed back into pyCMS for use in creating
|
||||
transforms and such (as in ImageCms.buildTransformFromOpenProfiles()).
|
||||
|
||||
If profileFilename is not a vaild filename for an ICC profile, a
|
||||
PyCMSError will be raised.
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
return ImageCmsProfile(profileFilename)
|
||||
except (IOError, TypeError, ValueError), v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
# (pyCMS) Builds an ICC transform mapping from the inputProfile to the
|
||||
# outputProfile. Use applyTransform to apply the transform to a given
|
||||
# image.
|
||||
|
||||
def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, flags=0):
|
||||
"""
|
||||
ImageCms.buildTransform(inputProfile, outputProfile, inMode, outMode,
|
||||
[renderingIntent])
|
||||
|
||||
Returns a CmsTransform class object.
|
||||
|
||||
inputProfile = string, as a valid filename path to the ICC input
|
||||
profile you wish to use for this transform, or a profile object
|
||||
outputProfile = string, as a valid filename path to the ICC output
|
||||
profile you wish to use for this transform, or a profile object
|
||||
inMode = string, as a valid PIL mode that the appropriate profile also
|
||||
supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
outMode = string, as a valid PIL mode that the appropriate profile also
|
||||
supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
renderingIntent = integer (0-3) specifying the rendering intent you
|
||||
wish to use for the transform
|
||||
INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
|
||||
INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
|
||||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
see the pyCMS documentation for details on rendering intents and
|
||||
what they do.
|
||||
flags = integer (0-...) specifying additional flags
|
||||
|
||||
If the input or output profiles specified are not valid filenames, a
|
||||
PyCMSError will be raised. If an error occurs during creation of the
|
||||
transform, a PyCMSError will be raised.
|
||||
|
||||
If inMode or outMode are not a mode supported by the outputProfile (or
|
||||
by pyCMS), a PyCMSError will be raised.
|
||||
|
||||
This function builds and returns an ICC transform from the inputProfile
|
||||
to the outputProfile using the renderingIntent to determine what to do
|
||||
with out-of-gamut colors. It will ONLY work for converting images that
|
||||
are in inMode to images that are in outMode color format (PIL mode,
|
||||
i.e. "RGB", "RGBA", "CMYK", etc.).
|
||||
|
||||
Building the transform is a fair part of the overhead in
|
||||
ImageCms.profileToProfile(), so if you're planning on converting multiple
|
||||
images using the same input/output settings, this can save you time.
|
||||
Once you have a transform object, it can be used with
|
||||
ImageCms.applyProfile() to convert images without the need to re-compute
|
||||
the lookup table for the transform.
|
||||
|
||||
The reason pyCMS returns a class object rather than a handle directly
|
||||
to the transform is that it needs to keep track of the PIL input/output
|
||||
modes that the transform is meant for. These attributes are stored in
|
||||
the "inMode" and "outMode" attributes of the object (which can be
|
||||
manually overridden if you really want to, but I don't know of any
|
||||
time that would be of use, or would even work).
|
||||
|
||||
"""
|
||||
|
||||
if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
|
||||
raise PyCMSError("renderingIntent must be an integer between 0 and 3")
|
||||
|
||||
if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
|
||||
raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
|
||||
try:
|
||||
if not isinstance(inputProfile, ImageCmsProfile):
|
||||
inputProfile = ImageCmsProfile(inputProfile)
|
||||
if not isinstance(outputProfile, ImageCmsProfile):
|
||||
outputProfile = ImageCmsProfile(outputProfile)
|
||||
return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags)
|
||||
except (IOError, TypeError, ValueError), v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
# (pyCMS) Builds an ICC transform mapping from the inputProfile to the
|
||||
# outputProfile, but tries to simulate the result that would be
|
||||
# obtained on the proofProfile device.
|
||||
|
||||
def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, proofRenderingIntent=INTENT_ABSOLUTE_COLORIMETRIC, flags=FLAGS["SOFTPROOFING"]):
|
||||
"""
|
||||
ImageCms.buildProofTransform(inputProfile, outputProfile, proofProfile,
|
||||
inMode, outMode, [renderingIntent], [proofRenderingIntent])
|
||||
|
||||
Returns a CmsTransform class object.
|
||||
|
||||
inputProfile = string, as a valid filename path to the ICC input
|
||||
profile you wish to use for this transform, or a profile object
|
||||
outputProfile = string, as a valid filename path to the ICC output
|
||||
(monitor, usually) profile you wish to use for this transform,
|
||||
or a profile object
|
||||
proofProfile = string, as a valid filename path to the ICC proof
|
||||
profile you wish to use for this transform, or a profile object
|
||||
inMode = string, as a valid PIL mode that the appropriate profile also
|
||||
supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
outMode = string, as a valid PIL mode that the appropriate profile also
|
||||
supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
renderingIntent = integer (0-3) specifying the rendering intent you
|
||||
wish to use for the input->proof (simulated) transform
|
||||
INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
|
||||
INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
|
||||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
see the pyCMS documentation for details on rendering intents and
|
||||
what they do.
|
||||
proofRenderingIntent = integer (0-3) specifying the rendering intent
|
||||
you wish to use for proof->output transform
|
||||
INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
|
||||
INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
|
||||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
see the pyCMS documentation for details on rendering intents and
|
||||
what they do.
|
||||
flags = integer (0-...) specifying additional flags
|
||||
|
||||
If the input, output, or proof profiles specified are not valid
|
||||
filenames, a PyCMSError will be raised.
|
||||
|
||||
If an error occurs during creation of the transform, a PyCMSError will
|
||||
be raised.
|
||||
|
||||
If inMode or outMode are not a mode supported by the outputProfile
|
||||
(or by pyCMS), a PyCMSError will be raised.
|
||||
|
||||
This function builds and returns an ICC transform from the inputProfile
|
||||
to the outputProfile, but tries to simulate the result that would be
|
||||
obtained on the proofProfile device using renderingIntent and
|
||||
proofRenderingIntent to determine what to do with out-of-gamut
|
||||
colors. This is known as "soft-proofing". It will ONLY work for
|
||||
converting images that are in inMode to images that are in outMode
|
||||
color format (PIL mode, i.e. "RGB", "RGBA", "CMYK", etc.).
|
||||
|
||||
Usage of the resulting transform object is exactly the same as with
|
||||
ImageCms.buildTransform().
|
||||
|
||||
Proof profiling is generally used when using an output device to get a
|
||||
good idea of what the final printed/displayed image would look like on
|
||||
the proofProfile device when it's quicker and easier to use the
|
||||
output device for judging color. Generally, this means that the
|
||||
output device is a monitor, or a dye-sub printer (etc.), and the simulated
|
||||
device is something more expensive, complicated, or time consuming
|
||||
(making it difficult to make a real print for color judgement purposes).
|
||||
|
||||
Soft-proofing basically functions by adjusting the colors on the
|
||||
output device to match the colors of the device being simulated. However,
|
||||
when the simulated device has a much wider gamut than the output
|
||||
device, you may obtain marginal results.
|
||||
|
||||
"""
|
||||
|
||||
if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
|
||||
raise PyCMSError("renderingIntent must be an integer between 0 and 3")
|
||||
|
||||
if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
|
||||
raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
|
||||
try:
|
||||
if not isinstance(inputProfile, ImageCmsProfile):
|
||||
inputProfile = ImageCmsProfile(inputProfile)
|
||||
if not isinstance(outputProfile, ImageCmsProfile):
|
||||
outputProfile = ImageCmsProfile(outputProfile)
|
||||
if not isinstance(proofProfile, ImageCmsProfile):
|
||||
proofProfile = ImageCmsProfile(proofProfile)
|
||||
return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, proofProfile, proofRenderingIntent, flags)
|
||||
except (IOError, TypeError, ValueError), v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
buildTransformFromOpenProfiles = buildTransform
|
||||
buildProofTransformFromOpenProfiles = buildProofTransform
|
||||
|
||||
##
|
||||
# (pyCMS) Applies a transform to a given image.
|
||||
|
||||
def applyTransform(im, transform, inPlace=0):
|
||||
"""
|
||||
ImageCms.applyTransform(im, transform, [inPlace])
|
||||
|
||||
Returns either None, or a new PIL Image object, depending on the value
|
||||
of inPlace (see below)
|
||||
|
||||
im = a PIL Image object, and im.mode must be the same as the inMode
|
||||
supported by the transform.
|
||||
transform = a valid CmsTransform class object
|
||||
inPlace = BOOL (1 == TRUE, 0 or None == FALSE). If TRUE, im is
|
||||
modified in place and None is returned, if FALSE, a new Image
|
||||
object with the transform applied is returned (and im is not
|
||||
changed). The default is FALSE.
|
||||
|
||||
If im.mode != transform.inMode, a PyCMSError is raised.
|
||||
|
||||
If inPlace == TRUE and transform.inMode != transform.outMode, a
|
||||
PyCMSError is raised.
|
||||
|
||||
If im.mode, transfer.inMode, or transfer.outMode is not supported by
|
||||
pyCMSdll or the profiles you used for the transform, a PyCMSError is
|
||||
raised.
|
||||
|
||||
If an error occurs while the transform is being applied, a PyCMSError
|
||||
is raised.
|
||||
|
||||
This function applies a pre-calculated transform (from
|
||||
ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles()) to an
|
||||
image. The transform can be used for multiple images, saving
|
||||
considerable calcuation time if doing the same conversion multiple times.
|
||||
|
||||
If you want to modify im in-place instead of receiving a new image as
|
||||
the return value, set inPlace to TRUE. This can only be done if
|
||||
transform.inMode and transform.outMode are the same, because we can't
|
||||
change the mode in-place (the buffer sizes for some modes are
|
||||
different). The default behavior is to return a new Image object of
|
||||
the same dimensions in mode transform.outMode.
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
if inPlace:
|
||||
transform.apply_in_place(im)
|
||||
imOut = None
|
||||
else:
|
||||
imOut = transform.apply(im)
|
||||
except (TypeError, ValueError), v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
return imOut
|
||||
|
||||
##
|
||||
# (pyCMS) Creates a profile.
|
||||
|
||||
def createProfile(colorSpace, colorTemp=-1):
|
||||
"""
|
||||
ImageCms.createProfile(colorSpace, [colorTemp])
|
||||
|
||||
Returns a CmsProfile class object
|
||||
|
||||
colorSpace = string, the color space of the profile you wish to create.
|
||||
Currently only "LAB", "XYZ", and "sRGB" are supported.
|
||||
colorTemp = positive integer for the white point for the profile, in
|
||||
degrees Kelvin (i.e. 5000, 6500, 9600, etc.). The default is for
|
||||
D50 illuminant if omitted (5000k). colorTemp is ONLY applied to
|
||||
LAB profiles, and is ignored for XYZ and sRGB.
|
||||
|
||||
If colorSpace not in ["LAB", "XYZ", "sRGB"], a PyCMSError is raised
|
||||
|
||||
If using LAB and colorTemp != a positive integer, a PyCMSError is raised.
|
||||
|
||||
If an error occurs while creating the profile, a PyCMSError is raised.
|
||||
|
||||
Use this function to create common profiles on-the-fly instead of
|
||||
having to supply a profile on disk and knowing the path to it. It
|
||||
returns a normal CmsProfile object that can be passed to
|
||||
ImageCms.buildTransformFromOpenProfiles() to create a transform to apply
|
||||
to images.
|
||||
|
||||
"""
|
||||
if colorSpace not in ["LAB", "XYZ", "sRGB"]:
|
||||
raise PyCMSError("Color space not supported for on-the-fly profile creation (%s)" % colorSpace)
|
||||
|
||||
if colorSpace == "LAB":
|
||||
if type(colorTemp) == type(5000.0):
|
||||
colorTemp = int(colorTemp + 0.5)
|
||||
if type (colorTemp) != type (5000):
|
||||
raise PyCMSError("Color temperature must be a positive integer, \"%s\" not valid" % colorTemp)
|
||||
|
||||
try:
|
||||
return core.createProfile(colorSpace, colorTemp)
|
||||
except (TypeError, ValueError), v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
# (pyCMS) Gets the internal product name for the given profile.
|
||||
|
||||
def getProfileName(profile):
|
||||
"""
|
||||
ImageCms.getProfileName(profile)
|
||||
|
||||
Returns a string containing the internal name of the profile as stored
|
||||
in an ICC tag.
|
||||
|
||||
profile = EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
|
||||
If profile isn't a valid CmsProfile object or filename to a profile,
|
||||
a PyCMSError is raised If an error occurs while trying to obtain the
|
||||
name tag, a PyCMSError is raised.
|
||||
|
||||
Use this function to obtain the INTERNAL name of the profile (stored
|
||||
in an ICC tag in the profile itself), usually the one used when the
|
||||
profile was originally created. Sometimes this tag also contains
|
||||
additional information supplied by the creator.
|
||||
|
||||
"""
|
||||
try:
|
||||
# add an extra newline to preserve pyCMS compatibility
|
||||
if not isinstance(profile, ImageCmsProfile):
|
||||
profile = ImageCmsProfile(profile)
|
||||
return profile.profile.product_name + "\n"
|
||||
except (AttributeError, IOError, TypeError, ValueError), v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
# (pyCMS) Gets the internal product information for the given profile.
|
||||
|
||||
def getProfileInfo(profile):
|
||||
"""
|
||||
ImageCms.getProfileInfo(profile)
|
||||
|
||||
Returns a string containing the internal profile information stored in
|
||||
an ICC tag.
|
||||
|
||||
profile = EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
|
||||
If profile isn't a valid CmsProfile object or filename to a profile,
|
||||
a PyCMSError is raised.
|
||||
|
||||
If an error occurs while trying to obtain the info tag, a PyCMSError
|
||||
is raised
|
||||
|
||||
Use this function to obtain the information stored in the profile's
|
||||
info tag. This often contains details about the profile, and how it
|
||||
was created, as supplied by the creator.
|
||||
|
||||
"""
|
||||
try:
|
||||
if not isinstance(profile, ImageCmsProfile):
|
||||
profile = ImageCmsProfile(profile)
|
||||
# add an extra newline to preserve pyCMS compatibility
|
||||
return profile.product_info + "\n"
|
||||
except (AttributeError, IOError, TypeError, ValueError), v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
# (pyCMS) Gets the default intent name for the given profile.
|
||||
|
||||
def getDefaultIntent(profile):
|
||||
"""
|
||||
ImageCms.getDefaultIntent(profile)
|
||||
|
||||
Returns integer 0-3 specifying the default rendering intent for this
|
||||
profile.
|
||||
INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
|
||||
INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
|
||||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
see the pyCMS documentation for details on rendering intents and
|
||||
what they do.
|
||||
|
||||
profile = EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
|
||||
If profile isn't a valid CmsProfile object or filename to a profile,
|
||||
a PyCMSError is raised.
|
||||
|
||||
If an error occurs while trying to obtain the default intent, a
|
||||
PyCMSError is raised.
|
||||
|
||||
Use this function to determine the default (and usually best optomized)
|
||||
rendering intent for this profile. Most profiles support multiple
|
||||
rendering intents, but are intended mostly for one type of conversion.
|
||||
If you wish to use a different intent than returned, use
|
||||
ImageCms.isIntentSupported() to verify it will work first.
|
||||
"""
|
||||
try:
|
||||
if not isinstance(profile, ImageCmsProfile):
|
||||
profile = ImageCmsProfile(profile)
|
||||
return profile.profile.rendering_intent
|
||||
except (AttributeError, IOError, TypeError, ValueError), v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
# (pyCMS) Checks if a given intent is supported.
|
||||
|
||||
def isIntentSupported(profile, intent, direction):
|
||||
"""
|
||||
ImageCms.isIntentSupported(profile, intent, direction)
|
||||
|
||||
Returns 1 if the intent/direction are supported, -1 if they are not.
|
||||
|
||||
profile = EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
intent = integer (0-3) specifying the rendering intent you wish to use
|
||||
with this profile
|
||||
INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
|
||||
INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
|
||||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
see the pyCMS documentation for details on rendering intents and
|
||||
what they do.
|
||||
direction = integer specifing if the profile is to be used for input,
|
||||
output, or proof
|
||||
INPUT = 0 (or use ImageCms.DIRECTION_INPUT)
|
||||
OUTPUT = 1 (or use ImageCms.DIRECTION_OUTPUT)
|
||||
PROOF = 2 (or use ImageCms.DIRECTION_PROOF)
|
||||
|
||||
Use this function to verify that you can use your desired
|
||||
renderingIntent with profile, and that profile can be used for the
|
||||
input/output/proof profile as you desire.
|
||||
|
||||
Some profiles are created specifically for one "direction", can cannot
|
||||
be used for others. Some profiles can only be used for certain
|
||||
rendering intents... so it's best to either verify this before trying
|
||||
to create a transform with them (using this function), or catch the
|
||||
potential PyCMSError that will occur if they don't support the modes
|
||||
you select.
|
||||
|
||||
"""
|
||||
try:
|
||||
if not isinstance(profile, ImageCmsProfile):
|
||||
profile = ImageCmsProfile(profile)
|
||||
# FIXME: I get different results for the same data w. different
|
||||
# compilers. Bug in LittleCMS or in the binding?
|
||||
if profile.profile.is_intent_supported(intent, direction):
|
||||
return 1
|
||||
else:
|
||||
return -1
|
||||
except (AttributeError, IOError, TypeError, ValueError), v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
# (pyCMS) Fetches versions.
|
||||
|
||||
def versions():
|
||||
import sys
|
||||
return (
|
||||
VERSION, core.littlecms_version, sys.version.split()[0], Image.VERSION
|
||||
)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
if __name__ == "__main__":
|
||||
# create a cheap manual from the __doc__ strings for the functions above
|
||||
|
||||
import ImageCms
|
||||
import string
|
||||
print __doc__
|
||||
|
||||
for f in dir(pyCMS):
|
||||
print "="*80
|
||||
print "%s" %f
|
||||
|
||||
try:
|
||||
exec ("doc = ImageCms.%s.__doc__" %(f))
|
||||
if string.find(doc, "pyCMS") >= 0:
|
||||
# so we don't get the __doc__ string for imported modules
|
||||
print doc
|
||||
except AttributeError:
|
||||
pass
|
||||
263
Darwin/lib/python2.7/site-packages/PIL/ImageColor.py
Normal file
263
Darwin/lib/python2.7/site-packages/PIL/ImageColor.py
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# map CSS3-style colour description strings to RGB
|
||||
#
|
||||
# History:
|
||||
# 2002-10-24 fl Added support for CSS-style color strings
|
||||
# 2002-12-15 fl Added RGBA support
|
||||
# 2004-03-27 fl Fixed remaining int() problems for Python 1.5.2
|
||||
# 2004-07-19 fl Fixed gray/grey spelling issues
|
||||
# 2009-03-05 fl Fixed rounding error in grayscale calculation
|
||||
#
|
||||
# Copyright (c) 2002-2004 by Secret Labs AB
|
||||
# Copyright (c) 2002-2004 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
import re, string
|
||||
|
||||
try:
|
||||
x = int("a", 16)
|
||||
except TypeError:
|
||||
# python 1.5.2 doesn't support int(x,b)
|
||||
str2int = string.atoi
|
||||
else:
|
||||
str2int = int
|
||||
|
||||
##
|
||||
# Convert color string to RGB tuple.
|
||||
#
|
||||
# @param color A CSS3-style colour string.
|
||||
# @return An RGB-tuple.
|
||||
# @exception ValueError If the color string could not be interpreted
|
||||
# as an RGB value.
|
||||
|
||||
def getrgb(color):
|
||||
# FIXME: add RGBA support
|
||||
try:
|
||||
rgb = colormap[color]
|
||||
except KeyError:
|
||||
try:
|
||||
# fall back on case-insensitive lookup
|
||||
rgb = colormap[string.lower(color)]
|
||||
except KeyError:
|
||||
rgb = None
|
||||
# found color in cache
|
||||
if rgb:
|
||||
if isinstance(rgb, type(())):
|
||||
return rgb
|
||||
colormap[color] = rgb = getrgb(rgb)
|
||||
return rgb
|
||||
# check for known string formats
|
||||
m = re.match("#\w\w\w$", color)
|
||||
if m:
|
||||
return (
|
||||
str2int(color[1]*2, 16),
|
||||
str2int(color[2]*2, 16),
|
||||
str2int(color[3]*2, 16)
|
||||
)
|
||||
m = re.match("#\w\w\w\w\w\w$", color)
|
||||
if m:
|
||||
return (
|
||||
str2int(color[1:3], 16),
|
||||
str2int(color[3:5], 16),
|
||||
str2int(color[5:7], 16)
|
||||
)
|
||||
m = re.match("rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color)
|
||||
if m:
|
||||
return (
|
||||
str2int(m.group(1)),
|
||||
str2int(m.group(2)),
|
||||
str2int(m.group(3))
|
||||
)
|
||||
m = re.match("rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color)
|
||||
if m:
|
||||
return (
|
||||
int((str2int(m.group(1)) * 255) / 100.0 + 0.5),
|
||||
int((str2int(m.group(2)) * 255) / 100.0 + 0.5),
|
||||
int((str2int(m.group(3)) * 255) / 100.0 + 0.5)
|
||||
)
|
||||
m = re.match("hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color)
|
||||
if m:
|
||||
from colorsys import hls_to_rgb
|
||||
rgb = hls_to_rgb(
|
||||
float(m.group(1)) / 360.0,
|
||||
float(m.group(3)) / 100.0,
|
||||
float(m.group(2)) / 100.0,
|
||||
)
|
||||
return (
|
||||
int(rgb[0] * 255 + 0.5),
|
||||
int(rgb[1] * 255 + 0.5),
|
||||
int(rgb[2] * 255 + 0.5)
|
||||
)
|
||||
raise ValueError("unknown color specifier: %r" % color)
|
||||
|
||||
def getcolor(color, mode):
|
||||
# same as getrgb, but converts the result to the given mode
|
||||
color = getrgb(color)
|
||||
if mode == "RGB":
|
||||
return color
|
||||
if mode == "RGBA":
|
||||
r, g, b = color
|
||||
return r, g, b, 255
|
||||
if Image.getmodebase(mode) == "L":
|
||||
r, g, b = color
|
||||
return (r*299 + g*587 + b*114)/1000
|
||||
return color
|
||||
|
||||
colormap = {
|
||||
# X11 colour table (from "CSS3 module: Color working draft"), with
|
||||
# gray/grey spelling issues fixed. This is a superset of HTML 4.0
|
||||
# colour names used in CSS 1.
|
||||
"aliceblue": "#f0f8ff",
|
||||
"antiquewhite": "#faebd7",
|
||||
"aqua": "#00ffff",
|
||||
"aquamarine": "#7fffd4",
|
||||
"azure": "#f0ffff",
|
||||
"beige": "#f5f5dc",
|
||||
"bisque": "#ffe4c4",
|
||||
"black": "#000000",
|
||||
"blanchedalmond": "#ffebcd",
|
||||
"blue": "#0000ff",
|
||||
"blueviolet": "#8a2be2",
|
||||
"brown": "#a52a2a",
|
||||
"burlywood": "#deb887",
|
||||
"cadetblue": "#5f9ea0",
|
||||
"chartreuse": "#7fff00",
|
||||
"chocolate": "#d2691e",
|
||||
"coral": "#ff7f50",
|
||||
"cornflowerblue": "#6495ed",
|
||||
"cornsilk": "#fff8dc",
|
||||
"crimson": "#dc143c",
|
||||
"cyan": "#00ffff",
|
||||
"darkblue": "#00008b",
|
||||
"darkcyan": "#008b8b",
|
||||
"darkgoldenrod": "#b8860b",
|
||||
"darkgray": "#a9a9a9",
|
||||
"darkgrey": "#a9a9a9",
|
||||
"darkgreen": "#006400",
|
||||
"darkkhaki": "#bdb76b",
|
||||
"darkmagenta": "#8b008b",
|
||||
"darkolivegreen": "#556b2f",
|
||||
"darkorange": "#ff8c00",
|
||||
"darkorchid": "#9932cc",
|
||||
"darkred": "#8b0000",
|
||||
"darksalmon": "#e9967a",
|
||||
"darkseagreen": "#8fbc8f",
|
||||
"darkslateblue": "#483d8b",
|
||||
"darkslategray": "#2f4f4f",
|
||||
"darkslategrey": "#2f4f4f",
|
||||
"darkturquoise": "#00ced1",
|
||||
"darkviolet": "#9400d3",
|
||||
"deeppink": "#ff1493",
|
||||
"deepskyblue": "#00bfff",
|
||||
"dimgray": "#696969",
|
||||
"dimgrey": "#696969",
|
||||
"dodgerblue": "#1e90ff",
|
||||
"firebrick": "#b22222",
|
||||
"floralwhite": "#fffaf0",
|
||||
"forestgreen": "#228b22",
|
||||
"fuchsia": "#ff00ff",
|
||||
"gainsboro": "#dcdcdc",
|
||||
"ghostwhite": "#f8f8ff",
|
||||
"gold": "#ffd700",
|
||||
"goldenrod": "#daa520",
|
||||
"gray": "#808080",
|
||||
"grey": "#808080",
|
||||
"green": "#008000",
|
||||
"greenyellow": "#adff2f",
|
||||
"honeydew": "#f0fff0",
|
||||
"hotpink": "#ff69b4",
|
||||
"indianred": "#cd5c5c",
|
||||
"indigo": "#4b0082",
|
||||
"ivory": "#fffff0",
|
||||
"khaki": "#f0e68c",
|
||||
"lavender": "#e6e6fa",
|
||||
"lavenderblush": "#fff0f5",
|
||||
"lawngreen": "#7cfc00",
|
||||
"lemonchiffon": "#fffacd",
|
||||
"lightblue": "#add8e6",
|
||||
"lightcoral": "#f08080",
|
||||
"lightcyan": "#e0ffff",
|
||||
"lightgoldenrodyellow": "#fafad2",
|
||||
"lightgreen": "#90ee90",
|
||||
"lightgray": "#d3d3d3",
|
||||
"lightgrey": "#d3d3d3",
|
||||
"lightpink": "#ffb6c1",
|
||||
"lightsalmon": "#ffa07a",
|
||||
"lightseagreen": "#20b2aa",
|
||||
"lightskyblue": "#87cefa",
|
||||
"lightslategray": "#778899",
|
||||
"lightslategrey": "#778899",
|
||||
"lightsteelblue": "#b0c4de",
|
||||
"lightyellow": "#ffffe0",
|
||||
"lime": "#00ff00",
|
||||
"limegreen": "#32cd32",
|
||||
"linen": "#faf0e6",
|
||||
"magenta": "#ff00ff",
|
||||
"maroon": "#800000",
|
||||
"mediumaquamarine": "#66cdaa",
|
||||
"mediumblue": "#0000cd",
|
||||
"mediumorchid": "#ba55d3",
|
||||
"mediumpurple": "#9370db",
|
||||
"mediumseagreen": "#3cb371",
|
||||
"mediumslateblue": "#7b68ee",
|
||||
"mediumspringgreen": "#00fa9a",
|
||||
"mediumturquoise": "#48d1cc",
|
||||
"mediumvioletred": "#c71585",
|
||||
"midnightblue": "#191970",
|
||||
"mintcream": "#f5fffa",
|
||||
"mistyrose": "#ffe4e1",
|
||||
"moccasin": "#ffe4b5",
|
||||
"navajowhite": "#ffdead",
|
||||
"navy": "#000080",
|
||||
"oldlace": "#fdf5e6",
|
||||
"olive": "#808000",
|
||||
"olivedrab": "#6b8e23",
|
||||
"orange": "#ffa500",
|
||||
"orangered": "#ff4500",
|
||||
"orchid": "#da70d6",
|
||||
"palegoldenrod": "#eee8aa",
|
||||
"palegreen": "#98fb98",
|
||||
"paleturquoise": "#afeeee",
|
||||
"palevioletred": "#db7093",
|
||||
"papayawhip": "#ffefd5",
|
||||
"peachpuff": "#ffdab9",
|
||||
"peru": "#cd853f",
|
||||
"pink": "#ffc0cb",
|
||||
"plum": "#dda0dd",
|
||||
"powderblue": "#b0e0e6",
|
||||
"purple": "#800080",
|
||||
"red": "#ff0000",
|
||||
"rosybrown": "#bc8f8f",
|
||||
"royalblue": "#4169e1",
|
||||
"saddlebrown": "#8b4513",
|
||||
"salmon": "#fa8072",
|
||||
"sandybrown": "#f4a460",
|
||||
"seagreen": "#2e8b57",
|
||||
"seashell": "#fff5ee",
|
||||
"sienna": "#a0522d",
|
||||
"silver": "#c0c0c0",
|
||||
"skyblue": "#87ceeb",
|
||||
"slateblue": "#6a5acd",
|
||||
"slategray": "#708090",
|
||||
"slategrey": "#708090",
|
||||
"snow": "#fffafa",
|
||||
"springgreen": "#00ff7f",
|
||||
"steelblue": "#4682b4",
|
||||
"tan": "#d2b48c",
|
||||
"teal": "#008080",
|
||||
"thistle": "#d8bfd8",
|
||||
"tomato": "#ff6347",
|
||||
"turquoise": "#40e0d0",
|
||||
"violet": "#ee82ee",
|
||||
"wheat": "#f5deb3",
|
||||
"white": "#ffffff",
|
||||
"whitesmoke": "#f5f5f5",
|
||||
"yellow": "#ffff00",
|
||||
"yellowgreen": "#9acd32",
|
||||
}
|
||||
378
Darwin/lib/python2.7/site-packages/PIL/ImageDraw.py
Normal file
378
Darwin/lib/python2.7/site-packages/PIL/ImageDraw.py
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# drawing interface operations
|
||||
#
|
||||
# History:
|
||||
# 1996-04-13 fl Created (experimental)
|
||||
# 1996-08-07 fl Filled polygons, ellipses.
|
||||
# 1996-08-13 fl Added text support
|
||||
# 1998-06-28 fl Handle I and F images
|
||||
# 1998-12-29 fl Added arc; use arc primitive to draw ellipses
|
||||
# 1999-01-10 fl Added shape stuff (experimental)
|
||||
# 1999-02-06 fl Added bitmap support
|
||||
# 1999-02-11 fl Changed all primitives to take options
|
||||
# 1999-02-20 fl Fixed backwards compatibility
|
||||
# 2000-10-12 fl Copy on write, when necessary
|
||||
# 2001-02-18 fl Use default ink for bitmap/text also in fill mode
|
||||
# 2002-10-24 fl Added support for CSS-style color strings
|
||||
# 2002-12-10 fl Added experimental support for RGBA-on-RGB drawing
|
||||
# 2002-12-11 fl Refactored low-level drawing API (work in progress)
|
||||
# 2004-08-26 fl Made Draw() a factory function, added getdraw() support
|
||||
# 2004-09-04 fl Added width support to line primitive
|
||||
# 2004-09-10 fl Added font mode handling
|
||||
# 2006-06-19 fl Added font bearing support (getmask2)
|
||||
#
|
||||
# Copyright (c) 1997-2006 by Secret Labs AB
|
||||
# Copyright (c) 1996-2006 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageColor
|
||||
|
||||
try:
|
||||
import warnings
|
||||
except ImportError:
|
||||
warnings = None
|
||||
|
||||
##
|
||||
# A simple 2D drawing interface for PIL images.
|
||||
# <p>
|
||||
# Application code should use the <b>Draw</b> factory, instead of
|
||||
# directly.
|
||||
|
||||
class ImageDraw:
|
||||
|
||||
##
|
||||
# Create a drawing instance.
|
||||
#
|
||||
# @param im The image to draw in.
|
||||
# @param mode Optional mode to use for color values. For RGB
|
||||
# images, this argument can be RGB or RGBA (to blend the
|
||||
# drawing into the image). For all other modes, this argument
|
||||
# must be the same as the image mode. If omitted, the mode
|
||||
# defaults to the mode of the image.
|
||||
|
||||
def __init__(self, im, mode=None):
|
||||
im.load()
|
||||
if im.readonly:
|
||||
im._copy() # make it writable
|
||||
blend = 0
|
||||
if mode is None:
|
||||
mode = im.mode
|
||||
if mode != im.mode:
|
||||
if mode == "RGBA" and im.mode == "RGB":
|
||||
blend = 1
|
||||
else:
|
||||
raise ValueError("mode mismatch")
|
||||
if mode == "P":
|
||||
self.palette = im.palette
|
||||
else:
|
||||
self.palette = None
|
||||
self.im = im.im
|
||||
self.draw = Image.core.draw(self.im, blend)
|
||||
self.mode = mode
|
||||
if mode in ("I", "F"):
|
||||
self.ink = self.draw.draw_ink(1, mode)
|
||||
else:
|
||||
self.ink = self.draw.draw_ink(-1, mode)
|
||||
if mode in ("1", "P", "I", "F"):
|
||||
# FIXME: fix Fill2 to properly support matte for I+F images
|
||||
self.fontmode = "1"
|
||||
else:
|
||||
self.fontmode = "L" # aliasing is okay for other modes
|
||||
self.fill = 0
|
||||
self.font = None
|
||||
|
||||
##
|
||||
# Set the default pen color.
|
||||
|
||||
def setink(self, ink):
|
||||
# compatibility
|
||||
if warnings:
|
||||
warnings.warn(
|
||||
"'setink' is deprecated; use keyword arguments instead",
|
||||
DeprecationWarning, stacklevel=2
|
||||
)
|
||||
if Image.isStringType(ink):
|
||||
ink = ImageColor.getcolor(ink, self.mode)
|
||||
if self.palette and not Image.isNumberType(ink):
|
||||
ink = self.palette.getcolor(ink)
|
||||
self.ink = self.draw.draw_ink(ink, self.mode)
|
||||
|
||||
##
|
||||
# Set the default background color.
|
||||
|
||||
def setfill(self, onoff):
|
||||
# compatibility
|
||||
if warnings:
|
||||
warnings.warn(
|
||||
"'setfill' is deprecated; use keyword arguments instead",
|
||||
DeprecationWarning, stacklevel=2
|
||||
)
|
||||
self.fill = onoff
|
||||
|
||||
##
|
||||
# Set the default font.
|
||||
|
||||
def setfont(self, font):
|
||||
# compatibility
|
||||
self.font = font
|
||||
|
||||
##
|
||||
# Get the current default font.
|
||||
|
||||
def getfont(self):
|
||||
if not self.font:
|
||||
# FIXME: should add a font repository
|
||||
import ImageFont
|
||||
self.font = ImageFont.load_default()
|
||||
return self.font
|
||||
|
||||
def _getink(self, ink, fill=None):
|
||||
if ink is None and fill is None:
|
||||
if self.fill:
|
||||
fill = self.ink
|
||||
else:
|
||||
ink = self.ink
|
||||
else:
|
||||
if ink is not None:
|
||||
if Image.isStringType(ink):
|
||||
ink = ImageColor.getcolor(ink, self.mode)
|
||||
if self.palette and not Image.isNumberType(ink):
|
||||
ink = self.palette.getcolor(ink)
|
||||
ink = self.draw.draw_ink(ink, self.mode)
|
||||
if fill is not None:
|
||||
if Image.isStringType(fill):
|
||||
fill = ImageColor.getcolor(fill, self.mode)
|
||||
if self.palette and not Image.isNumberType(fill):
|
||||
fill = self.palette.getcolor(fill)
|
||||
fill = self.draw.draw_ink(fill, self.mode)
|
||||
return ink, fill
|
||||
|
||||
##
|
||||
# Draw an arc.
|
||||
|
||||
def arc(self, xy, start, end, fill=None):
|
||||
ink, fill = self._getink(fill)
|
||||
if ink is not None:
|
||||
self.draw.draw_arc(xy, start, end, ink)
|
||||
|
||||
##
|
||||
# Draw a bitmap.
|
||||
|
||||
def bitmap(self, xy, bitmap, fill=None):
|
||||
bitmap.load()
|
||||
ink, fill = self._getink(fill)
|
||||
if ink is None:
|
||||
ink = fill
|
||||
if ink is not None:
|
||||
self.draw.draw_bitmap(xy, bitmap.im, ink)
|
||||
|
||||
##
|
||||
# Draw a chord.
|
||||
|
||||
def chord(self, xy, start, end, fill=None, outline=None):
|
||||
ink, fill = self._getink(outline, fill)
|
||||
if fill is not None:
|
||||
self.draw.draw_chord(xy, start, end, fill, 1)
|
||||
if ink is not None:
|
||||
self.draw.draw_chord(xy, start, end, ink, 0)
|
||||
|
||||
##
|
||||
# Draw an ellipse.
|
||||
|
||||
def ellipse(self, xy, fill=None, outline=None):
|
||||
ink, fill = self._getink(outline, fill)
|
||||
if fill is not None:
|
||||
self.draw.draw_ellipse(xy, fill, 1)
|
||||
if ink is not None:
|
||||
self.draw.draw_ellipse(xy, ink, 0)
|
||||
|
||||
##
|
||||
# Draw a line, or a connected sequence of line segments.
|
||||
|
||||
def line(self, xy, fill=None, width=0):
|
||||
ink, fill = self._getink(fill)
|
||||
if ink is not None:
|
||||
self.draw.draw_lines(xy, ink, width)
|
||||
|
||||
##
|
||||
# (Experimental) Draw a shape.
|
||||
|
||||
def shape(self, shape, fill=None, outline=None):
|
||||
# experimental
|
||||
shape.close()
|
||||
ink, fill = self._getink(outline, fill)
|
||||
if fill is not None:
|
||||
self.draw.draw_outline(shape, fill, 1)
|
||||
if ink is not None:
|
||||
self.draw.draw_outline(shape, ink, 0)
|
||||
|
||||
##
|
||||
# Draw a pieslice.
|
||||
|
||||
def pieslice(self, xy, start, end, fill=None, outline=None):
|
||||
ink, fill = self._getink(outline, fill)
|
||||
if fill is not None:
|
||||
self.draw.draw_pieslice(xy, start, end, fill, 1)
|
||||
if ink is not None:
|
||||
self.draw.draw_pieslice(xy, start, end, ink, 0)
|
||||
|
||||
##
|
||||
# Draw one or more individual pixels.
|
||||
|
||||
def point(self, xy, fill=None):
|
||||
ink, fill = self._getink(fill)
|
||||
if ink is not None:
|
||||
self.draw.draw_points(xy, ink)
|
||||
|
||||
##
|
||||
# Draw a polygon.
|
||||
|
||||
def polygon(self, xy, fill=None, outline=None):
|
||||
ink, fill = self._getink(outline, fill)
|
||||
if fill is not None:
|
||||
self.draw.draw_polygon(xy, fill, 1)
|
||||
if ink is not None:
|
||||
self.draw.draw_polygon(xy, ink, 0)
|
||||
|
||||
##
|
||||
# Draw a rectangle.
|
||||
|
||||
def rectangle(self, xy, fill=None, outline=None):
|
||||
ink, fill = self._getink(outline, fill)
|
||||
if fill is not None:
|
||||
self.draw.draw_rectangle(xy, fill, 1)
|
||||
if ink is not None:
|
||||
self.draw.draw_rectangle(xy, ink, 0)
|
||||
|
||||
##
|
||||
# Draw text.
|
||||
|
||||
def text(self, xy, text, fill=None, font=None, anchor=None):
|
||||
ink, fill = self._getink(fill)
|
||||
if font is None:
|
||||
font = self.getfont()
|
||||
if ink is None:
|
||||
ink = fill
|
||||
if ink is not None:
|
||||
try:
|
||||
mask, offset = font.getmask2(text, self.fontmode)
|
||||
xy = xy[0] + offset[0], xy[1] + offset[1]
|
||||
except AttributeError:
|
||||
try:
|
||||
mask = font.getmask(text, self.fontmode)
|
||||
except TypeError:
|
||||
mask = font.getmask(text)
|
||||
self.draw.draw_bitmap(xy, mask, ink)
|
||||
|
||||
##
|
||||
# Get the size of a given string, in pixels.
|
||||
|
||||
def textsize(self, text, font=None):
|
||||
if font is None:
|
||||
font = self.getfont()
|
||||
return font.getsize(text)
|
||||
|
||||
##
|
||||
# A simple 2D drawing interface for PIL images.
|
||||
#
|
||||
# @param im The image to draw in.
|
||||
# @param mode Optional mode to use for color values. For RGB
|
||||
# images, this argument can be RGB or RGBA (to blend the
|
||||
# drawing into the image). For all other modes, this argument
|
||||
# must be the same as the image mode. If omitted, the mode
|
||||
# defaults to the mode of the image.
|
||||
|
||||
def Draw(im, mode=None):
|
||||
try:
|
||||
return im.getdraw(mode)
|
||||
except AttributeError:
|
||||
return ImageDraw(im, mode)
|
||||
|
||||
# experimental access to the outline API
|
||||
try:
|
||||
Outline = Image.core.outline
|
||||
except:
|
||||
Outline = None
|
||||
|
||||
##
|
||||
# (Experimental) A more advanced 2D drawing interface for PIL images,
|
||||
# based on the WCK interface.
|
||||
#
|
||||
# @param im The image to draw in.
|
||||
# @param hints An optional list of hints.
|
||||
# @return A (drawing context, drawing resource factory) tuple.
|
||||
|
||||
def getdraw(im=None, hints=None):
|
||||
# FIXME: this needs more work!
|
||||
# FIXME: come up with a better 'hints' scheme.
|
||||
handler = None
|
||||
if not hints or "nicest" in hints:
|
||||
try:
|
||||
import _imagingagg
|
||||
handler = _imagingagg
|
||||
except ImportError:
|
||||
pass
|
||||
if handler is None:
|
||||
import ImageDraw2
|
||||
handler = ImageDraw2
|
||||
if im:
|
||||
im = handler.Draw(im)
|
||||
return im, handler
|
||||
|
||||
##
|
||||
# (experimental) Fills a bounded region with a given color.
|
||||
#
|
||||
# @param image Target image.
|
||||
# @param xy Seed position (a 2-item coordinate tuple).
|
||||
# @param value Fill color.
|
||||
# @param border Optional border value. If given, the region consists of
|
||||
# pixels with a color different from the border color. If not given,
|
||||
# the region consists of pixels having the same color as the seed
|
||||
# pixel.
|
||||
|
||||
def floodfill(image, xy, value, border=None):
|
||||
"Fill bounded region."
|
||||
# based on an implementation by Eric S. Raymond
|
||||
pixel = image.load()
|
||||
x, y = xy
|
||||
try:
|
||||
background = pixel[x, y]
|
||||
if background == value:
|
||||
return # seed point already has fill color
|
||||
pixel[x, y] = value
|
||||
except IndexError:
|
||||
return # seed point outside image
|
||||
edge = [(x, y)]
|
||||
if border is None:
|
||||
while edge:
|
||||
newedge = []
|
||||
for (x, y) in edge:
|
||||
for (s, t) in ((x+1, y), (x-1, y), (x, y+1), (x, y-1)):
|
||||
try:
|
||||
p = pixel[s, t]
|
||||
except IndexError:
|
||||
pass
|
||||
else:
|
||||
if p == background:
|
||||
pixel[s, t] = value
|
||||
newedge.append((s, t))
|
||||
edge = newedge
|
||||
else:
|
||||
while edge:
|
||||
newedge = []
|
||||
for (x, y) in edge:
|
||||
for (s, t) in ((x+1, y), (x-1, y), (x, y+1), (x, y-1)):
|
||||
try:
|
||||
p = pixel[s, t]
|
||||
except IndexError:
|
||||
pass
|
||||
else:
|
||||
if p != value and p != border:
|
||||
pixel[s, t] = value
|
||||
newedge.append((s, t))
|
||||
edge = newedge
|
||||
105
Darwin/lib/python2.7/site-packages/PIL/ImageDraw2.py
Normal file
105
Darwin/lib/python2.7/site-packages/PIL/ImageDraw2.py
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# WCK-style drawing interface operations
|
||||
#
|
||||
# History:
|
||||
# 2003-12-07 fl created
|
||||
# 2005-05-15 fl updated; added to PIL as ImageDraw2
|
||||
# 2005-05-15 fl added text support
|
||||
# 2005-05-20 fl added arc/chord/pieslice support
|
||||
#
|
||||
# Copyright (c) 2003-2005 by Secret Labs AB
|
||||
# Copyright (c) 2003-2005 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageColor, ImageDraw, ImageFont, ImagePath
|
||||
|
||||
class Pen:
|
||||
def __init__(self, color, width=1, opacity=255):
|
||||
self.color = ImageColor.getrgb(color)
|
||||
self.width = width
|
||||
|
||||
class Brush:
|
||||
def __init__(self, color, opacity=255):
|
||||
self.color = ImageColor.getrgb(color)
|
||||
|
||||
class Font:
|
||||
def __init__(self, color, file, size=12):
|
||||
# FIXME: add support for bitmap fonts
|
||||
self.color = ImageColor.getrgb(color)
|
||||
self.font = ImageFont.truetype(file, size)
|
||||
|
||||
class Draw:
|
||||
|
||||
def __init__(self, image, size=None, color=None):
|
||||
if not hasattr(image, "im"):
|
||||
image = Image.new(image, size, color)
|
||||
self.draw = ImageDraw.Draw(image)
|
||||
self.image = image
|
||||
self.transform = None
|
||||
|
||||
def flush(self):
|
||||
return self.image
|
||||
|
||||
def render(self, op, xy, pen, brush=None):
|
||||
# handle color arguments
|
||||
outline = fill = None; width = 1
|
||||
if isinstance(pen, Pen):
|
||||
outline = pen.color
|
||||
width = pen.width
|
||||
elif isinstance(brush, Pen):
|
||||
outline = brush.color
|
||||
width = brush.width
|
||||
if isinstance(brush, Brush):
|
||||
fill = brush.color
|
||||
elif isinstance(pen, Brush):
|
||||
fill = pen.color
|
||||
# handle transformation
|
||||
if self.transform:
|
||||
xy = ImagePath.Path(xy)
|
||||
xy.transform(self.transform)
|
||||
# render the item
|
||||
if op == "line":
|
||||
self.draw.line(xy, fill=outline, width=width)
|
||||
else:
|
||||
getattr(self.draw, op)(xy, fill=fill, outline=outline)
|
||||
|
||||
def settransform(self, (xoffset, yoffset)):
|
||||
self.transform = (1, 0, xoffset, 0, 1, yoffset)
|
||||
|
||||
def arc(self, xy, start, end, *options):
|
||||
self.render("arc", xy, start, end, *options)
|
||||
|
||||
def chord(self, xy, start, end, *options):
|
||||
self.render("chord", xy, start, end, *options)
|
||||
|
||||
def ellipse(self, xy, *options):
|
||||
self.render("ellipse", xy, *options)
|
||||
|
||||
def line(self, xy, *options):
|
||||
self.render("line", xy, *options)
|
||||
|
||||
def pieslice(self, xy, start, end, *options):
|
||||
self.render("pieslice", xy, start, end, *options)
|
||||
|
||||
def polygon(self, xy, *options):
|
||||
self.render("polygon", xy, *options)
|
||||
|
||||
def rectangle(self, xy, *options):
|
||||
self.render("rectangle", xy, *options)
|
||||
|
||||
def symbol(self, xy, symbol, *options):
|
||||
raise NotImplementedError("not in this version")
|
||||
|
||||
def text(self, xy, text, font):
|
||||
if self.transform:
|
||||
xy = ImagePath.Path(xy)
|
||||
xy.transform(self.transform)
|
||||
self.draw.text(xy, text, font=font.font, fill=font.color)
|
||||
|
||||
def textsize(self, text, font):
|
||||
return self.draw.textsize(text, font=font.font)
|
||||
90
Darwin/lib/python2.7/site-packages/PIL/ImageEnhance.py
Normal file
90
Darwin/lib/python2.7/site-packages/PIL/ImageEnhance.py
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# image enhancement classes
|
||||
#
|
||||
# For a background, see "Image Processing By Interpolation and
|
||||
# Extrapolation", Paul Haeberli and Douglas Voorhies. Available
|
||||
# at http://www.sgi.com/grafica/interp/index.html
|
||||
#
|
||||
# History:
|
||||
# 1996-03-23 fl Created
|
||||
# 2009-06-16 fl Fixed mean calculation
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 1997.
|
||||
# Copyright (c) Fredrik Lundh 1996.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFilter, ImageStat
|
||||
|
||||
class _Enhance:
|
||||
|
||||
##
|
||||
# Returns an enhanced image. The enhancement factor is a floating
|
||||
# point value controlling the enhancement. Factor 1.0 always
|
||||
# returns a copy of the original image, lower factors mean less
|
||||
# colour (brightness, contrast, etc), and higher values more.
|
||||
# There are no restrictions on this value.
|
||||
#
|
||||
# @param factor Enhancement factor.
|
||||
# @return An enhanced image.
|
||||
|
||||
def enhance(self, factor):
|
||||
return Image.blend(self.degenerate, self.image, factor)
|
||||
|
||||
##
|
||||
# Color enhancement object.
|
||||
# <p>
|
||||
# This class can be used to adjust the colour balance of an image, in
|
||||
# a manner similar to the controls on a colour TV set. An enhancement
|
||||
# factor of 0.0 gives a black and white image, a factor of 1.0 gives
|
||||
# the original image.
|
||||
|
||||
class Color(_Enhance):
|
||||
"Adjust image colour balance"
|
||||
def __init__(self, image):
|
||||
self.image = image
|
||||
self.degenerate = image.convert("L").convert(image.mode)
|
||||
|
||||
##
|
||||
# Contrast enhancement object.
|
||||
# <p>
|
||||
# This class can be used to control the contrast of an image, similar
|
||||
# to the contrast control on a TV set. An enhancement factor of 0.0
|
||||
# gives a solid grey image, factor 1.0 gives the original image.
|
||||
|
||||
class Contrast(_Enhance):
|
||||
"Adjust image contrast"
|
||||
def __init__(self, image):
|
||||
self.image = image
|
||||
mean = int(ImageStat.Stat(image.convert("L")).mean[0] + 0.5)
|
||||
self.degenerate = Image.new("L", image.size, mean).convert(image.mode)
|
||||
|
||||
##
|
||||
# Brightness enhancement object.
|
||||
# <p>
|
||||
# This class can be used to control the brighntess of an image. An
|
||||
# enhancement factor of 0.0 gives a black image, factor 1.0 gives the
|
||||
# original image.
|
||||
|
||||
class Brightness(_Enhance):
|
||||
"Adjust image brightness"
|
||||
def __init__(self, image):
|
||||
self.image = image
|
||||
self.degenerate = Image.new(image.mode, image.size, 0)
|
||||
|
||||
##
|
||||
# Sharpness enhancement object.
|
||||
# <p>
|
||||
# This class can be used to adjust the sharpness of an image. The
|
||||
# enhancement factor 0.0 gives a blurred image, 1.0 gives the original
|
||||
# image, and a factor of 2.0 gives a sharpened image.
|
||||
|
||||
class Sharpness(_Enhance):
|
||||
"Adjust image sharpness"
|
||||
def __init__(self, image):
|
||||
self.image = image
|
||||
self.degenerate = image.filter(ImageFilter.SMOOTH)
|
||||
528
Darwin/lib/python2.7/site-packages/PIL/ImageFile.py
Normal file
528
Darwin/lib/python2.7/site-packages/PIL/ImageFile.py
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# base class for image file handlers
|
||||
#
|
||||
# history:
|
||||
# 1995-09-09 fl Created
|
||||
# 1996-03-11 fl Fixed load mechanism.
|
||||
# 1996-04-15 fl Added pcx/xbm decoders.
|
||||
# 1996-04-30 fl Added encoders.
|
||||
# 1996-12-14 fl Added load helpers
|
||||
# 1997-01-11 fl Use encode_to_file where possible
|
||||
# 1997-08-27 fl Flush output in _save
|
||||
# 1998-03-05 fl Use memory mapping for some modes
|
||||
# 1999-02-04 fl Use memory mapping also for "I;16" and "I;16B"
|
||||
# 1999-05-31 fl Added image parser
|
||||
# 2000-10-12 fl Set readonly flag on memory-mapped images
|
||||
# 2002-03-20 fl Use better messages for common decoder errors
|
||||
# 2003-04-21 fl Fall back on mmap/map_buffer if map is not available
|
||||
# 2003-10-30 fl Added StubImageFile class
|
||||
# 2004-02-25 fl Made incremental parser more robust
|
||||
#
|
||||
# Copyright (c) 1997-2004 by Secret Labs AB
|
||||
# Copyright (c) 1995-2004 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
import traceback, string, os
|
||||
|
||||
MAXBLOCK = 65536
|
||||
|
||||
SAFEBLOCK = 1024*1024
|
||||
|
||||
ERRORS = {
|
||||
-1: "image buffer overrun error",
|
||||
-2: "decoding error",
|
||||
-3: "unknown error",
|
||||
-8: "bad configuration",
|
||||
-9: "out of memory error"
|
||||
}
|
||||
|
||||
def raise_ioerror(error):
|
||||
try:
|
||||
message = Image.core.getcodecstatus(error)
|
||||
except AttributeError:
|
||||
message = ERRORS.get(error)
|
||||
if not message:
|
||||
message = "decoder error %d" % error
|
||||
raise IOError(message + " when reading image file")
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Helpers
|
||||
|
||||
def _tilesort(t1, t2):
|
||||
# sort on offset
|
||||
return cmp(t1[2], t2[2])
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# ImageFile base class
|
||||
|
||||
##
|
||||
# Base class for image file handlers.
|
||||
|
||||
class ImageFile(Image.Image):
|
||||
"Base class for image file format handlers."
|
||||
|
||||
def __init__(self, fp=None, filename=None):
|
||||
Image.Image.__init__(self)
|
||||
|
||||
self.tile = None
|
||||
self.readonly = 1 # until we know better
|
||||
|
||||
self.decoderconfig = ()
|
||||
self.decodermaxblock = MAXBLOCK
|
||||
|
||||
if Image.isStringType(fp):
|
||||
# filename
|
||||
self.fp = open(fp, "rb")
|
||||
self.filename = fp
|
||||
else:
|
||||
# stream
|
||||
self.fp = fp
|
||||
self.filename = filename
|
||||
|
||||
try:
|
||||
self._open()
|
||||
except IndexError, v: # end of data
|
||||
if Image.DEBUG > 1:
|
||||
traceback.print_exc()
|
||||
raise SyntaxError, v
|
||||
except TypeError, v: # end of data (ord)
|
||||
if Image.DEBUG > 1:
|
||||
traceback.print_exc()
|
||||
raise SyntaxError, v
|
||||
except KeyError, v: # unsupported mode
|
||||
if Image.DEBUG > 1:
|
||||
traceback.print_exc()
|
||||
raise SyntaxError, v
|
||||
except EOFError, v: # got header but not the first frame
|
||||
if Image.DEBUG > 1:
|
||||
traceback.print_exc()
|
||||
raise SyntaxError, v
|
||||
|
||||
if not self.mode or self.size[0] <= 0:
|
||||
raise SyntaxError, "not identified by this driver"
|
||||
|
||||
def draft(self, mode, size):
|
||||
"Set draft mode"
|
||||
|
||||
pass
|
||||
|
||||
def verify(self):
|
||||
"Check file integrity"
|
||||
|
||||
# raise exception if something's wrong. must be called
|
||||
# directly after open, and closes file when finished.
|
||||
self.fp = None
|
||||
|
||||
def load(self):
|
||||
"Load image data based on tile list"
|
||||
|
||||
pixel = Image.Image.load(self)
|
||||
|
||||
if self.tile is None:
|
||||
raise IOError("cannot load this image")
|
||||
if not self.tile:
|
||||
return pixel
|
||||
|
||||
self.map = None
|
||||
|
||||
readonly = 0
|
||||
|
||||
if self.filename and len(self.tile) == 1:
|
||||
# try memory mapping
|
||||
d, e, o, a = self.tile[0]
|
||||
if d == "raw" and a[0] == self.mode and a[0] in Image._MAPMODES:
|
||||
try:
|
||||
if hasattr(Image.core, "map"):
|
||||
# use built-in mapper
|
||||
self.map = Image.core.map(self.filename)
|
||||
self.map.seek(o)
|
||||
self.im = self.map.readimage(
|
||||
self.mode, self.size, a[1], a[2]
|
||||
)
|
||||
else:
|
||||
# use mmap, if possible
|
||||
import mmap
|
||||
file = open(self.filename, "r+")
|
||||
size = os.path.getsize(self.filename)
|
||||
# FIXME: on Unix, use PROT_READ etc
|
||||
self.map = mmap.mmap(file.fileno(), size)
|
||||
self.im = Image.core.map_buffer(
|
||||
self.map, self.size, d, e, o, a
|
||||
)
|
||||
readonly = 1
|
||||
except (AttributeError, EnvironmentError, ImportError):
|
||||
self.map = None
|
||||
|
||||
self.load_prepare()
|
||||
|
||||
# look for read/seek overrides
|
||||
try:
|
||||
read = self.load_read
|
||||
except AttributeError:
|
||||
read = self.fp.read
|
||||
|
||||
try:
|
||||
seek = self.load_seek
|
||||
except AttributeError:
|
||||
seek = self.fp.seek
|
||||
|
||||
if not self.map:
|
||||
|
||||
# sort tiles in file order
|
||||
self.tile.sort(_tilesort)
|
||||
|
||||
try:
|
||||
# FIXME: This is a hack to handle TIFF's JpegTables tag.
|
||||
prefix = self.tile_prefix
|
||||
except AttributeError:
|
||||
prefix = ""
|
||||
|
||||
for d, e, o, a in self.tile:
|
||||
d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
|
||||
seek(o)
|
||||
try:
|
||||
d.setimage(self.im, e)
|
||||
except ValueError:
|
||||
continue
|
||||
b = prefix
|
||||
t = len(b)
|
||||
while 1:
|
||||
s = read(self.decodermaxblock)
|
||||
if not s:
|
||||
self.tile = []
|
||||
raise IOError("image file is truncated (%d bytes not processed)" % len(b))
|
||||
b = b + s
|
||||
n, e = d.decode(b)
|
||||
if n < 0:
|
||||
break
|
||||
b = b[n:]
|
||||
t = t + n
|
||||
|
||||
self.tile = []
|
||||
self.readonly = readonly
|
||||
|
||||
self.fp = None # might be shared
|
||||
|
||||
if not self.map and e < 0:
|
||||
raise_ioerror(e)
|
||||
|
||||
# post processing
|
||||
if hasattr(self, "tile_post_rotate"):
|
||||
# FIXME: This is a hack to handle rotated PCD's
|
||||
self.im = self.im.rotate(self.tile_post_rotate)
|
||||
self.size = self.im.size
|
||||
|
||||
self.load_end()
|
||||
|
||||
return Image.Image.load(self)
|
||||
|
||||
def load_prepare(self):
|
||||
# create image memory if necessary
|
||||
if not self.im or\
|
||||
self.im.mode != self.mode or self.im.size != self.size:
|
||||
self.im = Image.core.new(self.mode, self.size)
|
||||
# create palette (optional)
|
||||
if self.mode == "P":
|
||||
Image.Image.load(self)
|
||||
|
||||
def load_end(self):
|
||||
# may be overridden
|
||||
pass
|
||||
|
||||
# may be defined for contained formats
|
||||
# def load_seek(self, pos):
|
||||
# pass
|
||||
|
||||
# may be defined for blocked formats (e.g. PNG)
|
||||
# def load_read(self, bytes):
|
||||
# pass
|
||||
|
||||
##
|
||||
# Base class for stub image loaders.
|
||||
# <p>
|
||||
# A stub loader is an image loader that can identify files of a
|
||||
# certain format, but relies on external code to load the file.
|
||||
|
||||
class StubImageFile(ImageFile):
|
||||
"Base class for stub image loaders."
|
||||
|
||||
def _open(self):
|
||||
raise NotImplementedError(
|
||||
"StubImageFile subclass must implement _open"
|
||||
)
|
||||
|
||||
def load(self):
|
||||
loader = self._load()
|
||||
if loader is None:
|
||||
raise IOError("cannot find loader for this %s file" % self.format)
|
||||
image = loader.load(self)
|
||||
assert image is not None
|
||||
# become the other object (!)
|
||||
self.__class__ = image.__class__
|
||||
self.__dict__ = image.__dict__
|
||||
|
||||
##
|
||||
# (Hook) Find actual image loader.
|
||||
|
||||
def _load(self):
|
||||
raise NotImplementedError(
|
||||
"StubImageFile subclass must implement _load"
|
||||
)
|
||||
|
||||
##
|
||||
# (Internal) Support class for the <b>Parser</b> file.
|
||||
|
||||
class _ParserFile:
|
||||
# parser support class.
|
||||
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.offset = 0
|
||||
|
||||
def close(self):
|
||||
self.data = self.offset = None
|
||||
|
||||
def tell(self):
|
||||
return self.offset
|
||||
|
||||
def seek(self, offset, whence=0):
|
||||
if whence == 0:
|
||||
self.offset = offset
|
||||
elif whence == 1:
|
||||
self.offset = self.offset + offset
|
||||
else:
|
||||
# force error in Image.open
|
||||
raise IOError("illegal argument to seek")
|
||||
|
||||
def read(self, bytes=0):
|
||||
pos = self.offset
|
||||
if bytes:
|
||||
data = self.data[pos:pos+bytes]
|
||||
else:
|
||||
data = self.data[pos:]
|
||||
self.offset = pos + len(data)
|
||||
return data
|
||||
|
||||
def readline(self):
|
||||
# FIXME: this is slow!
|
||||
s = ""
|
||||
while 1:
|
||||
c = self.read(1)
|
||||
if not c:
|
||||
break
|
||||
s = s + c
|
||||
if c == "\n":
|
||||
break
|
||||
return s
|
||||
|
||||
##
|
||||
# Incremental image parser. This class implements the standard
|
||||
# feed/close consumer interface.
|
||||
|
||||
class Parser:
|
||||
|
||||
incremental = None
|
||||
image = None
|
||||
data = None
|
||||
decoder = None
|
||||
finished = 0
|
||||
|
||||
##
|
||||
# (Consumer) Reset the parser. Note that you can only call this
|
||||
# method immediately after you've created a parser; parser
|
||||
# instances cannot be reused.
|
||||
|
||||
def reset(self):
|
||||
assert self.data is None, "cannot reuse parsers"
|
||||
|
||||
##
|
||||
# (Consumer) Feed data to the parser.
|
||||
#
|
||||
# @param data A string buffer.
|
||||
# @exception IOError If the parser failed to parse the image file.
|
||||
|
||||
def feed(self, data):
|
||||
# collect data
|
||||
|
||||
if self.finished:
|
||||
return
|
||||
|
||||
if self.data is None:
|
||||
self.data = data
|
||||
else:
|
||||
self.data = self.data + data
|
||||
|
||||
# parse what we have
|
||||
if self.decoder:
|
||||
|
||||
if self.offset > 0:
|
||||
# skip header
|
||||
skip = min(len(self.data), self.offset)
|
||||
self.data = self.data[skip:]
|
||||
self.offset = self.offset - skip
|
||||
if self.offset > 0 or not self.data:
|
||||
return
|
||||
|
||||
n, e = self.decoder.decode(self.data)
|
||||
|
||||
if n < 0:
|
||||
# end of stream
|
||||
self.data = None
|
||||
self.finished = 1
|
||||
if e < 0:
|
||||
# decoding error
|
||||
self.image = None
|
||||
raise_ioerror(e)
|
||||
else:
|
||||
# end of image
|
||||
return
|
||||
self.data = self.data[n:]
|
||||
|
||||
elif self.image:
|
||||
|
||||
# if we end up here with no decoder, this file cannot
|
||||
# be incrementally parsed. wait until we've gotten all
|
||||
# available data
|
||||
pass
|
||||
|
||||
else:
|
||||
|
||||
# attempt to open this file
|
||||
try:
|
||||
try:
|
||||
fp = _ParserFile(self.data)
|
||||
im = Image.open(fp)
|
||||
finally:
|
||||
fp.close() # explicitly close the virtual file
|
||||
except IOError:
|
||||
pass # not enough data
|
||||
else:
|
||||
flag = hasattr(im, "load_seek") or hasattr(im, "load_read")
|
||||
if flag or len(im.tile) != 1:
|
||||
# custom load code, or multiple tiles
|
||||
self.decode = None
|
||||
else:
|
||||
# initialize decoder
|
||||
im.load_prepare()
|
||||
d, e, o, a = im.tile[0]
|
||||
im.tile = []
|
||||
self.decoder = Image._getdecoder(
|
||||
im.mode, d, a, im.decoderconfig
|
||||
)
|
||||
self.decoder.setimage(im.im, e)
|
||||
|
||||
# calculate decoder offset
|
||||
self.offset = o
|
||||
if self.offset <= len(self.data):
|
||||
self.data = self.data[self.offset:]
|
||||
self.offset = 0
|
||||
|
||||
self.image = im
|
||||
|
||||
##
|
||||
# (Consumer) Close the stream.
|
||||
#
|
||||
# @return An image object.
|
||||
# @exception IOError If the parser failed to parse the image file.
|
||||
|
||||
def close(self):
|
||||
# finish decoding
|
||||
if self.decoder:
|
||||
# get rid of what's left in the buffers
|
||||
self.feed("")
|
||||
self.data = self.decoder = None
|
||||
if not self.finished:
|
||||
raise IOError("image was incomplete")
|
||||
if not self.image:
|
||||
raise IOError("cannot parse this image")
|
||||
if self.data:
|
||||
# incremental parsing not possible; reopen the file
|
||||
# not that we have all data
|
||||
try:
|
||||
fp = _ParserFile(self.data)
|
||||
self.image = Image.open(fp)
|
||||
finally:
|
||||
self.image.load()
|
||||
fp.close() # explicitly close the virtual file
|
||||
return self.image
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
##
|
||||
# (Helper) Save image body to file.
|
||||
#
|
||||
# @param im Image object.
|
||||
# @param fp File object.
|
||||
# @param tile Tile list.
|
||||
|
||||
def _save(im, fp, tile):
|
||||
"Helper to save image based on tile list"
|
||||
|
||||
im.load()
|
||||
if not hasattr(im, "encoderconfig"):
|
||||
im.encoderconfig = ()
|
||||
tile.sort(_tilesort)
|
||||
# FIXME: make MAXBLOCK a configuration parameter
|
||||
bufsize = max(MAXBLOCK, im.size[0] * 4) # see RawEncode.c
|
||||
try:
|
||||
fh = fp.fileno()
|
||||
fp.flush()
|
||||
except AttributeError:
|
||||
# compress to Python file-compatible object
|
||||
for e, b, o, a in tile:
|
||||
e = Image._getencoder(im.mode, e, a, im.encoderconfig)
|
||||
if o > 0:
|
||||
fp.seek(o, 0)
|
||||
e.setimage(im.im, b)
|
||||
while 1:
|
||||
l, s, d = e.encode(bufsize)
|
||||
fp.write(d)
|
||||
if s:
|
||||
break
|
||||
if s < 0:
|
||||
raise IOError("encoder error %d when writing image file" % s)
|
||||
else:
|
||||
# slight speedup: compress to real file object
|
||||
for e, b, o, a in tile:
|
||||
e = Image._getencoder(im.mode, e, a, im.encoderconfig)
|
||||
if o > 0:
|
||||
fp.seek(o, 0)
|
||||
e.setimage(im.im, b)
|
||||
s = e.encode_to_file(fh, bufsize)
|
||||
if s < 0:
|
||||
raise IOError("encoder error %d when writing image file" % s)
|
||||
try:
|
||||
fp.flush()
|
||||
except: pass
|
||||
|
||||
|
||||
##
|
||||
# Reads large blocks in a safe way. Unlike fp.read(n), this function
|
||||
# doesn't trust the user. If the requested size is larger than
|
||||
# SAFEBLOCK, the file is read block by block.
|
||||
#
|
||||
# @param fp File handle. Must implement a <b>read</b> method.
|
||||
# @param size Number of bytes to read.
|
||||
# @return A string containing up to <i>size</i> bytes of data.
|
||||
|
||||
def _safe_read(fp, size):
|
||||
if size <= 0:
|
||||
return ""
|
||||
if size <= SAFEBLOCK:
|
||||
return fp.read(size)
|
||||
data = []
|
||||
while size > 0:
|
||||
block = fp.read(min(size, SAFEBLOCK))
|
||||
if not block:
|
||||
break
|
||||
data.append(block)
|
||||
size = size - len(block)
|
||||
return string.join(data, "")
|
||||
39
Darwin/lib/python2.7/site-packages/PIL/ImageFileIO.py
Normal file
39
Darwin/lib/python2.7/site-packages/PIL/ImageFileIO.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# kludge to get basic ImageFileIO functionality
|
||||
#
|
||||
# History:
|
||||
# 1998-08-06 fl Recreated
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 1998-2002.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from StringIO import StringIO
|
||||
|
||||
##
|
||||
# The <b>ImageFileIO</b> module can be used to read an image from a
|
||||
# socket, or any other stream device.
|
||||
# <p>
|
||||
# This module is deprecated. New code should use the <b>Parser</b>
|
||||
# class in the <a href="imagefile">ImageFile</a> module instead.
|
||||
#
|
||||
# @see ImageFile#Parser
|
||||
|
||||
class ImageFileIO(StringIO):
|
||||
|
||||
##
|
||||
# Adds buffering to a stream file object, in order to
|
||||
# provide <b>seek</b> and <b>tell</b> methods required
|
||||
# by the <b>Image.open</b> method. The stream object must
|
||||
# implement <b>read</b> and <b>close</b> methods.
|
||||
#
|
||||
# @param fp Stream file handle.
|
||||
# @see Image#open
|
||||
|
||||
def __init__(self, fp):
|
||||
data = fp.read()
|
||||
StringIO.__init__(self, data)
|
||||
289
Darwin/lib/python2.7/site-packages/PIL/ImageFilter.py
Normal file
289
Darwin/lib/python2.7/site-packages/PIL/ImageFilter.py
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# standard filters
|
||||
#
|
||||
# History:
|
||||
# 1995-11-27 fl Created
|
||||
# 2002-06-08 fl Added rank and mode filters
|
||||
# 2003-09-15 fl Fixed rank calculation in rank filter; added expand call
|
||||
#
|
||||
# Copyright (c) 1997-2003 by Secret Labs AB.
|
||||
# Copyright (c) 1995-2002 by Fredrik Lundh.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
class Filter:
|
||||
pass
|
||||
|
||||
##
|
||||
# Convolution filter kernel.
|
||||
|
||||
class Kernel(Filter):
|
||||
|
||||
##
|
||||
# Create a convolution kernel. The current version only
|
||||
# supports 3x3 and 5x5 integer and floating point kernels.
|
||||
# <p>
|
||||
# In the current version, kernels can only be applied to
|
||||
# "L" and "RGB" images.
|
||||
#
|
||||
# @def __init__(size, kernel, **options)
|
||||
# @param size Kernel size, given as (width, height). In
|
||||
# the current version, this must be (3,3) or (5,5).
|
||||
# @param kernel A sequence containing kernel weights.
|
||||
# @param **options Optional keyword arguments.
|
||||
# @keyparam scale Scale factor. If given, the result for each
|
||||
# pixel is divided by this value. The default is the sum
|
||||
# of the kernel weights.
|
||||
# @keyparam offset Offset. If given, this value is added to the
|
||||
# result, after it has been divided by the scale factor.
|
||||
|
||||
def __init__(self, size, kernel, scale=None, offset=0):
|
||||
if scale is None:
|
||||
# default scale is sum of kernel
|
||||
scale = reduce(lambda a,b: a+b, kernel)
|
||||
if size[0] * size[1] != len(kernel):
|
||||
raise ValueError("not enough coefficients in kernel")
|
||||
self.filterargs = size, scale, offset, kernel
|
||||
|
||||
def filter(self, image):
|
||||
if image.mode == "P":
|
||||
raise ValueError("cannot filter palette images")
|
||||
return apply(image.filter, self.filterargs)
|
||||
|
||||
class BuiltinFilter(Kernel):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
##
|
||||
# Rank filter.
|
||||
|
||||
class RankFilter(Filter):
|
||||
name = "Rank"
|
||||
|
||||
##
|
||||
# Create a rank filter. The rank filter sorts all pixels in
|
||||
# a window of the given size, and returns the rank'th value.
|
||||
#
|
||||
# @param size The kernel size, in pixels.
|
||||
# @param rank What pixel value to pick. Use 0 for a min filter,
|
||||
# size*size/2 for a median filter, size*size-1 for a max filter,
|
||||
# etc.
|
||||
|
||||
def __init__(self, size, rank):
|
||||
self.size = size
|
||||
self.rank = rank
|
||||
|
||||
def filter(self, image):
|
||||
if image.mode == "P":
|
||||
raise ValueError("cannot filter palette images")
|
||||
image = image.expand(self.size/2, self.size/2)
|
||||
return image.rankfilter(self.size, self.rank)
|
||||
|
||||
##
|
||||
# Median filter. Picks the median pixel value in a window with the
|
||||
# given size.
|
||||
|
||||
class MedianFilter(RankFilter):
|
||||
name = "Median"
|
||||
|
||||
##
|
||||
# Create a median filter.
|
||||
#
|
||||
# @param size The kernel size, in pixels.
|
||||
|
||||
def __init__(self, size=3):
|
||||
self.size = size
|
||||
self.rank = size*size/2
|
||||
|
||||
##
|
||||
# Min filter. Picks the lowest pixel value in a window with the given
|
||||
# size.
|
||||
|
||||
class MinFilter(RankFilter):
|
||||
name = "Min"
|
||||
|
||||
##
|
||||
# Create a min filter.
|
||||
#
|
||||
# @param size The kernel size, in pixels.
|
||||
|
||||
def __init__(self, size=3):
|
||||
self.size = size
|
||||
self.rank = 0
|
||||
|
||||
##
|
||||
# Max filter. Picks the largest pixel value in a window with the
|
||||
# given size.
|
||||
|
||||
class MaxFilter(RankFilter):
|
||||
name = "Max"
|
||||
|
||||
##
|
||||
# Create a max filter.
|
||||
#
|
||||
# @param size The kernel size, in pixels.
|
||||
|
||||
def __init__(self, size=3):
|
||||
self.size = size
|
||||
self.rank = size*size-1
|
||||
|
||||
##
|
||||
# Mode filter. Picks the most frequent pixel value in a box with the
|
||||
# given size. Pixel values that occur only once or twice are ignored;
|
||||
# if no pixel value occurs more than twice, the original pixel value
|
||||
# is preserved.
|
||||
|
||||
class ModeFilter(Filter):
|
||||
name = "Mode"
|
||||
|
||||
##
|
||||
# Create a mode filter.
|
||||
#
|
||||
# @param size The kernel size, in pixels.
|
||||
|
||||
def __init__(self, size=3):
|
||||
self.size = size
|
||||
def filter(self, image):
|
||||
return image.modefilter(self.size)
|
||||
|
||||
##
|
||||
# Gaussian blur filter.
|
||||
|
||||
class GaussianBlur(Filter):
|
||||
name = "GaussianBlur"
|
||||
|
||||
def __init__(self, radius=2):
|
||||
self.radius = 2
|
||||
def filter(self, image):
|
||||
return image.gaussian_blur(self.radius)
|
||||
|
||||
##
|
||||
# Unsharp mask filter.
|
||||
|
||||
class UnsharpMask(Filter):
|
||||
name = "UnsharpMask"
|
||||
|
||||
def __init__(self, radius=2, percent=150, threshold=3):
|
||||
self.radius = 2
|
||||
self.percent = percent
|
||||
self.threshold = threshold
|
||||
def filter(self, image):
|
||||
return image.unsharp_mask(self.radius, self.percent, self.threshold)
|
||||
|
||||
##
|
||||
# Simple blur filter.
|
||||
|
||||
class BLUR(BuiltinFilter):
|
||||
name = "Blur"
|
||||
filterargs = (5, 5), 16, 0, (
|
||||
1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 1
|
||||
)
|
||||
|
||||
##
|
||||
# Simple contour filter.
|
||||
|
||||
class CONTOUR(BuiltinFilter):
|
||||
name = "Contour"
|
||||
filterargs = (3, 3), 1, 255, (
|
||||
-1, -1, -1,
|
||||
-1, 8, -1,
|
||||
-1, -1, -1
|
||||
)
|
||||
|
||||
##
|
||||
# Simple detail filter.
|
||||
|
||||
class DETAIL(BuiltinFilter):
|
||||
name = "Detail"
|
||||
filterargs = (3, 3), 6, 0, (
|
||||
0, -1, 0,
|
||||
-1, 10, -1,
|
||||
0, -1, 0
|
||||
)
|
||||
|
||||
##
|
||||
# Simple edge enhancement filter.
|
||||
|
||||
class EDGE_ENHANCE(BuiltinFilter):
|
||||
name = "Edge-enhance"
|
||||
filterargs = (3, 3), 2, 0, (
|
||||
-1, -1, -1,
|
||||
-1, 10, -1,
|
||||
-1, -1, -1
|
||||
)
|
||||
|
||||
##
|
||||
# Simple stronger edge enhancement filter.
|
||||
|
||||
class EDGE_ENHANCE_MORE(BuiltinFilter):
|
||||
name = "Edge-enhance More"
|
||||
filterargs = (3, 3), 1, 0, (
|
||||
-1, -1, -1,
|
||||
-1, 9, -1,
|
||||
-1, -1, -1
|
||||
)
|
||||
|
||||
##
|
||||
# Simple embossing filter.
|
||||
|
||||
class EMBOSS(BuiltinFilter):
|
||||
name = "Emboss"
|
||||
filterargs = (3, 3), 1, 128, (
|
||||
-1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0
|
||||
)
|
||||
|
||||
##
|
||||
# Simple edge-finding filter.
|
||||
|
||||
class FIND_EDGES(BuiltinFilter):
|
||||
name = "Find Edges"
|
||||
filterargs = (3, 3), 1, 0, (
|
||||
-1, -1, -1,
|
||||
-1, 8, -1,
|
||||
-1, -1, -1
|
||||
)
|
||||
|
||||
##
|
||||
# Simple smoothing filter.
|
||||
|
||||
class SMOOTH(BuiltinFilter):
|
||||
name = "Smooth"
|
||||
filterargs = (3, 3), 13, 0, (
|
||||
1, 1, 1,
|
||||
1, 5, 1,
|
||||
1, 1, 1
|
||||
)
|
||||
|
||||
##
|
||||
# Simple stronger smoothing filter.
|
||||
|
||||
class SMOOTH_MORE(BuiltinFilter):
|
||||
name = "Smooth More"
|
||||
filterargs = (5, 5), 100, 0, (
|
||||
1, 1, 1, 1, 1,
|
||||
1, 5, 5, 5, 1,
|
||||
1, 5, 44, 5, 1,
|
||||
1, 5, 5, 5, 1,
|
||||
1, 1, 1, 1, 1
|
||||
)
|
||||
|
||||
##
|
||||
# Simple sharpening filter.
|
||||
|
||||
class SHARPEN(BuiltinFilter):
|
||||
name = "Sharpen"
|
||||
filterargs = (3, 3), 16, 0, (
|
||||
-2, -2, -2,
|
||||
-2, 32, -2,
|
||||
-2, -2, -2
|
||||
)
|
||||
390
Darwin/lib/python2.7/site-packages/PIL/ImageFont.py
Normal file
390
Darwin/lib/python2.7/site-packages/PIL/ImageFont.py
Normal file
|
|
@ -0,0 +1,390 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# PIL raster font management
|
||||
#
|
||||
# History:
|
||||
# 1996-08-07 fl created (experimental)
|
||||
# 1997-08-25 fl minor adjustments to handle fonts from pilfont 0.3
|
||||
# 1999-02-06 fl rewrote most font management stuff in C
|
||||
# 1999-03-17 fl take pth files into account in load_path (from Richard Jones)
|
||||
# 2001-02-17 fl added freetype support
|
||||
# 2001-05-09 fl added TransposedFont wrapper class
|
||||
# 2002-03-04 fl make sure we have a "L" or "1" font
|
||||
# 2002-12-04 fl skip non-directory entries in the system path
|
||||
# 2003-04-29 fl add embedded default font
|
||||
# 2003-09-27 fl added support for truetype charmap encodings
|
||||
#
|
||||
# Todo:
|
||||
# Adapt to PILFONT2 format (16-bit fonts, compressed, single file)
|
||||
#
|
||||
# Copyright (c) 1997-2003 by Secret Labs AB
|
||||
# Copyright (c) 1996-2003 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
import os, string, sys
|
||||
|
||||
class _imagingft_not_installed:
|
||||
# module placeholder
|
||||
def __getattr__(self, id):
|
||||
raise ImportError("The _imagingft C module is not installed")
|
||||
|
||||
try:
|
||||
import _imagingft
|
||||
core = _imagingft
|
||||
del _imagingft
|
||||
except ImportError:
|
||||
core = _imagingft_not_installed()
|
||||
|
||||
# FIXME: add support for pilfont2 format (see FontFile.py)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Font metrics format:
|
||||
# "PILfont" LF
|
||||
# fontdescriptor LF
|
||||
# (optional) key=value... LF
|
||||
# "DATA" LF
|
||||
# binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox)
|
||||
#
|
||||
# To place a character, cut out srcbox and paste at dstbox,
|
||||
# relative to the character position. Then move the character
|
||||
# position according to dx, dy.
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
##
|
||||
# The <b>ImageFont</b> module defines a class with the same name.
|
||||
# Instances of this class store bitmap fonts, and are used with the
|
||||
# <b>text</b> method of the <b>ImageDraw</b> class.
|
||||
# <p>
|
||||
# PIL uses it's own font file format to store bitmap fonts. You can
|
||||
# use the <b>pilfont</b> utility to convert BDF and PCF font
|
||||
# descriptors (X window font formats) to this format.
|
||||
# <p>
|
||||
# Starting with version 1.1.4, PIL can be configured to support
|
||||
# TrueType and OpenType fonts. For earlier version, TrueType
|
||||
# support is only available as part of the imToolkit package
|
||||
#
|
||||
# @see ImageDraw#ImageDraw.text
|
||||
# @see pilfont
|
||||
|
||||
class ImageFont:
|
||||
"PIL font wrapper"
|
||||
|
||||
def _load_pilfont(self, filename):
|
||||
|
||||
file = open(filename, "rb")
|
||||
|
||||
for ext in (".png", ".gif", ".pbm"):
|
||||
try:
|
||||
fullname = os.path.splitext(filename)[0] + ext
|
||||
image = Image.open(fullname)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
if image and image.mode in ("1", "L"):
|
||||
break
|
||||
else:
|
||||
raise IOError("cannot find glyph data file")
|
||||
|
||||
self.file = fullname
|
||||
|
||||
return self._load_pilfont_data(file, image)
|
||||
|
||||
def _load_pilfont_data(self, file, image):
|
||||
|
||||
# read PILfont header
|
||||
if file.readline() != "PILfont\n":
|
||||
raise SyntaxError("Not a PILfont file")
|
||||
d = string.split(file.readline(), ";")
|
||||
self.info = [] # FIXME: should be a dictionary
|
||||
while True:
|
||||
s = file.readline()
|
||||
if not s or s == "DATA\n":
|
||||
break
|
||||
self.info.append(s)
|
||||
|
||||
# read PILfont metrics
|
||||
data = file.read(256*20)
|
||||
|
||||
# check image
|
||||
if image.mode not in ("1", "L"):
|
||||
raise TypeError("invalid font image mode")
|
||||
|
||||
image.load()
|
||||
|
||||
self.font = Image.core.font(image.im, data)
|
||||
|
||||
# delegate critical operations to internal type
|
||||
self.getsize = self.font.getsize
|
||||
self.getmask = self.font.getmask
|
||||
|
||||
##
|
||||
# Wrapper for FreeType fonts. Application code should use the
|
||||
# <b>truetype</b> factory function to create font objects.
|
||||
|
||||
class FreeTypeFont:
|
||||
"FreeType font wrapper (requires _imagingft service)"
|
||||
|
||||
def __init__(self, file, size, index=0, encoding=""):
|
||||
# FIXME: use service provider instead
|
||||
self.font = core.getfont(file, size, index, encoding)
|
||||
|
||||
def getname(self):
|
||||
return self.font.family, self.font.style
|
||||
|
||||
def getmetrics(self):
|
||||
return self.font.ascent, self.font.descent
|
||||
|
||||
def getsize(self, text):
|
||||
return self.font.getsize(text)[0]
|
||||
|
||||
def getmask(self, text, mode=""):
|
||||
return self.getmask2(text, mode)[0]
|
||||
|
||||
def getmask2(self, text, mode="", fill=Image.core.fill):
|
||||
size, offset = self.font.getsize(text)
|
||||
im = fill("L", size, 0)
|
||||
self.font.render(text, im.id, mode=="1")
|
||||
return im, offset
|
||||
|
||||
##
|
||||
# Wrapper that creates a transposed font from any existing font
|
||||
# object.
|
||||
#
|
||||
# @param font A font object.
|
||||
# @param orientation An optional orientation. If given, this should
|
||||
# be one of Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM,
|
||||
# Image.ROTATE_90, Image.ROTATE_180, or Image.ROTATE_270.
|
||||
|
||||
class TransposedFont:
|
||||
"Wrapper for writing rotated or mirrored text"
|
||||
|
||||
def __init__(self, font, orientation=None):
|
||||
self.font = font
|
||||
self.orientation = orientation # any 'transpose' argument, or None
|
||||
|
||||
def getsize(self, text):
|
||||
w, h = self.font.getsize(text)
|
||||
if self.orientation in (Image.ROTATE_90, Image.ROTATE_270):
|
||||
return h, w
|
||||
return w, h
|
||||
|
||||
def getmask(self, text, mode=""):
|
||||
im = self.font.getmask(text, mode)
|
||||
if self.orientation is not None:
|
||||
return im.transpose(self.orientation)
|
||||
return im
|
||||
|
||||
##
|
||||
# Load font file. This function loads a font object from the given
|
||||
# bitmap font file, and returns the corresponding font object.
|
||||
#
|
||||
# @param filename Name of font file.
|
||||
# @return A font object.
|
||||
# @exception IOError If the file could not be read.
|
||||
|
||||
def load(filename):
|
||||
"Load a font file."
|
||||
f = ImageFont()
|
||||
f._load_pilfont(filename)
|
||||
return f
|
||||
|
||||
##
|
||||
# Load a TrueType or OpenType font file, and create a font object.
|
||||
# This function loads a font object from the given file, and creates
|
||||
# a font object for a font of the given size.
|
||||
# <p>
|
||||
# This function requires the _imagingft service.
|
||||
#
|
||||
# @param filename A truetype font file. Under Windows, if the file
|
||||
# is not found in this filename, the loader also looks in Windows
|
||||
# <b>fonts</b> directory
|
||||
# @param size The requested size, in points.
|
||||
# @param index Which font face to load (default is first available face).
|
||||
# @param encoding Which font encoding to use (default is Unicode). Common
|
||||
# encodings are "unic" (Unicode), "symb" (Microsoft Symbol), "ADOB"
|
||||
# (Adobe Standard), "ADBE" (Adobe Expert), and "armn" (Apple Roman).
|
||||
# See the FreeType documentation for more information.
|
||||
# @return A font object.
|
||||
# @exception IOError If the file could not be read.
|
||||
|
||||
def truetype(filename, size, index=0, encoding=""):
|
||||
"Load a truetype font file."
|
||||
try:
|
||||
return FreeTypeFont(filename, size, index, encoding)
|
||||
except IOError:
|
||||
if sys.platform == "win32":
|
||||
# check the windows font repository
|
||||
# NOTE: must use uppercase WINDIR, to work around bugs in
|
||||
# 1.5.2's os.environ.get()
|
||||
windir = os.environ.get("WINDIR")
|
||||
if windir:
|
||||
filename = os.path.join(windir, "fonts", filename)
|
||||
return FreeTypeFont(filename, size, index, encoding)
|
||||
raise
|
||||
|
||||
##
|
||||
# Load font file. Same as load, but searches for a bitmap font along
|
||||
# the Python path.
|
||||
#
|
||||
# @param filename Name of font file.
|
||||
# @return A font object.
|
||||
# @exception IOError If the file could not be read.
|
||||
# @see #load
|
||||
|
||||
def load_path(filename):
|
||||
"Load a font file, searching along the Python path."
|
||||
for dir in sys.path:
|
||||
if Image.isDirectory(dir):
|
||||
try:
|
||||
return load(os.path.join(dir, filename))
|
||||
except IOError:
|
||||
pass
|
||||
raise IOError("cannot find font file")
|
||||
|
||||
##
|
||||
# Load a (probably rather ugly) default font.
|
||||
#
|
||||
# @return A font object.
|
||||
|
||||
def load_default():
|
||||
"Load a default font."
|
||||
from StringIO import StringIO
|
||||
import base64
|
||||
f = ImageFont()
|
||||
f._load_pilfont_data(
|
||||
# courB08
|
||||
StringIO(base64.decodestring('''
|
||||
UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA
|
||||
BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL
|
||||
AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA
|
||||
AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB
|
||||
ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A
|
||||
BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB
|
||||
//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA
|
||||
AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH
|
||||
AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA
|
||||
ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv
|
||||
AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/
|
||||
/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5
|
||||
AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA
|
||||
AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG
|
||||
AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA
|
||||
BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA
|
||||
AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA
|
||||
2AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF
|
||||
AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA////
|
||||
+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA
|
||||
////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA
|
||||
BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv
|
||||
AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA
|
||||
AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA
|
||||
AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA
|
||||
BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP//
|
||||
//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA
|
||||
AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF
|
||||
AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB
|
||||
mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn
|
||||
AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA
|
||||
AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7
|
||||
AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA
|
||||
Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB
|
||||
//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA
|
||||
AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ
|
||||
AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC
|
||||
DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ
|
||||
AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/
|
||||
+wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5
|
||||
AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/
|
||||
///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG
|
||||
AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA
|
||||
BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA
|
||||
Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC
|
||||
eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG
|
||||
AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA////
|
||||
+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA
|
||||
////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA
|
||||
BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT
|
||||
AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A
|
||||
AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA
|
||||
Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA
|
||||
Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP//
|
||||
//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA
|
||||
AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ
|
||||
AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA
|
||||
LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5
|
||||
AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA
|
||||
AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5
|
||||
AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA
|
||||
AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG
|
||||
AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA
|
||||
EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK
|
||||
AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA
|
||||
pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG
|
||||
AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA////
|
||||
+QAGAAIAzgAKANUAEw==
|
||||
''')), Image.open(StringIO(base64.decodestring('''
|
||||
iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u
|
||||
Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9
|
||||
M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g
|
||||
LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F
|
||||
IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA
|
||||
Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791
|
||||
NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx
|
||||
in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9
|
||||
SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY
|
||||
AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt
|
||||
y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG
|
||||
ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY
|
||||
lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H
|
||||
/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3
|
||||
AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47
|
||||
c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/
|
||||
/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw
|
||||
pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv
|
||||
oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR
|
||||
evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA
|
||||
AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v//
|
||||
Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR
|
||||
w7IkEbzhVQAAAABJRU5ErkJggg==
|
||||
'''))))
|
||||
return f
|
||||
|
||||
if __name__ == "__main__":
|
||||
# create font data chunk for embedding
|
||||
import base64, os, sys
|
||||
font = "../Images/courB08"
|
||||
print " f._load_pilfont_data("
|
||||
print " # %s" % os.path.basename(font)
|
||||
print " StringIO(base64.decodestring('''"
|
||||
base64.encode(open(font + ".pil", "rb"), sys.stdout)
|
||||
print "''')), Image.open(StringIO(base64.decodestring('''"
|
||||
base64.encode(open(font + ".pbm", "rb"), sys.stdout)
|
||||
print "'''))))"
|
||||
28
Darwin/lib/python2.7/site-packages/PIL/ImageGL.py
Normal file
28
Darwin/lib/python2.7/site-packages/PIL/ImageGL.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# OpenGL pixmap/texture interface (requires imToolkit OpenGL extensions)
|
||||
#
|
||||
# History:
|
||||
# 2003-09-13 fl Added
|
||||
#
|
||||
# Copyright (c) Secret Labs AB 2003.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
##
|
||||
# OpenGL pixmap/texture interface (requires imToolkit OpenGL
|
||||
# extensions.)
|
||||
##
|
||||
|
||||
import _imaginggl
|
||||
|
||||
##
|
||||
# Texture factory.
|
||||
|
||||
class TextureFactory:
|
||||
pass # overwritten by the _imaginggl module
|
||||
|
||||
from _imaginggl import *
|
||||
71
Darwin/lib/python2.7/site-packages/PIL/ImageGrab.py
Normal file
71
Darwin/lib/python2.7/site-packages/PIL/ImageGrab.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# screen grabber (windows only)
|
||||
#
|
||||
# History:
|
||||
# 2001-04-26 fl created
|
||||
# 2001-09-17 fl use builtin driver, if present
|
||||
# 2002-11-19 fl added grabclipboard support
|
||||
#
|
||||
# Copyright (c) 2001-2002 by Secret Labs AB
|
||||
# Copyright (c) 2001-2002 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
|
||||
##
|
||||
# (New in 1.1.3) The <b>ImageGrab</b> module can be used to copy
|
||||
# the contents of the screen to a PIL image memory.
|
||||
# <p>
|
||||
# The current version works on Windows only.</p>
|
||||
#
|
||||
# @since 1.1.3
|
||||
##
|
||||
|
||||
try:
|
||||
# built-in driver (1.1.3 and later)
|
||||
grabber = Image.core.grabscreen
|
||||
except AttributeError:
|
||||
# stand-alone driver (pil plus)
|
||||
import _grabscreen
|
||||
grabber = _grabscreen.grab
|
||||
|
||||
##
|
||||
# (New in 1.1.3) Take a snapshot of the screen. The pixels inside the
|
||||
# bounding box are returned as an "RGB" image. If the bounding box is
|
||||
# omitted, the entire screen is copied.
|
||||
#
|
||||
# @param bbox What region to copy. Default is the entire screen.
|
||||
# @return An image
|
||||
# @since 1.1.3
|
||||
|
||||
def grab(bbox=None):
|
||||
size, data = grabber()
|
||||
im = Image.fromstring(
|
||||
"RGB", size, data,
|
||||
# RGB, 32-bit line padding, origo in lower left corner
|
||||
"raw", "BGR", (size[0]*3 + 3) & -4, -1
|
||||
)
|
||||
if bbox:
|
||||
im = im.crop(bbox)
|
||||
return im
|
||||
|
||||
##
|
||||
# (New in 1.1.4) Take a snapshot of the clipboard image, if any.
|
||||
#
|
||||
# @return An image, a list of filenames, or None if the clipboard does
|
||||
# not contain image data or filenames. Note that if a list is
|
||||
# returned, the filenames may not represent image files.
|
||||
# @since 1.1.4
|
||||
|
||||
def grabclipboard():
|
||||
debug = 0 # temporary interface
|
||||
data = Image.core.grabclipboard(debug)
|
||||
if Image.isStringType(data):
|
||||
import BmpImagePlugin, StringIO
|
||||
return BmpImagePlugin.DibImageFile(StringIO.StringIO(data))
|
||||
return data
|
||||
207
Darwin/lib/python2.7/site-packages/PIL/ImageMath.py
Normal file
207
Darwin/lib/python2.7/site-packages/PIL/ImageMath.py
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# a simple math add-on for the Python Imaging Library
|
||||
#
|
||||
# History:
|
||||
# 1999-02-15 fl Original PIL Plus release
|
||||
# 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6
|
||||
# 2005-09-12 fl Fixed int() and float() for Python 2.4.1
|
||||
#
|
||||
# Copyright (c) 1999-2005 by Secret Labs AB
|
||||
# Copyright (c) 2005 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
import _imagingmath
|
||||
|
||||
VERBOSE = 0
|
||||
|
||||
def _isconstant(v):
|
||||
return isinstance(v, type(0)) or isinstance(v, type(0.0))
|
||||
|
||||
class _Operand:
|
||||
# wraps an image operand, providing standard operators
|
||||
|
||||
def __init__(self, im):
|
||||
self.im = im
|
||||
|
||||
def __fixup(self, im1):
|
||||
# convert image to suitable mode
|
||||
if isinstance(im1, _Operand):
|
||||
# argument was an image.
|
||||
if im1.im.mode in ("1", "L"):
|
||||
return im1.im.convert("I")
|
||||
elif im1.im.mode in ("I", "F"):
|
||||
return im1.im
|
||||
else:
|
||||
raise ValueError, "unsupported mode: %s" % im1.im.mode
|
||||
else:
|
||||
# argument was a constant
|
||||
if _isconstant(im1) and self.im.mode in ("1", "L", "I"):
|
||||
return Image.new("I", self.im.size, im1)
|
||||
else:
|
||||
return Image.new("F", self.im.size, im1)
|
||||
|
||||
def apply(self, op, im1, im2=None, mode=None):
|
||||
im1 = self.__fixup(im1)
|
||||
if im2 is None:
|
||||
# unary operation
|
||||
out = Image.new(mode or im1.mode, im1.size, None)
|
||||
im1.load()
|
||||
try:
|
||||
op = getattr(_imagingmath, op+"_"+im1.mode)
|
||||
except AttributeError:
|
||||
raise TypeError, "bad operand type for '%s'" % op
|
||||
_imagingmath.unop(op, out.im.id, im1.im.id)
|
||||
else:
|
||||
# binary operation
|
||||
im2 = self.__fixup(im2)
|
||||
if im1.mode != im2.mode:
|
||||
# convert both arguments to floating point
|
||||
if im1.mode != "F": im1 = im1.convert("F")
|
||||
if im2.mode != "F": im2 = im2.convert("F")
|
||||
if im1.mode != im2.mode:
|
||||
raise ValueError, "mode mismatch"
|
||||
if im1.size != im2.size:
|
||||
# crop both arguments to a common size
|
||||
size = (min(im1.size[0], im2.size[0]),
|
||||
min(im1.size[1], im2.size[1]))
|
||||
if im1.size != size: im1 = im1.crop((0, 0) + size)
|
||||
if im2.size != size: im2 = im2.crop((0, 0) + size)
|
||||
out = Image.new(mode or im1.mode, size, None)
|
||||
else:
|
||||
out = Image.new(mode or im1.mode, im1.size, None)
|
||||
im1.load(); im2.load()
|
||||
try:
|
||||
op = getattr(_imagingmath, op+"_"+im1.mode)
|
||||
except AttributeError:
|
||||
raise TypeError, "bad operand type for '%s'" % op
|
||||
_imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id)
|
||||
return _Operand(out)
|
||||
|
||||
# unary operators
|
||||
def __nonzero__(self):
|
||||
# an image is "true" if it contains at least one non-zero pixel
|
||||
return self.im.getbbox() is not None
|
||||
def __abs__(self):
|
||||
return self.apply("abs", self)
|
||||
def __pos__(self):
|
||||
return self
|
||||
def __neg__(self):
|
||||
return self.apply("neg", self)
|
||||
|
||||
# binary operators
|
||||
def __add__(self, other):
|
||||
return self.apply("add", self, other)
|
||||
def __radd__(self, other):
|
||||
return self.apply("add", other, self)
|
||||
def __sub__(self, other):
|
||||
return self.apply("sub", self, other)
|
||||
def __rsub__(self, other):
|
||||
return self.apply("sub", other, self)
|
||||
def __mul__(self, other):
|
||||
return self.apply("mul", self, other)
|
||||
def __rmul__(self, other):
|
||||
return self.apply("mul", other, self)
|
||||
def __div__(self, other):
|
||||
return self.apply("div", self, other)
|
||||
def __rdiv__(self, other):
|
||||
return self.apply("div", other, self)
|
||||
def __mod__(self, other):
|
||||
return self.apply("mod", self, other)
|
||||
def __rmod__(self, other):
|
||||
return self.apply("mod", other, self)
|
||||
def __pow__(self, other):
|
||||
return self.apply("pow", self, other)
|
||||
def __rpow__(self, other):
|
||||
return self.apply("pow", other, self)
|
||||
|
||||
# bitwise
|
||||
def __invert__(self):
|
||||
return self.apply("invert", self)
|
||||
def __and__(self, other):
|
||||
return self.apply("and", self, other)
|
||||
def __rand__(self, other):
|
||||
return self.apply("and", other, self)
|
||||
def __or__(self, other):
|
||||
return self.apply("or", self, other)
|
||||
def __ror__(self, other):
|
||||
return self.apply("or", other, self)
|
||||
def __xor__(self, other):
|
||||
return self.apply("xor", self, other)
|
||||
def __rxor__(self, other):
|
||||
return self.apply("xor", other, self)
|
||||
def __lshift__(self, other):
|
||||
return self.apply("lshift", self, other)
|
||||
def __rshift__(self, other):
|
||||
return self.apply("rshift", self, other)
|
||||
|
||||
# logical
|
||||
def __eq__(self, other):
|
||||
return self.apply("eq", self, other)
|
||||
def __ne__(self, other):
|
||||
return self.apply("ne", self, other)
|
||||
def __lt__(self, other):
|
||||
return self.apply("lt", self, other)
|
||||
def __le__(self, other):
|
||||
return self.apply("le", self, other)
|
||||
def __gt__(self, other):
|
||||
return self.apply("gt", self, other)
|
||||
def __ge__(self, other):
|
||||
return self.apply("ge", self, other)
|
||||
|
||||
# conversions
|
||||
def imagemath_int(self):
|
||||
return _Operand(self.im.convert("I"))
|
||||
def imagemath_float(self):
|
||||
return _Operand(self.im.convert("F"))
|
||||
|
||||
# logical
|
||||
def imagemath_equal(self, other):
|
||||
return self.apply("eq", self, other, mode="I")
|
||||
def imagemath_notequal(self, other):
|
||||
return self.apply("ne", self, other, mode="I")
|
||||
|
||||
def imagemath_min(self, other):
|
||||
return self.apply("min", self, other)
|
||||
def imagemath_max(self, other):
|
||||
return self.apply("max", self, other)
|
||||
|
||||
def imagemath_convert(self, mode):
|
||||
return _Operand(self.im.convert(mode))
|
||||
|
||||
ops = {}
|
||||
for k, v in globals().items():
|
||||
if k[:10] == "imagemath_":
|
||||
ops[k[10:]] = v
|
||||
|
||||
##
|
||||
# Evaluates an image expression.
|
||||
#
|
||||
# @param expression A string containing a Python-style expression.
|
||||
# @keyparam options Values to add to the evaluation context. You
|
||||
# can either use a dictionary, or one or more keyword arguments.
|
||||
# @return The evaluated expression. This is usually an image object,
|
||||
# but can also be an integer, a floating point value, or a pixel
|
||||
# tuple, depending on the expression.
|
||||
|
||||
def eval(expression, _dict={}, **kw):
|
||||
|
||||
# build execution namespace
|
||||
args = ops.copy()
|
||||
args.update(_dict)
|
||||
args.update(kw)
|
||||
for k, v in args.items():
|
||||
if hasattr(v, "im"):
|
||||
args[k] = _Operand(v)
|
||||
|
||||
import __builtin__
|
||||
out =__builtin__.eval(expression, args)
|
||||
try:
|
||||
return out.im
|
||||
except AttributeError:
|
||||
return out
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue