From f7da82a416fd20e21ced3a913a6da011186ee05d Mon Sep 17 00:00:00 2001
From: David Maciejak <david.maciejak@gmail.com>
Date: Sat, 8 Mar 2014 11:02:08 +0800
Subject: [PATCH] wrlib: added support for imagemagick third-party lib

It uses to provide some missing common image format
like SVG, BMP, PICT, ...
---
 configure.ac          |   27 +++++++++++++++
 m4/wm_imgfmt_check.m4 |   20 +++++++++++
 src/dialog.c          |    8 +++--
 src/main.c            |    1 +
 wrlib/Makefile.am     |    4 +++
 wrlib/imgformat.h     |    9 +++--
 wrlib/libwraster.map  |    1 +
 wrlib/load.c          |   15 +++++++++
 wrlib/load_magick.c   |   89 +++++++++++++++++++++++++++++++++++++++++++++++++
 wrlib/wraster.h       |    4 +++
 10 files changed, 174 insertions(+), 4 deletions(-)
 create mode 100644 wrlib/load_magick.c

diff --git a/configure.ac b/configure.ac
index 8c29211..edc4b77 100644
--- a/configure.ac
+++ b/configure.ac
@@ -322,6 +322,11 @@ dnl ==========
 dnl AC_ARG_VAR(PKGCONFIG, [pkg-config command])
 AC_CHECK_PROG(PKGCONFIG, pkg-config, pkg-config) 
 
+dnl Magick-config
+dnl ==========
+dnl AC_ARG_VAR(MAGICKCONFIG, [Magick-config command])
+AC_CHECK_PROG(MAGICKCONFIG, Magick-config, Magick-config)
+
 dnl gettext
 dnl =======
 
@@ -559,6 +564,18 @@ else
 fi
 AC_SUBST(FCLIBS)
 
+dnl
+dnl libMagickWand
+dnl
+AC_MSG_CHECKING([for libmagickwand header])
+IMFLAGS=`$MAGICKCONFIG --cflags`
+if test "x$IMFLAGS" = "x" ; then
+        AC_MSG_RESULT([not found])
+else
+        AC_MSG_RESULT([found])
+fi
+AC_SUBST(IMFLAGS)
+
 
 dnl Xft2 antialiased font support
 dnl =============================
@@ -688,6 +705,16 @@ AC_ARG_ENABLE([webp],
     [enable_webp=auto])
 WM_IMGFMT_CHECK_WEBP
 
+dnl MAGICK Support
+dnl ===========
+AC_ARG_ENABLE([magick],
+    [AS_HELP_STRING([--disable-magick], [disable MAGICK support through libMagickWand])],
+    [AS_CASE(["$enableval"],
+        [yes|no], [],
+        [AC_MSG_ERROR([bad value $enableval for --enable-magick])] )],
+    [enable_magick=auto])
+WM_IMGFMT_CHECK_MAGICK
+
 dnl PPM Support
 dnl ===========
 # The PPM format is always enabled because we have built-in support for the format
diff --git a/m4/wm_imgfmt_check.m4 b/m4/wm_imgfmt_check.m4
index 0881cdd..b5f6eee 100644
--- a/m4/wm_imgfmt_check.m4
+++ b/m4/wm_imgfmt_check.m4
@@ -241,3 +241,23 @@ AC_DEFUN_ONCE([WM_IMGFMT_CHECK_WEBP],
      CFLAGS="$wm_save_CFLAGS"],
     [supported_gfx], [GFXLIBS])dnl
 ]) dnl AC_DEFUN
+
+# WM_IMGFMT_CHECK_MAGICK
+# -------------------
+#
+# Check for MAGICK file support through 'libMagickWand'
+# The check depends on variable 'enable_magick' being either:
+#   yes  - detect, fail if not found
+#   no   - do not detect, disable support
+#   auto - detect, disable if not found
+#
+# When not found, append info to variable 'unsupported'
+AC_DEFUN_ONCE([WM_IMGFMT_CHECK_MAGICK],
+[WM_LIB_CHECK([MAGICK], ["-lMagickWand"], [MagickGetImagePixels], [$XLFLAGS $XLIBS],
+    [wm_save_CFLAGS="$CFLAGS $IMFLAGS"
+     AS_IF([wm_fn_lib_try_compile "wand/magick_wand.h" "" "return 0" ""],
+         [],
+         [AC_MSG_ERROR([found $CACHEVAR but could not find appropriate header - are you missing libmagickwand package?])])
+     CFLAGS="$wm_save_CFLAGS"],
+    [supported_gfx], [GFXLIBS])dnl
+]) dnl AC_DEFUN
diff --git a/src/dialog.c b/src/dialog.c
index 221f6ac..6d5d21a 100644
--- a/src/dialog.c
+++ b/src/dialog.c
@@ -1278,7 +1278,7 @@ void wShowInfoPanel(WScreen *scr)
 	}
 #endif
 
-	strbuf = wstrappend(strbuf, _("Supported image formats: "));
+	strbuf = wstrappend(strbuf, _("Image formats: "));
 	strl = RSupportedFileFormats();
 	separator = NULL;
 	for (i = 0; strl[i] != NULL; i++) {
@@ -1303,6 +1303,10 @@ void wShowInfoPanel(WScreen *scr)
 	strbuf = wstrappend(strbuf, ", MWM");
 #endif
 
+#ifdef USE_MAGICK
+	strbuf = wstrappend(strbuf, ", ImageMagick");
+#endif
+
 #ifdef USE_XINERAMA
 	strbuf = wstrappend(strbuf, _("\n"));
 #ifdef SOLARIS_XINERAMA
@@ -1311,7 +1315,7 @@ void wShowInfoPanel(WScreen *scr)
 	strbuf = wstrappend(strbuf, _("Xinerama: "));
 	{
 		char tmp[128];
-		snprintf(tmp, sizeof(tmp) - 1, _("%d heads found."), scr->xine_info.count);
+		snprintf(tmp, sizeof(tmp) - 1, _("%d head(s) found."), scr->xine_info.count);
 		strbuf = wstrappend(strbuf, tmp);
 	}
 #endif
diff --git a/src/main.c b/src/main.c
index a21290e..bc14721 100644
--- a/src/main.c
+++ b/src/main.c
@@ -201,6 +201,7 @@ noreturn void Exit(int status)
 	if (dpy)
 		XCloseDisplay(dpy);
 
+	RShutdown(); /* wrlib clean exit */
 	wutil_shutdown();  /* WUtil clean-up */
 
 	exit(status);
diff --git a/wrlib/Makefile.am b/wrlib/Makefile.am
index 48af352..daf4a1f 100644
--- a/wrlib/Makefile.am
+++ b/wrlib/Makefile.am
@@ -64,6 +64,10 @@ if USE_WEBP
 libwraster_la_SOURCES += load_webp.c
 endif
 
+if USE_MAGICK
+libwraster_la_SOURCES += load_magick.c
+endif
+
 AM_CPPFLAGS = $(DFLAGS) @HEADER_SEARCH_PATH@
 
 libwraster_la_LIBADD = @LIBRARY_SEARCH_PATH@ @GFXLIBS@ @XLIBS@ @LIBXMU@ -lm
diff --git a/wrlib/imgformat.h b/wrlib/imgformat.h
index 43df3ec..0a44009 100644
--- a/wrlib/imgformat.h
+++ b/wrlib/imgformat.h
@@ -39,12 +39,13 @@ typedef enum {
 	IM_PPM     =  4,
 	IM_JPEG    =  5,
 	IM_GIF     =  6,
-	IM_WEBP    =  7
+	IM_WEBP    =  7,
+	IM_MAGICK  =  8
 } WRImgFormat;
 
 /* How many image types we have. */
 /* Increase this when adding new image types! */
-#define IM_TYPES    7
+#define IM_TYPES    8
 
 /*
  * Function for Loading in a specific format
@@ -73,6 +74,10 @@ RImage *RLoadGIF(const char *file, int index);
 RImage *RLoadWEBP(const char *file);
 #endif
 
+#ifdef USE_MAGICK
+RImage *RLoadMagick(const char *file_name);
+ #endif
+
 /*
  * Function for Saving in a specific format
  */
diff --git a/wrlib/libwraster.map b/wrlib/libwraster.map
index 6282e2c..6e165ef 100644
--- a/wrlib/libwraster.map
+++ b/wrlib/libwraster.map
@@ -72,6 +72,7 @@ LIBWRASTER3
     RRotateImage;
     RSaveImage;
     RScaleImage;
+    RShutdown;
     RSmoothScaleImage;
     RSupportedFileFormats;
 
diff --git a/wrlib/load.c b/wrlib/load.c
index fb785d7..8e0d34d 100644
--- a/wrlib/load.c
+++ b/wrlib/load.c
@@ -105,6 +105,13 @@ char **RSupportedFileFormats(void)
 	return tmp;
 }
 
+/* cleaning third-party libs at shutdown */
+void RShutdown() {
+#ifdef USE_MAGICK
+	MagickWandTerminus();
+#endif
+}
+
 static void init_cache(void)
 {
 	char *tmp;
@@ -167,8 +174,16 @@ RImage *RLoadImage(RContext * context, const char *file, int index)
 		return NULL;
 
 	case IM_UNKNOWN:
+#ifdef USE_MAGICK
+		/* generic file format support using ImageMagick
+		 * BMP, PCX, PICT, SVG, ...
+		*/
+		image = RLoadMagick(file);
+		break;
+#else
 		RErrorCode = RERR_BADFORMAT;
 		return NULL;
+#endif
 
 	case IM_XPM:
 		image = RLoadXPM(context, file);
diff --git a/wrlib/load_magick.c b/wrlib/load_magick.c
new file mode 100644
index 0000000..d9ecb2d
--- /dev/null
+++ b/wrlib/load_magick.c
@@ -0,0 +1,89 @@
+/* load_magick.c - load image file using ImageMagick
+ *
+ * Raster graphics library
+ *
+ * Copyright (c) 2014 Window Maker Team
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *  MA 02110-1301, USA.
+ */
+
+#include <config.h>
+#include <X11/Xlib.h>
+
+#include <wand/magick_wand.h>
+
+#include "wraster.h"
+#include "imgformat.h"
+
+RImage * RLoadMagick(const char *file_name)
+{
+	RImage *image = NULL;
+	unsigned char *ptr;
+	unsigned long w,h;
+	MagickWand *m_wand = NULL;
+	MagickBooleanType mrc;
+	MagickBooleanType hasAlfa;
+	PixelWand *bg_wand = NULL;
+
+	MagickWandGenesis();
+
+	/* Create a wand */
+	m_wand = NewMagickWand();
+
+	/* set the default background as transparent */
+	bg_wand = NewPixelWand ();
+	PixelSetColor(bg_wand, "none");
+	MagickSetBackgroundColor(m_wand, bg_wand);
+
+	/* Read the input image */
+	if (!MagickReadImage(m_wand, file_name)) {
+		RErrorCode = RERR_BADIMAGEFILE;
+		goto bye;
+	}
+
+	w = MagickGetImageWidth(m_wand);
+	h = MagickGetImageHeight(m_wand);
+	//fprintf(stderr, "%lu x %lu\n", w,h);
+
+	hasAlfa = MagickGetImageAlphaChannel(m_wand);
+
+	image = RCreateImage(w, h, (unsigned int) hasAlfa);
+	if (!image) {
+		RErrorCode = RERR_NOMEMORY;
+		goto bye;
+	}
+
+	ptr = image->data;
+	if (hasAlfa == MagickTrue)
+		mrc = MagickExportImagePixels(m_wand, 0, 0, (size_t)w, (size_t)h, "RGBA", CharPixel, ptr);
+	else
+		mrc = MagickExportImagePixels(m_wand, 0, 0, (size_t)w, (size_t)h, "RGB", CharPixel, ptr);
+
+	if (mrc == MagickFalse) {
+		RErrorCode = RERR_BADIMAGEFILE;
+		RReleaseImage(image);
+		goto bye;
+	}
+
+bye:
+	/* Tidy up */
+	MagickClearException(m_wand);
+	m_wand = DestroyMagickWand(m_wand);
+	/* destroy is called when exiting wmaker */
+	/* MagickWandTerminus(); */
+
+	return image;
+}
diff --git a/wrlib/wraster.h b/wrlib/wraster.h
index 25e39e7..c4ed231 100644
--- a/wrlib/wraster.h
+++ b/wrlib/wraster.h
@@ -431,7 +431,11 @@ RImage *RRenderMultiGradient(unsigned width, unsigned height, RColor **colors,
 RImage *RRenderInterwovenGradient(unsigned width, unsigned height,
                                   RColor colors1[2], int thickness1,
                                   RColor colors2[2], int thickness2);
+/*
+ * Cleaning
+ */
 
+void RShutdown();
 
 /*
  * Convertion into X Pixmaps
-- 
1.7.10.4

