Subject: [PATCH] Add support for ImageMagick 7 (Bug#25967)

From: Karl Otness <[email-masked]>
Date: Fri, 1 Jun 2018 14:17:32 -0500

I have attached a patch which adds support for ImageMagick version 7.
I have tried to keep compatibility with version 6 as well. I have
gotten clean builds against both versions on my machine (running Arch
and overriding PKG_CONFIG_PATH to test). I also did a quick build on a
Mac and it also seemed to link up to the ImageMagick 7 from homebrew.
On both machines I could open/resize/rotate images and page through
the frames of animated GIFs.

The changes that seem to be needed are doable with a #define and a
typedef to rename a function and type in image.c. The patch makes
these conditional on the major version that is found by pkg-config
during ./configure, trying version 7 first and falling back to 6.

I'm not very familiar with autoconf, but the conditional checking in
the patch seems to work and avoids checking for ImageMagick 6 if it
finds version 7 first. I used AS_IF for this rather than the action
arguments to EMACS_CHECK_MODULES since this way seems to avoid the
redundant checks.

Thanks,
Karl
From 2d9b9e611e1c08240830cbb99fe445a99cc93594 Mon Sep 17 00:00:00 2001
From: Karl Otness <[email-masked]>
Date: Thu, 31 May 2018 19:23:21 -0500
Subject: [PATCH] Add support for ImageMagick 7 (Bug#25967)

* configure.ac: Allow linking to ImageMagick 7 and expose the major
version found to the rest of build.
* src/image.c [MagickWand >= 7]: Define functions and types for
ImageMagick 7 compatibility.
---
 configure.ac | 17 +++++++++++++----
 src/image.c  | 15 ++++++++++++---
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/configure.ac b/configure.ac
index a11abc1b65..c3a5401570 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2549,9 +2549,16 @@ AC_DEFUN
 
     ## 6.3.5 is the earliest version known to work; see Bug#17339.
     ## 6.8.2 makes Emacs crash; see Bug#13867.
-    ## 7 and later have not been ported to; See Bug#25967.
-    IMAGEMAGICK_MODULE="Wand >= 6.3.5 Wand != 6.8.2 Wand < 7"
-    EMACS_CHECK_MODULES([IMAGEMAGICK], [$IMAGEMAGICK_MODULE])
+    IMAGEMAGICK7_MODULE="MagickWand >= 7"
+    IMAGEMAGICK6_MODULE="Wand >= 6.3.5 Wand != 6.8.2"
+    # As we check for ImageMagick 7 then 6 track which version we find
+    EMACS_CHECK_MODULES([IMAGEMAGICK], [$IMAGEMAGICK7_MODULE])
+    AS_IF([test $HAVE_IMAGEMAGICK = yes],
+      [IMAGEMAGICK_MAJOR=7],
+      [
+        EMACS_CHECK_MODULES([IMAGEMAGICK], [$IMAGEMAGICK6_MODULE])
+        AS_IF([test $HAVE_IMAGEMAGICK = yes], [IMAGEMAGICK_MAJOR=6])
+      ])
 
     if test $HAVE_IMAGEMAGICK = yes; then
       OLD_CFLAGS=$CFLAGS
@@ -2571,6 +2578,8 @@ AC_DEFUN
     fi
     if test $HAVE_IMAGEMAGICK = yes; then
       AC_DEFINE([HAVE_IMAGEMAGICK], 1, [Define to 1 if using ImageMagick.])
+      AC_DEFINE_UNQUOTED([IMAGEMAGICK_MAJOR], [$IMAGEMAGICK_MAJOR],
+                         [ImageMagick major version number (from configure).])
     else
       IMAGEMAGICK_CFLAGS=
       IMAGEMAGICK_LIBS=
@@ -5458,7 +5467,7 @@ AC_DEFUN
   Does Emacs use -lrsvg-2?                                ${HAVE_RSVG}
   Does Emacs use cairo?                                   ${HAVE_CAIRO}
   Does Emacs use -llcms2?                                 ${HAVE_LCMS2}
-  Does Emacs use imagemagick (version 6)?                 ${HAVE_IMAGEMAGICK}
+  Does Emacs use imagemagick?                             ${HAVE_IMAGEMAGICK}
   Does Emacs support sound?                               ${HAVE_SOUND}
   Does Emacs use -lgpm?                                   ${HAVE_GPM}
   Does Emacs use -ldbus?                                  ${HAVE_DBUS}
diff --git a/src/image.c b/src/image.c
index 992b225d7b..3c1366f5ce 100644
--- a/src/image.c
+++ b/src/image.c
@@ -8272,11 +8272,20 @@ imagemagick_image_p (Lisp_Object object)
 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
    Therefore rename the function so it doesn't collide with ImageMagick.  */
 #define DrawRectangle DrawRectangleGif
-#include <wand/MagickWand.h>
+
+#if IMAGEMAGICK_MAJOR == 6
+# include <wand/MagickWand.h>
+# include <magick/version.h>
+#else
+# include <MagickWand/MagickWand.h>
+# include <MagickCore/version.h>
+/* ImageMagick 7 compatibility definitions */
+# define PixelSetMagickColor PixelSetPixelColor
+typedef PixelInfo MagickPixelPacket;
+#endif
 
 /* ImageMagick 6.5.3 through 6.6.5 hid PixelGetMagickColor for some reason.
    Emacs seems to work fine with the hidden version, so unhide it.  */
-#include <magick/version.h>
 #if 0x653 <= MagickLibVersion && MagickLibVersion <= 0x665
 extern WandExport void PixelGetMagickColor (const PixelWand *,
 					    MagickPixelPacket *);
@@ -8814,7 +8823,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
 #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
     {
       size_t image_height;
-      MagickRealType color_scale = 65535.0 / QuantumRange;
+      MagickRealType color_scale = 65535.0 / (MagickRealType) QuantumRange;
 #ifdef USE_CAIRO
       data = xmalloc (width * height * 4);
       color_scale /= 256;
-- 
2.17.1