diff --git a/configure.ac b/configure.ac index a0aca45a..3d42c610 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 MagickWand-config +dnl ========== +dnl AC_ARG_VAR(MAGICKWCONFIG, [MagickWand-config command]) +AC_CHECK_PROG(MAGICKWCONFIG, MagickWand-config, MagickWand-config) + dnl gettext dnl ======= @@ -559,6 +564,26 @@ else fi AC_SUBST(FCLIBS) +dnl +dnl libMagickWand +dnl +AC_MSG_CHECKING([for libmagickwand header]) +IMFLAGS=`$MAGICKWCONFIG --cflags` +if test "x$IMFLAGS" = "x" ; then + AC_MSG_RESULT([not found]) +else + AC_MSG_RESULT([found]) +fi +AC_SUBST(IMFLAGS) + +AC_MSG_CHECKING([for libmagickwand library]) +IMLIBS=`$MAGICKWCONFIG --ldflags` +if test "x$IMLIBS" = "x" ; then + AC_MSG_RESULT([not found]) +else + AC_MSG_RESULT([found]) +fi +AC_SUBST(IMLIBS) dnl Xft2 antialiased font support dnl ============================= @@ -690,6 +715,17 @@ AC_ARG_ENABLE([webp], 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 ad37993a..af43f717 100644 --- a/m4/wm_imgfmt_check.m4 +++ b/m4/wm_imgfmt_check.m4 @@ -244,3 +244,26 @@ AS_IF([test "x$enable_xpm" = "xno"], ]) AM_CONDITIONAL([USE_XPM], [test "x$enable_xpm" != "xno"])dnl ]) dnl AC_DEFUN + + +# WM_IMGFMT_CHECK_MAGICK +# ---------------------- +# +# Check for MagickWand library to support more image file formats +# 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 found, store the appropriate compilation flags in MAGICKFLAGS +# and MAGICKLIBS, and append info to the variable 'supported_gfx' +# When not found, append info to variable 'unsupported' +AC_DEFUN_ONCE([WM_IMGFMT_CHECK_MAGICK], +[WM_LIB_CHECK([MAGICK], ["$IMLIBS"], [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 1341af8c..541bd748 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -1297,6 +1297,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 diff --git a/src/main.c b/src/main.c index a21290e5..bc147216 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 48af352a..daf4a1ff 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 43df3ec9..f60c9659 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 6282e2c4..6e165ef0 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 641cfae6..df0ae9ff 100644 --- a/wrlib/load.c +++ b/wrlib/load.c @@ -103,6 +103,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; @@ -165,8 +172,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 00000000..397ed34d --- /dev/null +++ b/wrlib/load_magick.c @@ -0,0 +1,88 @@ +/* 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 + +#include + +#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); + + 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 */ + DestroyPixelWand(bg_wand); + MagickClearException(m_wand); + m_wand = DestroyMagickWand(m_wand); + + return image; +} diff --git a/wrlib/wraster.h b/wrlib/wraster.h index 25e39e79..c4ed2310 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