From 2bffa0189dec332f0026c144f081493e2b7fe94b Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 22 Oct 2021 15:41:00 +0300 Subject: [PATCH] Fix WebP support on MS-Windows * src/image.c (WebPDecodeRGBA, WebPDecodeRGB, WebPFree): Use correct names and argument lists in DEF_DLL_FN; fix typos. (WebPGetFeaturesInternal): Load this instead of WebPGetFeatures, which is a static inline function in webp/decode.h. (WebPGetFeatures): Redirect to call WebPGetFeaturesInternal. * lisp/term/w32-win.el (dynamic-library-alist): Fix the name of the WebP symbol. * configure.ac (HAVE_WEBP): Fix detection of libwebp on MinGW. * nt/INSTALL.W64: * nt/INSTALL: Update information about libwebp availability. --- configure.ac | 18 +++++++++--------- lisp/term/w32-win.el | 2 +- nt/INSTALL | 10 +++++++++- nt/INSTALL.W64 | 1 + src/image.c | 16 +++++++++++----- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index d091866b872..86928c83934 100644 --- a/configure.ac +++ b/configure.ac @@ -2590,23 +2590,23 @@ if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${opsys}" = fi ### Use -lwebp if available, unless '--with-webp=no' -### mingw32 doesn't use -lwebp, since it loads the library dynamically. HAVE_WEBP=no if test "${with_webp}" != "no"; then - if test "$opsys" = mingw32; then - AC_CHECK_HEADER([webp/decode.h], [HAVE_WEBP=yes]) - elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \ - || test "${HAVE_NS}" = "yes"; then + if test "${HAVE_X11}" = "yes" || test "${opsys}" = "mingw32" \ + || test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes"; then WEBP_REQUIRED=0.6.0 WEBP_MODULE="libwebp >= $WEBP_REQUIRED" EMACS_CHECK_MODULES([WEBP], [$WEBP_MODULE]) AC_SUBST(WEBP_CFLAGS) AC_SUBST(WEBP_LIBS) - - if test $HAVE_WEBP = yes; then - AC_DEFINE(HAVE_WEBP, 1, [Define to 1 if using libwebp.]) - CFLAGS="$CFLAGS $WEBP_CFLAGS" + fi + if test $HAVE_WEBP = yes; then + AC_DEFINE(HAVE_WEBP, 1, [Define to 1 if using libwebp.]) + CFLAGS="$CFLAGS $WEBP_CFLAGS" + # Windows loads libwebp dynamically + if test "${opsys}" = "mingw32"; then + WEBP_LIBS= fi fi fi diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el index 366992cbbf0..8b745c495d5 100644 --- a/lisp/term/w32-win.el +++ b/lisp/term/w32-win.el @@ -274,7 +274,7 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.") '(gif "libgif-6.dll" "giflib5.dll" "gif.dll") '(gif "libgif-5.dll" "giflib4.dll" "libungif4.dll" "libungif.dll"))) '(svg "librsvg-2-2.dll") - '(libwebp "libwebp-7.dll" "libwebp.dll") + '(webp "libwebp-7.dll" "libwebp.dll") '(gdk-pixbuf "libgdk_pixbuf-2.0-0.dll") '(glib "libglib-2.0-0.dll") '(gio "libgio-2.0-0.dll") diff --git a/nt/INSTALL b/nt/INSTALL index a39057c66c6..5a76f5bdeda 100644 --- a/nt/INSTALL +++ b/nt/INSTALL @@ -737,10 +737,18 @@ build will run on Windows 9X and newer systems). without it by specifying the --without-rsvg switch to the configure script. - For WebP images you will need libwebp: + For WebP images you will need libwebp. You can find it here: + + http://sourceforge.net/projects/ezwinports/files/ + + Note: the MS-Windows binary distribution on the Google site: https://developers.google.com/speed/webp/ + were compiled by MSVC, and include only static libraries, no DLLs. + So you cannot use that to build Emacs with WebP support on + MS-Windows, as that needs libwebp as a DLL. + Binaries for the other image libraries can be found on the ezwinports site or at the GnuWin32 project (the latter are generally very old, so not recommended). Note specifically that, due to some diff --git a/nt/INSTALL.W64 b/nt/INSTALL.W64 index 8f0d0c9528f..c3845d5b177 100644 --- a/nt/INSTALL.W64 +++ b/nt/INSTALL.W64 @@ -51,6 +51,7 @@ packages (you can copy and paste it into the shell with Shift + Insert): mingw-w64-x86_64-libpng \ mingw-w64-x86_64-libjpeg-turbo \ mingw-w64-x86_64-librsvg \ + mingw-w64-x86_64-libwebp \ mingw-w64-x86_64-lcms2 \ mingw-w64-x86_64-jansson \ mingw-w64-x86_64-libxml2 \ diff --git a/src/image.c b/src/image.c index fe0bb509c58..308dc687260 100644 --- a/src/image.c +++ b/src/image.c @@ -8802,10 +8802,15 @@ webp_image_p (Lisp_Object object) /* WebP library details. */ DEF_DLL_FN (int, WebPGetInfo, (const uint8_t *, size_t, int *, int *)); -DEF_DLL_FN (VP8StatusCode, WebPGetFeatures, (const uint8_t *, size_t, WebPBitstreamFeatures *)); +/* WebPGetFeatures is a static inline function defined in WebP's + decode.h. Since we cannot use that with dynamically-loaded libwebp + DLL, we instead load the internal function it calls and redirect to + that through a macro. */ +DEF_DLL_FN (VP8StatusCode, WebPGetFeaturesInternal, + (const uint8_t *, size_t, WebPBitstreamFeatures *, int)); +DEF_DLL_FN (uint8_t *, WebPDecodeRGBA, (const uint8_t *, size_t, int *, int *)); DEF_DLL_FN (uint8_t *, WebPDecodeRGB, (const uint8_t *, size_t, int *, int *)); -DEF_DLL_FN (uint8_t *, WebPDecodeBGR, (const uint8_t *, size_t, int *, int *)); -DEF_DLL_FN (void, WebPFreeDecBuffer (WebPDecBuffer *)); +DEF_DLL_FN (void, WebPFree, (void *)); static bool init_webp_functions (void) @@ -8816,7 +8821,7 @@ init_webp_functions (void) return false; LOAD_DLL_FN (library, WebPGetInfo); - LOAD_DLL_FN (library, WebPGetFeatures); + LOAD_DLL_FN (library, WebPGetFeaturesInternal); LOAD_DLL_FN (library, WebPDecodeRGBA); LOAD_DLL_FN (library, WebPDecodeRGB); LOAD_DLL_FN (library, WebPFree); @@ -8830,7 +8835,8 @@ init_webp_functions (void) #undef WebPFree #define WebPGetInfo fn_WebPGetInfo -#define WebPGetFeatures fn_WebPGetFeatures +#define WebPGetFeatures(d,s,f) \ + fn_WebPGetFeaturesInternal(d,s,f,WEBP_DECODER_ABI_VERSION) #define WebPDecodeRGBA fn_WebPDecodeRGBA #define WebPDecodeRGB fn_WebPDecodeRGB #define WebPFree fn_WebPFree -- 2.39.5