Skip to content

Commit 70b4b73

Browse files
committed
✨ Rework of Pillow recipe adding WebP support
We add `optional` support for [WebP](https://developers.google.com/speed/webp) images, but to enable it, you must add `libwebp` to your build requirements. We also: - 🎨 sort imports - 📝 add docstrings to Pillow recipe - 🎨 move to python3's f-strings...to increase readability - 💡 add inline comments
1 parent 392d57f commit 70b4b73

File tree

2 files changed

+70
-55
lines changed

2 files changed

+70
-55
lines changed

pythonforandroid/recipes/Pillow/__init__.py

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,33 @@
1-
from pythonforandroid.recipe import CompiledComponentsPythonRecipe
21
from os.path import join
32

3+
from pythonforandroid.recipe import CompiledComponentsPythonRecipe
4+
45

56
class PillowRecipe(CompiledComponentsPythonRecipe):
7+
"""
8+
A recipe for Pillow (previously known as Pil).
9+
10+
This recipe allow us to build the Pillow recipe with support for different
11+
types of images and fonts. But you should be aware, that in order to use
12+
some of the features of Pillow, we must build some libraries. By default
13+
we automatically trigger the build of below libraries::
14+
15+
- freetype: rendering fonts support.
16+
- harfbuzz: a text shaping library.
17+
- jpeg: reading and writing JPEG image files.
18+
- png: support for PNG images.
19+
20+
But you also could enable the build of some extra image types by requesting
21+
the build of some libraries via argument `requirements`::
22+
23+
- libwebp: library to encode and decode images in WebP format.
24+
"""
625

726
version = '7.0.0'
827
url = 'https://github.com/python-pillow/Pillow/archive/{version}.tar.gz'
928
site_packages_name = 'Pillow'
1029
depends = ['png', 'jpeg', 'freetype', 'setuptools']
30+
opt_depends = ['libwebp']
1131
patches = [join('patches', 'fix-setup.patch')]
1232

1333
call_hostpython_via_targetpython = False
@@ -36,20 +56,40 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True):
3656
harf_lib_dir = join(harfbuzz.get_build_dir(arch.arch), 'src', '.libs')
3757
harf_inc_dir = harfbuzz.get_build_dir(arch.arch)
3858

39-
env['JPEG_ROOT'] = '{}|{}'.format(jpeg_lib_dir, jpeg_inc_dir)
40-
env['FREETYPE_ROOT'] = '{}|{}'.format(free_lib_dir, free_inc_dir)
41-
env['ZLIB_ROOT'] = '{}|{}'.format(ndk_lib_dir, ndk_include_dir)
42-
43-
cflags = ' -I{}'.format(png_inc_dir)
44-
cflags += ' -I{} -I{}'.format(harf_inc_dir, join(harf_inc_dir, 'src'))
45-
cflags += ' -I{}'.format(free_inc_dir)
46-
cflags += ' -I{}'.format(jpeg_inc_dir)
47-
cflags += ' -I{}'.format(ndk_include_dir)
48-
59+
# these below env variables are defined at Pillow's `setup.py`
60+
env['JPEG_ROOT'] = f'{jpeg_lib_dir}|{jpeg_inc_dir}'
61+
env['FREETYPE_ROOT'] = f'{free_lib_dir}|{free_inc_dir}'
62+
env['ZLIB_ROOT'] = f'{ndk_lib_dir}|{ndk_include_dir}'
63+
64+
# libwebp is an optional dependency, so we add the
65+
# flags if we have it in our `ctx.recipe_build_order`
66+
build_with_webp_support = 'libwebp' in self.ctx.recipe_build_order
67+
if build_with_webp_support:
68+
webp = self.get_recipe('libwebp', self.ctx)
69+
webp_install = join(
70+
webp.get_build_dir(arch.arch), 'installation'
71+
)
72+
73+
# Add libraries includes to CFLAGS
74+
cflags = f' -I{png_inc_dir}'
75+
cflags += f' -I{harf_inc_dir} -I{join(harf_inc_dir, "src")}'
76+
cflags += f' -I{free_inc_dir}'
77+
cflags += f' -I{jpeg_inc_dir}'
78+
if build_with_webp_support:
79+
cflags += f' -I{join(webp_install, "include")}'
80+
cflags += f' -I{ndk_include_dir}'
81+
82+
# Link the basic Pillow libraries...no need to add webp's libraries
83+
# since it seems that the linkage is properly made without it :)
4984
env['LIBS'] = ' -lpng -lfreetype -lharfbuzz -ljpeg -lturbojpeg'
5085

51-
env['LDFLAGS'] += ' -L{} -L{} -L{} -L{}'.format(
52-
png_lib_dir, harf_lib_dir, jpeg_lib_dir, ndk_lib_dir)
86+
# Add libraries locations to LDFLAGS
87+
env['LDFLAGS'] += f' -L{png_lib_dir}'
88+
env['LDFLAGS'] += f' -L{harf_lib_dir}'
89+
env['LDFLAGS'] += f' -L{jpeg_lib_dir}'
90+
if build_with_webp_support:
91+
env['LDFLAGS'] += f' -L{join(webp_install, "lib")}'
92+
env['LDFLAGS'] += f' -L{ndk_lib_dir}'
5393
if cflags not in env['CFLAGS']:
5494
env['CFLAGS'] += cflags
5595
return env

pythonforandroid/recipes/Pillow/patches/fix-setup.patch

Lines changed: 17 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--- Pillow-7.0.0/setup.py.orig 2020-01-02 06:19:26.000000000 +0100
2-
+++ Pillow-7.0.0/setup.py 2020-02-22 17:33:03.121976748 +0100
2+
+++ Pillow-7.0.0/setup.py 2020-07-05 12:26:18.882948858 +0200
33
@@ -29,13 +29,13 @@ def get_version():
4-
4+
55
NAME = "Pillow"
66
PILLOW_VERSION = get_version()
77
-FREETYPE_ROOT = None
@@ -14,12 +14,12 @@
1414
TIFF_ROOT = None
1515
-ZLIB_ROOT = None
1616
+ZLIB_ROOT = tuple(os.environ['ZLIB_ROOT'].split('|')) if 'ZLIB_ROOT' in os.environ else None
17-
18-
17+
18+
1919
if sys.platform == "win32" and sys.version_info >= (3, 9):
2020
@@ -317,7 +317,7 @@ class pil_build_ext(build_ext):
2121
)
22-
22+
2323
def initialize_options(self):
2424
- self.disable_platform_guessing = None
2525
+ self.disable_platform_guessing = True
@@ -28,7 +28,7 @@
2828
for x in self.feature:
2929
@@ -567,62 +567,6 @@ class pil_build_ext(build_ext):
3030
feature.jpeg = "libjpeg" # alternative name
31-
31+
3232
feature.openjpeg_version = None
3333
- if feature.want("jpeg2000"):
3434
- _dbg("Looking for jpeg2000")
@@ -86,13 +86,13 @@
8686
- self, "libtiff"
8787
- ):
8888
- feature.tiff = "libtiff"
89-
89+
9090
if feature.want("freetype"):
9191
_dbg("Looking for freetype")
92-
@@ -647,40 +591,6 @@ class pil_build_ext(build_ext):
92+
@@ -647,15 +591,6 @@ class pil_build_ext(build_ext):
9393
if subdir:
9494
_add_directory(self.compiler.include_dirs, subdir, 0)
95-
95+
9696
- if feature.want("lcms"):
9797
- _dbg("Looking for lcms")
9898
- if _find_include_file(self, "lcms2.h"):
@@ -102,49 +102,24 @@
102102
- # alternate Windows name.
103103
- feature.lcms = "lcms2_static"
104104
-
105-
- if feature.want("webp"):
106-
- _dbg("Looking for webp")
107-
- if _find_include_file(self, "webp/encode.h") and _find_include_file(
108-
- self, "webp/decode.h"
109-
- ):
110-
- # In Google's precompiled zip it is call "libwebp":
111-
- if _find_library_file(self, "webp"):
112-
- feature.webp = "webp"
113-
- elif _find_library_file(self, "libwebp"):
114-
- feature.webp = "libwebp"
115-
-
116-
- if feature.want("webpmux"):
117-
- _dbg("Looking for webpmux")
118-
- if _find_include_file(self, "webp/mux.h") and _find_include_file(
119-
- self, "webp/demux.h"
120-
- ):
121-
- if _find_library_file(self, "webpmux") and _find_library_file(
122-
- self, "webpdemux"
123-
- ):
124-
- feature.webpmux = "webpmux"
125-
- if _find_library_file(self, "libwebpmux") and _find_library_file(
126-
- self, "libwebpdemux"
127-
- ):
128-
- feature.webpmux = "libwebpmux"
129-
-
130-
for f in feature:
131-
if not getattr(feature, f) and feature.require(f):
132-
if f in ("jpeg", "zlib"):
133-
@@ -717,8 +627,8 @@ class pil_build_ext(build_ext):
105+
if feature.want("webp"):
106+
_dbg("Looking for webp")
107+
if _find_include_file(self, "webp/encode.h") and _find_include_file(
108+
@@ -717,8 +652,8 @@ class pil_build_ext(build_ext):
134109
defs.append(("HAVE_LIBTIFF", None))
135110
if sys.platform == "win32":
136111
libs.extend(["kernel32", "user32", "gdi32"])
137112
- if struct.unpack("h", b"\0\1")[0] == 1:
138113
- defs.append(("WORDS_BIGENDIAN", None))
139114
+ # if struct.unpack("h", b"\0\1")[0] == 1:
140115
+ # defs.append(("WORDS_BIGENDIAN", None))
141-
116+
142117
if sys.platform == "win32" and not (PLATFORM_PYPY or PLATFORM_MINGW):
143118
defs.append(("PILLOW_VERSION", '"\\"%s\\""' % PILLOW_VERSION))
144-
@@ -769,16 +679,6 @@ class pil_build_ext(build_ext):
119+
@@ -769,16 +704,6 @@ class pil_build_ext(build_ext):
145120
)
146121
)
147-
122+
148123
- tk_libs = ["psapi"] if sys.platform == "win32" else []
149124
- exts.append(
150125
- Extension(
@@ -157,4 +132,4 @@
157132
-
158133
exts.append(Extension("PIL._imagingmath", ["src/_imagingmath.c"]))
159134
exts.append(Extension("PIL._imagingmorph", ["src/_imagingmorph.c"]))
160-
135+

0 commit comments

Comments
 (0)