unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Fabrice Popineau <fabrice.popineau@gmail.com>
To: sds@gnu.org
Cc: Emacs developers <emacs-devel@gnu.org>
Subject: Re: Emacs and ImageMagick-7 issues
Date: Thu, 12 Jan 2017 21:11:08 +0100	[thread overview]
Message-ID: <CAFgFV9OQYOuGfJoQF0PjKDALDdVYTWgjHgrdxjCoB6w232+hgw@mail.gmail.com> (raw)
In-Reply-To: <m1tw945gbn.fsf@gnu.org>


[-- Attachment #1.1: Type: text/plain, Size: 187 bytes --]

2017-01-12 18:38 GMT+01:00 Sam Steingold <sds@gnu.org>:

>
> >


Attached is a diff file for Emacs-25 and ImageMagick-7 in case it can help
(and provided I did no mistake).


-- 
Fabrice

[-- Attachment #1.2: Type: text/html, Size: 682 bytes --]

[-- Attachment #2: emacs-25-imagemagick7.diff --]
[-- Type: text/plain, Size: 14159 bytes --]

diff --git a/lisp/loadup.el b/lisp/loadup.el
index c6107d3..cf62d7b 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -271,6 +271,7 @@
       (load "term/w32-win")
       (load "disp-table")
       (when (eq system-type 'windows-nt)
+        (load "image")
         (load "w32-fns")
         (load "ls-lisp")
         (load "dos-w32"))))
diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el
index 3ff0509..8ef0333 100644
--- a/lisp/term/w32-win.el
+++ b/lisp/term/w32-win.el
@@ -271,6 +271,8 @@ libgnutls-version
        '(gdk-pixbuf "libgdk_pixbuf-2.0-0.dll")
        '(glib "libglib-2.0-0.dll")
        '(gobject "libgobject-2.0-0.dll")
+       '(magickwand "libMagickWand-7.Q16HDRI-0.dll" "libMagickWand-7.Q16-0.dll")
+       '(magickcore "libMagickCore-7.Q16HDRI-0.dll" "libMagickCore-7.Q16-0.dll")
        (if (>= libgnutls-version 30400)
            '(gnutls "libgnutls-30.dll")
          '(gnutls "libgnutls-28.dll" "libgnutls-26.dll"))
diff --git a/src/image.c b/src/image.c
index b724da8..158d7c7 100644
--- a/src/image.c
+++ b/src/image.c
@@ -3159,6 +3255,8 @@ static bool xpm_load (struct frame *f, struct image *img);
 #define XImage xpm_XImage
 #define Display xpm_Display
 #define PIXEL_ALREADY_TYPEDEFED
+#undef close
+#undef open
 #include "X11/xpm.h"
 #undef FOR_MSW
 #undef XColor
@@ -8240,16 +8380,249 @@ 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
+#ifdef __MINGW64__
+#include <ImageMagick-7/MagickWand/MagickWand.h>
+#else
 #include <wand/MagickWand.h>
+#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.  */
+#ifdef __MINGW64__
+#include <ImageMagick-7/MagickCore/version.h>
+#else
 #include <magick/version.h>
+#endif
 #if 0x653 <= MagickLibVersion && MagickLibVersion <= 0x665
 extern WandExport void PixelGetMagickColor (const PixelWand *,
                                             MagickPixelPacket *);
 #endif
 
+#ifdef WINDOWSNT
+DEF_DLL_FN (MagickWand *, CloneMagickWand, (const MagickWand *));
+DEF_DLL_FN (MagickWand *, DestroyMagickWand, (MagickWand *));
+DEF_DLL_FN (MagickWand *, DestroyPixelIterator, (PixelIterator *));
+DEF_DLL_FN (PixelWand *, DestroyPixelWand, (PixelWand *));
+DEF_DLL_FN (MagickBooleanType, MagickCropImage, (MagickWand *, const size_t, const size_t, const ssize_t, const ssize_t));
+#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
+DEF_DLL_FN (MagickBooleanType, MagickExportImagePixels, (MagickWand *, const ssize_t, const ssize_t, const size_t, const size_t, const char *, const StorageType, void *));
+#endif
+DEF_DLL_FN (char *, MagickGetException, (const MagickWand *, ExceptionType *));
+DEF_DLL_FN (MagickWand *, MagickGetImage, (MagickWand *));
+DEF_DLL_FN (DisposeType, MagickGetImageDelay, (MagickWand *));
+DEF_DLL_FN (DisposeType, MagickGetImageDispose, (MagickWand *));
+DEF_DLL_FN (size_t, MagickGetImageHeight, (MagickWand *));
+DEF_DLL_FN (MagickBooleanType, MagickGetImagePage, (MagickWand *, size_t *, size_t *, ssize_t *, ssize_t *));
+DEF_DLL_FN (char *, MagickGetImageSignature, (MagickWand *));
+DEF_DLL_FN (size_t, MagickGetImageWidth, (MagickWand *));
+DEF_DLL_FN (size_t, MagickGetNumberImages, (MagickWand *));
+#ifdef HAVE_MAGICKMERGEIMAGELAYERS
+DEF_DLL_FN (MagickWand *, MagickMergeImageLayers, (MagickWand *, const LayerMethod));
+#else
+DEF_DLL_FN (MagickWand *, MagickFlattenImages, (MagickWand *));
+#endif
+DEF_DLL_FN (MagickBooleanType, MagickReadImage, (MagickWand *, const char *));
+DEF_DLL_FN (MagickBooleanType, MagickReadImageBlob, (MagickWand *, const void *, const size_t));
+DEF_DLL_FN (void *, MagickRelinquishMemory, (void *));
+DEF_DLL_FN (MagickBooleanType, MagickRotateImage, (MagickWand *, const PixelWand *, const double));
+DEF_DLL_FN (MagickBooleanType, MagickScaleImage, (MagickWand *, const size_t, const size_t));
+DEF_DLL_FN (MagickBooleanType, MagickSetFilename, (MagickWand *, const char *));
+DEF_DLL_FN (MagickBooleanType, MagickSetImageBackgroundColor, (MagickWand *, const PixelWand *));
+DEF_DLL_FN (MagickBooleanType, MagickSetIteratorIndex, (MagickWand *, const ssize_t));
+DEF_DLL_FN (void, MagickWandGenesis, (void));
+DEF_DLL_FN (void, MagickWandTerminus, (void));
+DEF_DLL_FN (MagickWand *, NewMagickWand, (void));
+DEF_DLL_FN (PixelIterator *, NewPixelIterator, (MagickWand *));
+DEF_DLL_FN (PixelWand *, NewPixelWand, (void));
+DEF_DLL_FN (double, PixelGetAlpha, (const PixelWand *));
+DEF_DLL_FN (void, PixelGetMagickColor, (const PixelWand *, PixelInfo *));
+DEF_DLL_FN (PixelWand **, PixelGetNextIteratorRow, (PixelIterator *, size_t *));
+DEF_DLL_FN (MagickBooleanType, PixelSetIteratorRow, (PixelIterator *, const ssize_t));
+DEF_DLL_FN (void, PixelSetPixelColor, (PixelWand *, const PixelInfo *));
+DEF_DLL_FN (void, PixelSetRed, (PixelWand *, const double));
+DEF_DLL_FN (void, PixelSetGreen, (PixelWand *, const double));
+DEF_DLL_FN (void, PixelSetBlue, (PixelWand *, const double));
+DEF_DLL_FN (MagickBooleanType, PixelSyncIterator, (PixelIterator *));
+
+DEF_DLL_FN (ExceptionInfo *, DestroyExceptionInfo, (ExceptionInfo *));
+DEF_DLL_FN (char *, DestroyString, (char *));
+DEF_DLL_FN (ExceptionInfo *, AcquireExceptionInfo, ());
+DEF_DLL_FN (char **, GetMagickList, (const char *, size_t *, ExceptionInfo *));
+
+static bool
+init_imagemagick_functions (void)
+{
+  HMODULE magickwand, magickcore;
+
+  /* Override ImageMgick settings to use the one packaged with Emacs. */
+  char buf[512];
+  char *var_format[] = {
+    "MAGICK_CONFIGURE_PATH=%s/lib/ImageMagick-7.0.3/config-Q16HDRI/",
+    "MAGICK_CODER_MODULE_PATH=%s/lib/ImageMagick-7.0.3/modules-Q16HDRI/coders/",
+    "MAGICK_FILTER_MODULE_PATH=%s/lib/ImageMagick-7.0.3/modules-Q16HDRI/filters/",
+#if 0
+    "MAGICK_DOCUMENTATION_PATH=%s/share/doc/ImageMagick-7/",
+    "MAGICK_EXECUTABLE_PATH=%s/bin",
+    "MAGICK_SHARE_PATH=%s/share/ImageMagick-7",
+    "MAGICK_SHAREARCH_PATH=%s/lib/ImageMagick-7.0.3/config-Q16HDRI",
+#endif
+    NULL
+  };
+  /* FIXME: assumes emacs is in bin directory */
+  char *emacs_dir = SSDATA(Fdirectory_file_name(Fexpand_file_name(build_string("../"), Vinvocation_directory)));
+
+  for (int i = 0; var_format[i] != NULL; i++) {
+    sprintf(buf, var_format[i], emacs_dir);
+    xputenv(buf);
+  };
+
+  if (!(magickcore = w32_delayed_load (Qmagickcore))
+      || !(magickwand = w32_delayed_load (Qmagickwand)))
+    return 0;
+
+  LOAD_DLL_FN (magickwand, CloneMagickWand);
+  LOAD_DLL_FN (magickwand, DestroyMagickWand);
+  LOAD_DLL_FN (magickwand, DestroyPixelIterator);
+  LOAD_DLL_FN (magickwand, DestroyPixelWand);
+  LOAD_DLL_FN (magickwand, MagickCropImage);
+#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
+  LOAD_DLL_FN (magickwand, MagickExportImagePixels);
+#endif
+  LOAD_DLL_FN (magickwand, MagickGetException);
+  LOAD_DLL_FN (magickwand, MagickGetImage);
+  LOAD_DLL_FN (magickwand, MagickGetImageDelay);
+  LOAD_DLL_FN (magickwand, MagickGetImageDispose);
+  LOAD_DLL_FN (magickwand, MagickGetImageHeight);
+  LOAD_DLL_FN (magickwand, MagickGetImagePage);
+  LOAD_DLL_FN (magickwand, MagickGetImageSignature);
+  LOAD_DLL_FN (magickwand, MagickGetImageWidth);
+  LOAD_DLL_FN (magickwand, MagickGetNumberImages);
+#ifdef HAVE_MAGICKMERGEIMAGELAYERS
+  LOAD_DLL_FN (magickwand, MagickMergeImageLayers);
+#else
+  LOAD_DLL_FN (magickwand, MagickFlattenImages);
+#endif
+  LOAD_DLL_FN (magickwand, MagickReadImage);
+  LOAD_DLL_FN (magickwand, MagickReadImageBlob);
+  LOAD_DLL_FN (magickwand, MagickRelinquishMemory);
+  LOAD_DLL_FN (magickwand, MagickRotateImage);
+  LOAD_DLL_FN (magickwand, MagickScaleImage);
+  LOAD_DLL_FN (magickwand, MagickSetFilename);
+  LOAD_DLL_FN (magickwand, MagickSetImageBackgroundColor);
+  LOAD_DLL_FN (magickwand, MagickSetIteratorIndex);
+  LOAD_DLL_FN (magickwand, MagickWandGenesis);
+  LOAD_DLL_FN (magickwand, MagickWandTerminus);
+  LOAD_DLL_FN (magickwand, NewMagickWand);
+  LOAD_DLL_FN (magickwand, NewPixelIterator);
+  LOAD_DLL_FN (magickwand, NewPixelWand);
+  LOAD_DLL_FN (magickwand, PixelGetAlpha);
+  LOAD_DLL_FN (magickwand, PixelGetMagickColor);
+  LOAD_DLL_FN (magickwand, PixelGetNextIteratorRow);
+  LOAD_DLL_FN (magickwand, PixelSetIteratorRow);
+  LOAD_DLL_FN (magickwand, PixelSetPixelColor);
+  LOAD_DLL_FN (magickwand, PixelSetRed);
+  LOAD_DLL_FN (magickwand, PixelSetGreen);
+  LOAD_DLL_FN (magickwand, PixelSetBlue);
+  LOAD_DLL_FN (magickwand, PixelSyncIterator);
+
+  LOAD_DLL_FN (magickcore, DestroyExceptionInfo);
+  LOAD_DLL_FN (magickcore, DestroyString);
+  LOAD_DLL_FN (magickcore, AcquireExceptionInfo);
+  LOAD_DLL_FN (magickcore, GetMagickList);
+
+  return 1;
+}
+
+#undef CloneMagickWand
+#undef DestroyMagickWand
+#undef DestroyPixelIterator
+#undef DestroyPixelWand
+#undef MagickCropImage
+#undef MagickExportImagePixels
+#undef MagickGetException
+#undef MagickGetImage
+#undef MagickGetImageDelay
+#undef MagickGetImageDispose
+#undef MagickGetImageHeight
+#undef MagickGetImagePage
+#undef MagickGetImageSignature
+#undef MagickGetImageWidth
+#undef MagickGetNumberImages
+#undef MagickMergeImageLayers
+#undef MagickFlattenImages
+#undef MagickReadImage
+#undef MagickReadImageBlob
+#undef MagickRelinquishMemory
+#undef MagickRotateImage
+#undef MagickScaleImage
+#undef MagickSetFilename
+#undef MagickSetImageBackgroundColor
+#undef MagickSetIteratorIndex
+#undef MagickWandGenesis
+#undef MagickWandTerminus
+#undef NewMagickWand
+#undef NewPixelIterator
+#undef NewPixelWand
+#undef PixelGetAlpha
+#undef PixelGetMagickColor
+#undef PixelGetNextIteratorRow
+#undef PixelSetIteratorRow
+#undef PixelSetPixelColor
+#undef PixelSetRed
+#undef PixelSetGreen
+#undef PixelSetBlue
+#undef PixelSyncIterator
+#undef DestroyExceptionInfo
+#undef DestroyString
+#undef AcquireExceptionInfo
+#undef GetMagickList
+
+#define CloneMagickWand fn_CloneMagickWand
+#define DestroyMagickWand fn_DestroyMagickWand
+#define DestroyPixelIterator fn_DestroyPixelIterator
+#define DestroyPixelWand fn_DestroyPixelWand
+#define MagickCropImage fn_MagickCropImage
+#define MagickExportImagePixels fn_MagickExportImagePixels
+#define MagickGetException fn_MagickGetException
+#define MagickGetImage fn_MagickGetImage
+#define MagickGetImageDelay fn_MagickGetImageDelay
+#define MagickGetImageDispose fn_MagickGetImageDispose
+#define MagickGetImageHeight fn_MagickGetImageHeight
+#define MagickGetImagePage fn_MagickGetImagePage
+#define MagickGetImageSignature fn_MagickGetImageSignature
+#define MagickGetImageWidth fn_MagickGetImageWidth
+#define MagickGetNumberImages fn_MagickGetNumberImages
+#define MagickMergeImageLayers fn_MagickMergeImageLayers
+#define MagickFlattenImages fn_MagickFlattenImages
+#define MagickReadImage fn_MagickReadImage
+#define MagickReadImageBlob fn_MagickReadImageBlob
+#define MagickRelinquishMemory fn_MagickRelinquishMemory
+#define MagickRotateImage fn_MagickRotateImage
+#define MagickScaleImage fn_MagickScaleImage
+#define MagickSetFilename fn_MagickSetFilename
+#define MagickSetImageBackgroundColor fn_MagickSetImageBackgroundColor
+#define MagickSetIteratorIndex fn_MagickSetIteratorIndex
+#define MagickWandGenesis fn_MagickWandGenesis
+#define MagickWandTerminus fn_MagickWandTerminus
+#define NewMagickWand fn_NewMagickWand
+#define NewPixelIterator fn_NewPixelIterator
+#define NewPixelWand fn_NewPixelWand
+#define PixelGetAlpha fn_PixelGetAlpha
+#define PixelGetMagickColor fn_PixelGetMagickColor
+#define PixelGetNextIteratorRow fn_PixelGetNextIteratorRow
+#define PixelSetIteratorRow fn_PixelSetIteratorRow
+#define PixelSetPixelColor fn_PixelSetPixelColor
+#define PixelSetRed fn_PixelSetRed
+#define PixelSetGreen fn_PixelSetGreen
+#define PixelSetBlue fn_PixelSetBlue
+#define PixelSyncIterator fn_PixelSyncIterator
+#define DestroyExceptionInfo fn_DestroyExceptionInfo
+#define DestroyString fn_DestroyString
+#define AcquireExceptionInfo fn_AcquireExceptionInfo
+#define GetMagickList fn_GetMagickList
+
+#endif /* !WINDOWSNT */
+
 /* Log ImageMagick error message.
    Useful when a ImageMagick function returns the status `MagickFalse'.  */
 
@@ -8402,7 +8775,7 @@ imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
       PixelWand **source, **dest;
       size_t source_width, source_height;
       ssize_t source_left, source_top;
-      MagickPixelPacket pixel;
+      PixelInfo pixel;
       DisposeType dispose;
       ptrdiff_t lines = 0;
 
@@ -8467,7 +8840,7 @@ imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
               if (dispose == BackgroundDispose || PixelGetAlpha (source[x]))
 		{
                   PixelGetMagickColor (source[x], &pixel);
-		  PixelSetMagickColor (dest[x + source_left], &pixel);
+                  PixelSetPixelColor (dest[x + source_left], &pixel);
 		}
             }
           PixelSyncIterator (dest_iterator);
@@ -8512,7 +8885,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
   MagickWand *image_wand;
   PixelIterator *iterator;
   PixelWand **pixels, *bg_wand = NULL;
-  MagickPixelPacket  pixel;
+  PixelInfo  pixel;
   Lisp_Object image;
   Lisp_Object value;
   Lisp_Object crop;
@@ -8889,6 +9262,11 @@ and `imagemagick-types-inhibit'.  */)
   char **imtypes;
   size_t i;
 
+#if WINDOWSNT
+          if (!init_imagemagick_functions ())
+            return Qnil;
+#endif
+
   ex = AcquireExceptionInfo();
   imtypes = GetMagickList ("*", &numf, ex);
   DestroyExceptionInfo(ex);
@@ -9902,12 +10347,16 @@ non-numeric, there is no explicit limit on the size of images.  */);
 #if defined (HAVE_IMAGEMAGICK)
   DEFSYM (Qimagemagick, "imagemagick");
   ADD_IMAGE_TYPE (Qimagemagick);
+#if defined HAVE_NTGUI && !defined CYGWIN
+  DEFSYM (Qmagickwand, "magickwand");
+  DEFSYM (Qmagickcore, "magickcore");
+#endif /* HAVE_NTGUI */
 #endif
 
 #if defined (HAVE_RSVG)
   DEFSYM (Qsvg, "svg");
   ADD_IMAGE_TYPE (Qsvg);
-#ifdef HAVE_NTGUI
+#if defined (HAVE_NTGUI) && !defined (CYGWIN)
   /* Other libraries used directly by svg code.  */
   DEFSYM (Qgdk_pixbuf, "gdk-pixbuf");
   DEFSYM (Qglib, "glib");

  reply	other threads:[~2017-01-12 20:11 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-02 20:14 Emacs and ImageMagick-7 issues Angelo Graziosi
2017-01-12 17:38 ` Sam Steingold
2017-01-12 20:11   ` Fabrice Popineau [this message]
2017-01-12 20:13     ` Fabrice Popineau
2017-01-13  8:08     ` Eli Zaretskii
  -- strict thread matches above, loose matches on Subject: below --
2017-01-13 10:03 Angelo Graziosi
2017-01-13 10:54 ` Angelo Graziosi
2017-01-13 13:01   ` Tino Calancha
2017-01-13 13:31     ` Angelo Graziosi
2017-01-13 13:49       ` Tino Calancha

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAFgFV9OQYOuGfJoQF0PjKDALDdVYTWgjHgrdxjCoB6w232+hgw@mail.gmail.com \
    --to=fabrice.popineau@gmail.com \
    --cc=emacs-devel@gnu.org \
    --cc=sds@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).