Package: emacs;
Reported by: Tej Chajed <tchajed <at> mit.edu>
Date: Sat, 4 Mar 2017 16:21:02 UTC
Severity: wishlist
Tags: patch
Found in version 25.1
Fixed in version 27.1
Done: Glenn Morris <rgm <at> gnu.org>
Bug is archived. No further changes may be made.
Message #72 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Andy Moreton <andrewjmoreton <at> gmail.com> To: bug-gnu-emacs <at> gnu.org Subject: Re: bug#25967: [PATCH] Add support for ImageMagick 7 (Bug#25967) Date: Mon, 03 Sep 2018 23:57:05 +0100
[Message part 1 (text/plain, inline)]
On Fri 01 Jun 2018, Karl Otness wrote: > 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. As a followup, here is a patch to add ImageMagick support for Windows. The patch was initially developed for Imagemagick 6, but I've updated it to support ImageMagick 7. I've given this some light testing on a 64bit mingw64 (MSYS2) and 64bit cygwin builds, both of which use Imagemagick 7. Please test, and report if it breaks anything on other platforms. AndyM
[imagemagick7.patch (text/x-patch, inline)]
diff --git a/configure.ac b/configure.ac index 6f3d7338c3..25e42fdbaf 100644 --- a/configure.ac +++ b/configure.ac @@ -2533,6 +2533,10 @@ AC_DEFUN MagickMergeImageLayers MagickAutoOrientImage]) CFLAGS=$OLD_CFLAGS LIBS=$OLD_LIBS + # Windows loads libmagickwand dynamically + if test "${opsys}" = "mingw32"; then + IMAGEMAGICK_LIBS= + fi # Check that ImageMagick links. It does not link on Fedora 25 # with './configure CC=clang', as pkg-config outputs flags like # -lomp that work for GCC but not Clang. diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el index dc57160d04..e07a011de5 100644 --- a/lisp/term/w32-win.el +++ b/lisp/term/w32-win.el @@ -277,7 +277,8 @@ libgnutls-version '(libxml2 "libxml2-2.dll" "libxml2.dll") '(zlib "zlib1.dll" "libz-1.dll") '(lcms2 "liblcms2-2.dll") - '(json "libjansson-4.dll"))) + '(json "libjansson-4.dll") + '(imagemagick "libMagickWand-7.Q16HDRI-6.dll"))) ;;; multi-tty support (defvar w32-initialized nil diff --git a/src/image.c b/src/image.c index 24decbc099..3faa3c6b3c 100644 --- a/src/image.c +++ b/src/image.c @@ -8277,8 +8277,8 @@ imagemagick_image_p (Lisp_Object object) #ifdef HAVE_IMAGEMAGICK7 # include <MagickWand/MagickWand.h> # include <MagickCore/version.h> -/* ImageMagick 7 compatibility definitions. */ -# define PixelSetMagickColor PixelSetPixelColor +/* ImageMagick 7 compatibility definitions. API functions are + redefined later, after the w32 runtime linking support code. */ typedef PixelInfo MagickPixelPacket; #else # include <wand/MagickWand.h> @@ -8292,6 +8292,255 @@ extern WandExport void PixelGetMagickColor (const PixelWand *, MagickPixelPacket *); #endif +#if defined HAVE_NTGUI && defined WINDOWSNT + +/* Imagemagick MagickWand library functions. */ + +DEF_DLL_FN (MagickWand *, CloneMagickWand, (const MagickWand *)); +DEF_DLL_FN (MagickWand *, DestroyMagickWand, (MagickWand *)); +DEF_DLL_FN (PixelIterator *, 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)); +DEF_DLL_FN (MagickBooleanType, MagickExportImagePixels, + (MagickWand *, const ssize_t, const ssize_t, const size_t, + const size_t, const char *, const StorageType, void *)); +#ifndef HAVE_MAGICKMERGEIMAGELAYERS +DEF_DLL_FN(MagickWand *, MagickFlattenImages, (MagickWand *)); +#endif +DEF_DLL_FN (char *, MagickGetException, (const MagickWand *, ExceptionType *)); +DEF_DLL_FN (MagickWand *, MagickGetImage, (MagickWand *)); +DEF_DLL_FN (size_t, 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)); +#endif +DEF_DLL_FN (char **, MagickQueryFormats, (const char *, size_t *)); +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 *, MagickPixelPacket *)); +DEF_DLL_FN (PixelWand **, PixelGetNextIteratorRow, (PixelIterator *, size_t *)); +DEF_DLL_FN (void, PixelSetBlue, (PixelWand *, const double)); +DEF_DLL_FN (void, PixelSetGreen, (PixelWand *, const double)); +DEF_DLL_FN (MagickBooleanType, PixelSetIteratorRow, + (PixelIterator *, const ssize_t)); +#ifdef HAVE_IMAGEMAGICK7 +DEF_DLL_FN (void, PixelSetPixelColor, (PixelWand *, const MagickPixelPacket *)); +#else +DEF_DLL_FN (void, PixelSetMagickColor, (PixelWand *, const MagickPixelPacket *)); +#endif +DEF_DLL_FN (void, PixelSetRed, (PixelWand *, const double)); +DEF_DLL_FN (MagickBooleanType, PixelSyncIterator, (PixelIterator *)); + +DEF_DLL_FN (MagickBooleanType, MagickSetSize, + (MagickWand *, const size_t, const size_t)); +DEF_DLL_FN (MagickBooleanType, MagickSetDepth, + (MagickWand *, const size_t)); +#ifdef HAVE_MAGICKAUTOORIENTIMAGE +DEF_DLL_FN (MagickBooleanType, MagickAutoOrientImage, (MagickWand *)); +#endif + +static bool +init_imagemagick_functions (void) +{ + HMODULE library = NULL; + + if (!(library = w32_delayed_load (Qimagemagick))) + { + return 0; + } + + LOAD_DLL_FN (library, CloneMagickWand); + LOAD_DLL_FN (library, DestroyMagickWand); + LOAD_DLL_FN (library, DestroyPixelIterator); + LOAD_DLL_FN (library, DestroyPixelWand); + LOAD_DLL_FN (library, MagickCropImage); + LOAD_DLL_FN (library, MagickExportImagePixels); +#ifndef HAVE_MAGICKMERGEIMAGELAYERS + LOAD_DLL_FN (library, MagickFlattenImages); +#endif + LOAD_DLL_FN (library, MagickGetException); + LOAD_DLL_FN (library, MagickGetImage); + LOAD_DLL_FN (library, MagickGetImageDelay); + LOAD_DLL_FN (library, MagickGetImageDispose); + LOAD_DLL_FN (library, MagickGetImageHeight); + LOAD_DLL_FN (library, MagickGetImagePage); + LOAD_DLL_FN (library, MagickGetImageSignature); + LOAD_DLL_FN (library, MagickGetImageWidth); + LOAD_DLL_FN (library, MagickGetNumberImages); +#ifdef HAVE_MAGICKMERGEIMAGELAYERS + LOAD_DLL_FN (library, MagickMergeImageLayers); +#endif + LOAD_DLL_FN (library, MagickQueryFormats); + LOAD_DLL_FN (library, MagickReadImage); + LOAD_DLL_FN (library, MagickReadImageBlob); + LOAD_DLL_FN (library, MagickRelinquishMemory); + LOAD_DLL_FN (library, MagickRotateImage); + LOAD_DLL_FN (library, MagickScaleImage); + LOAD_DLL_FN (library, MagickSetFilename); + LOAD_DLL_FN (library, MagickSetImageBackgroundColor); + LOAD_DLL_FN (library, MagickSetIteratorIndex); + LOAD_DLL_FN (library, MagickWandGenesis); + LOAD_DLL_FN (library, MagickWandTerminus); + LOAD_DLL_FN (library, NewMagickWand); + LOAD_DLL_FN (library, NewPixelIterator); + LOAD_DLL_FN (library, NewPixelWand); + LOAD_DLL_FN (library, PixelGetAlpha); + LOAD_DLL_FN (library, PixelGetMagickColor); + LOAD_DLL_FN (library, PixelGetNextIteratorRow); + LOAD_DLL_FN (library, PixelSetBlue); + LOAD_DLL_FN (library, PixelSetGreen); + LOAD_DLL_FN (library, PixelSetIteratorRow); +#ifdef HAVE_IMAGEMAGICK7 + LOAD_DLL_FN (library, PixelSetPixelColor); +#else + LOAD_DLL_FN (library, PixelSetMagickColor); +#endif + LOAD_DLL_FN (library, PixelSetRed); + LOAD_DLL_FN (library, PixelSyncIterator); + + LOAD_DLL_FN (library, MagickSetSize); + LOAD_DLL_FN (library, MagickSetDepth); +#ifdef HAVE_MAGICKAUTOORIENTIMAGE + LOAD_DLL_FN (library, MagickAutoOrientImage); +#endif + + return 1; +} + +#undef CloneMagickWand +#undef DestroyMagickWand +#undef DestroyPixelIterator +#undef DestroyPixelWand +#undef MagickCropImage +#undef MagickExportImagePixels +#undef MagickFlattenImages +#undef MagickGetException +#undef MagickGetImage +#undef MagickGetImageDelay +#undef MagickGetImageDispose +#undef MagickGetImageHeight +#undef MagickGetImagePage +#undef MagickGetImageSignature +#undef MagickGetImageWidth +#undef MagickGetNumberImages +#undef MagickMergeImageLayers +#undef MagickQueryFormats +#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 PixelSetBlue +#undef PixelSetGreen +#undef PixelSetIteratorRow +#undef PixelSetMagickColor +#undef PixelSetPixelColor +#undef PixelSetRed +#undef PixelSyncIterator + +#undef MagickSetSize +#undef MagickSetDepth +#undef MagickAutoOrientImage + +#define CloneMagickWand fn_CloneMagickWand +#define DestroyMagickWand fn_DestroyMagickWand +#define DestroyPixelIterator fn_DestroyPixelIterator +#define DestroyPixelWand fn_DestroyPixelWand +#define MagickCropImage fn_MagickCropImage +#define MagickExportImagePixels fn_MagickExportImagePixels +#ifndef HAVE_MAGICKMERGEIMAGELAYERS +#define MagickFlattenImages fn_MagickFlattenImages +#endif +#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 MagickQueryFormats fn_MagickQueryFormats +#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 PixelSetBlue fn_PixelSetBlue +#define PixelSetGreen fn_PixelSetGreen +#define PixelSetIteratorRow fn_PixelSetIteratorRow +#ifdef HAVE_IMAGEMAGICK7 +#define PixelSetPixelColor fn_PixelSetPixelColor +#else +#define PixelSetMagickColor fn_PixelSetMagickColor +#endif +#define PixelSetRed fn_PixelSetRed +#define PixelSyncIterator fn_PixelSyncIterator + +#define MagickSetSize fn_MagickSetSize +#define MagickSetDepth fn_MagickSetDepth +#ifdef HAVE_MAGICKAUTOORIENTIMAGE +#define MagickAutoOrientImage fn_MagickAutoOrientImage +#endif + +# endif /* HAVE_NTGUI WINDOWSNT */ + +#ifdef HAVE_IMAGEMAGICK7 +/* ImageMagick 7 compatibility definitions. Redefine API functions + here, after the w32 runtime linking support code. */ +# define PixelSetMagickColor PixelSetPixelColor +#endif + + /* Log ImageMagick error message. Useful when an ImageMagick function returns the status `MagickFalse'. */ @@ -8411,7 +8660,7 @@ imagemagick_get_animation_cache (MagickWand *wand) pcache = &cache->next; } - DestroyString (signature); + MagickRelinquishMemory (signature); cache->update_time = current_timespec (); return cache; } @@ -8985,13 +9234,14 @@ and `imagemagick-types-inhibit'. */) { Lisp_Object typelist = Qnil; size_t numf = 0; - ExceptionInfo *ex; char **imtypes; size_t i; - ex = AcquireExceptionInfo (); - imtypes = GetMagickList ("*", &numf, ex); - DestroyExceptionInfo (ex); + if (imagemagick_type.init && !imagemagick_type.init ()) + return Qnil; + + MagickWandGenesis (); + imtypes = MagickQueryFormats ("*", &numf); for (i = 0; i < numf; i++) { @@ -9001,6 +9251,8 @@ and `imagemagick-types-inhibit'. */) } MagickRelinquishMemory (imtypes); + MagickWandTerminus (); + return Fnreverse (typelist); }
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.