From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Andy Moreton Newsgroups: gmane.emacs.bugs Subject: bug#25967: [PATCH] Add support for ImageMagick 7 (Bug#25967) Date: Mon, 03 Sep 2018 23:57:05 +0100 Message-ID: <86wos25gvy.fsf@gmail.com> References: <6a48dc20-17fc-4e4b-b793-4c37c6bcbcc5@Spark> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1536015377 7432 195.159.176.226 (3 Sep 2018 22:56:17 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 3 Sep 2018 22:56:17 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1.50 (windows-nt) To: 25967@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Sep 04 00:56:12 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fwxlR-0001ie-Qn for geb-bug-gnu-emacs@m.gmane.org; Tue, 04 Sep 2018 00:56:10 +0200 Original-Received: from localhost ([::1]:47247 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fwxnY-00075C-6e for geb-bug-gnu-emacs@m.gmane.org; Mon, 03 Sep 2018 18:58:20 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:41280) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fwxnK-00074i-UE for bug-gnu-emacs@gnu.org; Mon, 03 Sep 2018 18:58:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fwxnG-0005oR-OO for bug-gnu-emacs@gnu.org; Mon, 03 Sep 2018 18:58:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:39715) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fwxnG-0005o8-G8 for bug-gnu-emacs@gnu.org; Mon, 03 Sep 2018 18:58:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1fwxnG-0001nh-AE for bug-gnu-emacs@gnu.org; Mon, 03 Sep 2018 18:58:02 -0400 X-Loop: help-debbugs@gnu.org In-Reply-To: <6a48dc20-17fc-4e4b-b793-4c37c6bcbcc5@Spark> Resent-From: Andy Moreton Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 03 Sep 2018 22:58:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 25967 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.15360154526875 (code B ref -1); Mon, 03 Sep 2018 22:58:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 3 Sep 2018 22:57:32 +0000 Original-Received: from localhost ([127.0.0.1]:44733 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fwxml-0001mo-00 for submit@debbugs.gnu.org; Mon, 03 Sep 2018 18:57:31 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:48280) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fwxmi-0001mY-Rh for submit@debbugs.gnu.org; Mon, 03 Sep 2018 18:57:29 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fwxmb-0005Xq-Ps for submit@debbugs.gnu.org; Mon, 03 Sep 2018 18:57:23 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:55567) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fwxmb-0005Xf-L8 for submit@debbugs.gnu.org; Mon, 03 Sep 2018 18:57:21 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:41022) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fwxmZ-0006Hy-Vu for bug-gnu-emacs@gnu.org; Mon, 03 Sep 2018 18:57:21 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fwxmV-0005VM-Sg for bug-gnu-emacs@gnu.org; Mon, 03 Sep 2018 18:57:19 -0400 Original-Received: from [195.159.176.226] (port=53619 helo=blaine.gmane.org) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fwxmV-0005UY-G9 for bug-gnu-emacs@gnu.org; Mon, 03 Sep 2018 18:57:15 -0400 Original-Received: from list by blaine.gmane.org with local (Exim 4.84_2) (envelope-from ) id 1fwxkL-0008Rt-4X for bug-gnu-emacs@gnu.org; Tue, 04 Sep 2018 00:55:01 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 369 Original-X-Complaints-To: usenet@blaine.gmane.org Cancel-Lock: sha1:Rt168fYDYxD1CMoePN5vYKqYGdk= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:150000 Archived-At: --=-=-= Content-Type: text/plain 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 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=imagemagick7.patch 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 # include -/* 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 @@ -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); } --=-=-=--