Skip to content

Commit

Permalink
Merge pull request #2256 from opacam/feature-pillow-with-webp-support
Browse files Browse the repository at this point in the history
✨ Rework of Pillow recipe adding WebP support
  • Loading branch information
AndreMiras committed Aug 22, 2020
2 parents e84b951 + 70b4b73 commit e288a94
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 55 deletions.
66 changes: 53 additions & 13 deletions pythonforandroid/recipes/Pillow/__init__.py
@@ -1,13 +1,33 @@
from pythonforandroid.recipe import CompiledComponentsPythonRecipe
from os.path import join

from pythonforandroid.recipe import CompiledComponentsPythonRecipe


class PillowRecipe(CompiledComponentsPythonRecipe):
"""
A recipe for Pillow (previously known as Pil).
This recipe allow us to build the Pillow recipe with support for different
types of images and fonts. But you should be aware, that in order to use
some of the features of Pillow, we must build some libraries. By default
we automatically trigger the build of below libraries::
- freetype: rendering fonts support.
- harfbuzz: a text shaping library.
- jpeg: reading and writing JPEG image files.
- png: support for PNG images.
But you also could enable the build of some extra image types by requesting
the build of some libraries via argument `requirements`::
- libwebp: library to encode and decode images in WebP format.
"""

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

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

env['JPEG_ROOT'] = '{}|{}'.format(jpeg_lib_dir, jpeg_inc_dir)
env['FREETYPE_ROOT'] = '{}|{}'.format(free_lib_dir, free_inc_dir)
env['ZLIB_ROOT'] = '{}|{}'.format(ndk_lib_dir, ndk_include_dir)

cflags = ' -I{}'.format(png_inc_dir)
cflags += ' -I{} -I{}'.format(harf_inc_dir, join(harf_inc_dir, 'src'))
cflags += ' -I{}'.format(free_inc_dir)
cflags += ' -I{}'.format(jpeg_inc_dir)
cflags += ' -I{}'.format(ndk_include_dir)

# these below env variables are defined at Pillow's `setup.py`
env['JPEG_ROOT'] = f'{jpeg_lib_dir}|{jpeg_inc_dir}'
env['FREETYPE_ROOT'] = f'{free_lib_dir}|{free_inc_dir}'
env['ZLIB_ROOT'] = f'{ndk_lib_dir}|{ndk_include_dir}'

# libwebp is an optional dependency, so we add the
# flags if we have it in our `ctx.recipe_build_order`
build_with_webp_support = 'libwebp' in self.ctx.recipe_build_order
if build_with_webp_support:
webp = self.get_recipe('libwebp', self.ctx)
webp_install = join(
webp.get_build_dir(arch.arch), 'installation'
)

# Add libraries includes to CFLAGS
cflags = f' -I{png_inc_dir}'
cflags += f' -I{harf_inc_dir} -I{join(harf_inc_dir, "src")}'
cflags += f' -I{free_inc_dir}'
cflags += f' -I{jpeg_inc_dir}'
if build_with_webp_support:
cflags += f' -I{join(webp_install, "include")}'
cflags += f' -I{ndk_include_dir}'

# Link the basic Pillow libraries...no need to add webp's libraries
# since it seems that the linkage is properly made without it :)
env['LIBS'] = ' -lpng -lfreetype -lharfbuzz -ljpeg -lturbojpeg'

env['LDFLAGS'] += ' -L{} -L{} -L{} -L{}'.format(
png_lib_dir, harf_lib_dir, jpeg_lib_dir, ndk_lib_dir)
# Add libraries locations to LDFLAGS
env['LDFLAGS'] += f' -L{png_lib_dir}'
env['LDFLAGS'] += f' -L{harf_lib_dir}'
env['LDFLAGS'] += f' -L{jpeg_lib_dir}'
if build_with_webp_support:
env['LDFLAGS'] += f' -L{join(webp_install, "lib")}'
env['LDFLAGS'] += f' -L{ndk_lib_dir}'
if cflags not in env['CFLAGS']:
env['CFLAGS'] += cflags
return env
Expand Down
59 changes: 17 additions & 42 deletions pythonforandroid/recipes/Pillow/patches/fix-setup.patch
@@ -1,7 +1,7 @@
--- Pillow-7.0.0/setup.py.orig 2020-01-02 06:19:26.000000000 +0100
+++ Pillow-7.0.0/setup.py 2020-02-22 17:33:03.121976748 +0100
+++ Pillow-7.0.0/setup.py 2020-07-05 12:26:18.882948858 +0200
@@ -29,13 +29,13 @@ def get_version():

NAME = "Pillow"
PILLOW_VERSION = get_version()
-FREETYPE_ROOT = None
Expand All @@ -14,12 +14,12 @@
TIFF_ROOT = None
-ZLIB_ROOT = None
+ZLIB_ROOT = tuple(os.environ['ZLIB_ROOT'].split('|')) if 'ZLIB_ROOT' in os.environ else None


if sys.platform == "win32" and sys.version_info >= (3, 9):
@@ -317,7 +317,7 @@ class pil_build_ext(build_ext):
)

def initialize_options(self):
- self.disable_platform_guessing = None
+ self.disable_platform_guessing = True
Expand All @@ -28,7 +28,7 @@
for x in self.feature:
@@ -567,62 +567,6 @@ class pil_build_ext(build_ext):
feature.jpeg = "libjpeg" # alternative name

feature.openjpeg_version = None
- if feature.want("jpeg2000"):
- _dbg("Looking for jpeg2000")
Expand Down Expand Up @@ -86,13 +86,13 @@
- self, "libtiff"
- ):
- feature.tiff = "libtiff"

if feature.want("freetype"):
_dbg("Looking for freetype")
@@ -647,40 +591,6 @@ class pil_build_ext(build_ext):
@@ -647,15 +591,6 @@ class pil_build_ext(build_ext):
if subdir:
_add_directory(self.compiler.include_dirs, subdir, 0)

- if feature.want("lcms"):
- _dbg("Looking for lcms")
- if _find_include_file(self, "lcms2.h"):
Expand All @@ -102,49 +102,24 @@
- # alternate Windows name.
- feature.lcms = "lcms2_static"
-
- if feature.want("webp"):
- _dbg("Looking for webp")
- if _find_include_file(self, "webp/encode.h") and _find_include_file(
- self, "webp/decode.h"
- ):
- # In Google's precompiled zip it is call "libwebp":
- if _find_library_file(self, "webp"):
- feature.webp = "webp"
- elif _find_library_file(self, "libwebp"):
- feature.webp = "libwebp"
-
- if feature.want("webpmux"):
- _dbg("Looking for webpmux")
- if _find_include_file(self, "webp/mux.h") and _find_include_file(
- self, "webp/demux.h"
- ):
- if _find_library_file(self, "webpmux") and _find_library_file(
- self, "webpdemux"
- ):
- feature.webpmux = "webpmux"
- if _find_library_file(self, "libwebpmux") and _find_library_file(
- self, "libwebpdemux"
- ):
- feature.webpmux = "libwebpmux"
-
for f in feature:
if not getattr(feature, f) and feature.require(f):
if f in ("jpeg", "zlib"):
@@ -717,8 +627,8 @@ class pil_build_ext(build_ext):
if feature.want("webp"):
_dbg("Looking for webp")
if _find_include_file(self, "webp/encode.h") and _find_include_file(
@@ -717,8 +652,8 @@ class pil_build_ext(build_ext):
defs.append(("HAVE_LIBTIFF", None))
if sys.platform == "win32":
libs.extend(["kernel32", "user32", "gdi32"])
- if struct.unpack("h", b"\0\1")[0] == 1:
- defs.append(("WORDS_BIGENDIAN", None))
+ # if struct.unpack("h", b"\0\1")[0] == 1:
+ # defs.append(("WORDS_BIGENDIAN", None))

if sys.platform == "win32" and not (PLATFORM_PYPY or PLATFORM_MINGW):
defs.append(("PILLOW_VERSION", '"\\"%s\\""' % PILLOW_VERSION))
@@ -769,16 +679,6 @@ class pil_build_ext(build_ext):
@@ -769,16 +704,6 @@ class pil_build_ext(build_ext):
)
)

- tk_libs = ["psapi"] if sys.platform == "win32" else []
- exts.append(
- Extension(
Expand All @@ -157,4 +132,4 @@
-
exts.append(Extension("PIL._imagingmath", ["src/_imagingmath.c"]))
exts.append(Extension("PIL._imagingmorph", ["src/_imagingmorph.c"]))

0 comments on commit e288a94

Please sign in to comment.