From 3b38eb317bc9f6ed409accb174d1fb52af8aea8b Mon Sep 17 00:00:00 2001 From: nulano Date: Sun, 30 Aug 2020 00:57:27 +0200 Subject: [PATCH 1/4] remove legacy include directory for libimagequant 1) it is hardcoded to 32-bit C:\msys64\mingw32 2) current library version uses \mingw64\include\libimagequant.h directly --- setup.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/setup.py b/setup.py index cf3916250..528a3a044 100755 --- a/setup.py +++ b/setup.py @@ -528,11 +528,6 @@ class pil_build_ext(build_ext): _add_directory(library_dirs, "/lib") if sys.platform == "win32": - if PLATFORM_MINGW: - _add_directory( - include_dirs, "C:\\msys64\\mingw32\\include\\libimagequant" - ) - # on Windows, look for the OpenJPEG libraries in the location that # the official installer puts them program_files = os.environ.get("ProgramFiles", "") From db6253c92733cc0360ddacc7ffacfbf5b65457c0 Mon Sep 17 00:00:00 2001 From: nulano Date: Sun, 30 Aug 2020 01:43:55 +0200 Subject: [PATCH 2/4] remove msys2 gcc workaround --- setup.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/setup.py b/setup.py index 528a3a044..ba34fbce7 100755 --- a/setup.py +++ b/setup.py @@ -133,18 +133,6 @@ class RequiredDependencyException(Exception): PLATFORM_MINGW = os.name == "nt" and "GCC" in sys.version PLATFORM_PYPY = hasattr(sys, "pypy_version_info") -if sys.platform == "win32" and PLATFORM_MINGW: - from distutils import cygwinccompiler - - cygwin_versions = cygwinccompiler.get_versions() - if cygwin_versions[1] is None: - # ld version is None - # distutils cygwinccompiler might fetch the ld path from gcc - # Try the normal path instead - cygwin_versions = list(cygwin_versions) - cygwin_versions[1] = cygwinccompiler._find_exe_version("ld -v") - cygwinccompiler.get_versions = lambda: tuple(cygwin_versions) - def _dbg(s, tp=None): if DEBUG: From 3cabcf242f472d0aa99ce03f6164787d902091a7 Mon Sep 17 00:00:00 2001 From: nulano Date: Sun, 30 Aug 2020 04:30:47 +0200 Subject: [PATCH 3/4] fix libtiff in MSYS2 --- .github/workflows/test-windows.yml | 5 ++--- setup.py | 4 ++++ src/libImaging/TiffDecode.c | 15 +++++++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 8508a4748..8d4849500 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -232,6 +232,7 @@ jobs: mingw-w64-x86_64-libimagequant \ mingw-w64-x86_64-libjpeg-turbo \ mingw-w64-x86_64-libraqm \ + mingw-w64-x86_64-libtiff \ mingw-w64-x86_64-libwebp \ mingw-w64-x86_64-openjpeg2 \ subversion @@ -241,9 +242,7 @@ jobs: pushd depends && ./install_extra_test_images.sh && popd - name: Build Pillow - run: | - # libtiff is unable to open files - CFLAGS="-coverage" python3 setup.py build_ext --disable-tiff install + run: CFLAGS="-coverage" python3 setup.py build_ext install - name: Test Pillow run: | diff --git a/setup.py b/setup.py index ba34fbce7..e1e2eb00d 100755 --- a/setup.py +++ b/setup.py @@ -710,6 +710,10 @@ class pil_build_ext(build_ext): if feature.tiff: libs.append(feature.tiff) defs.append(("HAVE_LIBTIFF", None)) + # FIXME the following define should be detected automatically + # based on system libtiff, see #4237 + if PLATFORM_MINGW: + defs.append(("USE_WIN32_FILEIO", None)) if feature.xcb: libs.append(feature.xcb) defs.append(("HAVE_XCB", None)) diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c index 532db1f68..f560b14fd 100644 --- a/src/libImaging/TiffDecode.c +++ b/src/libImaging/TiffDecode.c @@ -20,6 +20,17 @@ #include "TiffDecode.h" +/* Convert C file descriptor to WinApi HFILE if LibTiff was compiled with tif_win32.c + * + * This cast is safe, as the top 32-bits of HFILE are guaranteed to be zero, + * see https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication + */ +#ifndef USE_WIN32_FILEIO +#define fd_to_tiff_fd(fd) (fd) +#else +#define fd_to_tiff_fd(fd) ((int)_get_osfhandle(fd)) +#endif + void dump_state(const TIFFSTATE *state){ TRACE(("State: Location %u size %d eof %d data: %p ifd: %d\n", (uint)state->loc, (int)state->size, (uint)state->eof, state->data, state->ifd)); @@ -316,7 +327,7 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ if (clientstate->fp) { TRACE(("Opening using fd: %d\n",clientstate->fp)); lseek(clientstate->fp,0,SEEK_SET); // Sometimes, I get it set to the end. - tiff = TIFFFdOpen(clientstate->fp, filename, mode); + tiff = TIFFFdOpen(fd_to_tiff_fd(clientstate->fp), filename, mode); } else { TRACE(("Opening from string\n")); tiff = TIFFClientOpen(filename, mode, @@ -521,7 +532,7 @@ int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) { if (fp) { TRACE(("Opening using fd: %d for writing \n",clientstate->fp)); - clientstate->tiff = TIFFFdOpen(clientstate->fp, filename, mode); + clientstate->tiff = TIFFFdOpen(fd_to_tiff_fd(clientstate->fp), filename, mode); } else { // malloc a buffer to write the tif, we're going to need to realloc or something if we need bigger. TRACE(("Opening a buffer for writing \n")); From 3099ca6473aac78785dbf417bd38f5e739311560 Mon Sep 17 00:00:00 2001 From: nulano Date: Sun, 30 Aug 2020 05:07:32 +0200 Subject: [PATCH 4/4] document installation on MSYS2 --- docs/installation.rst | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/installation.rst b/docs/installation.rst index 706cfb1d7..9732f9332 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -64,6 +64,8 @@ for raqm, libimagequant, and libxcb:: python3 -m pip install --upgrade pip python3 -m pip install --upgrade Pillow +To install Pillow in MSYS2, see `Building on Windows using MSYS2/MinGW`_. + macOS Installation ^^^^^^^^^^^^^^^^^^ @@ -299,6 +301,42 @@ If you wish to compile Pillow manually, you can use the build scripts in the ``winbuild`` directory used for CI testing and development. These scripts require Visual Studio 2017 or newer and NASM. +Building on Windows using MSYS2/MinGW +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To build Pillow using MSYS2, make sure you run the **MSYS2 MinGW 32-bit** or +**MSYS2 MinGW 64-bit** console, *not* **MSYS2** directly. + +The following instructions target the 64-bit build, for 32-bit +replace all occurrences of ``mingw-w64-x86_64-`` with ``mingw-w64-i686-``. + +Make sure you have Python and GCC installed:: + + pacman -S \ + mingw-w64-x86_64-gcc \ + mingw-w64-x86_64-python3 \ + mingw-w64-x86_64-python3-pip \ + mingw-w64-x86_64-python3-setuptools + +Prerequisites are installed on **MSYS2 MinGW 64-bit** with:: + + pacman -S \ + mingw-w64-x86_64-libjpeg-turbo \ + mingw-w64-x86_64-zlib \ + mingw-w64-x86_64-libtiff \ + mingw-w64-x86_64-freetype \ + mingw-w64-x86_64-lcms2 \ + mingw-w64-x86_64-libwebp \ + mingw-w64-x86_64-openjpeg2 \ + mingw-w64-x86_64-libimagequant \ + mingw-w64-x86_64-libraqm + +Now install Pillow with:: + + python3 -m pip install --upgrade pip + python3 -m pip install --upgrade Pillow + + Building on FreeBSD ^^^^^^^^^^^^^^^^^^^