diff --git a/ChangeLog b/ChangeLog index 22323acc2..6661c5d56 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-06-28 Eric Wasylishen + + * Headers/Additions/GNUstepGUI/GSImageMagickImageRep.h: + * Source/GNUmakefile: + * Source/NSImageRep.m: + * Source/GSImageMagickImageRep.m: + * configure.ac: New ImageMagick-based NSBitmapImageRep subclass + 2011-06-28 Fred Kiefer * Source/GSDragView.m (-init): Set the window background colour to clear. diff --git a/Headers/Additions/GNUstepGUI/GSImageMagickImageRep.h b/Headers/Additions/GNUstepGUI/GSImageMagickImageRep.h new file mode 100644 index 000000000..b70b28429 --- /dev/null +++ b/Headers/Additions/GNUstepGUI/GSImageMagickImageRep.h @@ -0,0 +1,42 @@ +/* + GSImageMagickImageRep.h + + Ghostscript image representation. + + Copyright (C) 2011 Free Software Foundation, Inc. + + Written by: Eric Wasylishen + Date: June 2011 + + This file is part of the GNUstep GUI Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _GNUstep_H_GSImageMagickImageRep +#define _GNUstep_H_GSImageMagickImageRep + +#import + +@interface GSImageMagickImageRep : NSBitmapImageRep +{ +} + +@end + +#endif // _GNUstep_H_GSImageMagickImageRep + diff --git a/Headers/Additions/GNUstepGUI/config.h.in b/Headers/Additions/GNUstepGUI/config.h.in index ac91dd1ee..6573fe857 100644 --- a/Headers/Additions/GNUstepGUI/config.h.in +++ b/Headers/Additions/GNUstepGUI/config.h.in @@ -24,6 +24,9 @@ /* Define to 1 if you have the `getmntinfo' function. */ #undef HAVE_GETMNTINFO +/* Have ImageMagick */ +#undef HAVE_IMAGEMAGICK + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -48,9 +51,6 @@ /* Define to 1 if you have the `png' library (-lpng). */ #undef HAVE_LIBPNG -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBPNG_PNG_H - /* Define to 1 if you have the `tiff' library (-ltiff). */ #undef HAVE_LIBTIFF @@ -66,6 +66,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MNTENT_H +/* Define to 1 if you have the header file. */ +#undef HAVE_PNG_H + /* Define to 1 if you have the `rint' function. */ #undef HAVE_RINT diff --git a/Source/GNUmakefile b/Source/GNUmakefile index 94c82fead..cbc3a55ce 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -215,6 +215,7 @@ GSHorizontalTypesetter.m \ GSGhostscriptImageRep.m \ GSGormLoading.m \ GSIconManager.m \ +GSImageMagickImageRep.m \ GSNibLoading.m \ GSTheme.m \ GSThemeDrawing.m \ diff --git a/Source/GSImageMagickImageRep.m b/Source/GSImageMagickImageRep.m new file mode 100644 index 000000000..be5596aef --- /dev/null +++ b/Source/GSImageMagickImageRep.m @@ -0,0 +1,255 @@ +/** GSImageMagickImageRep + + ImageMagick image representation. + + Copyright (C) 2011 Free Software Foundation, Inc. + + Author: Eric Wasylishen + Date: June 2011 + + This file is part of the GNUstep Application Kit Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#import "config.h" + +#import +#import +#import +#import +#import +#import +#import "AppKit/NSBitmapImageRep.h" +#import "AppKit/NSGraphics.h" +#import "AppKit/NSPasteboard.h" +#import "AppKit/NSGraphicsContext.h" +#import "GNUstepGUI/GSImageMagickImageRep.h" + +#if HAVE_IMAGEMAGICK + +#include + +@implementation GSImageMagickImageRep + ++ (void) initialize +{ + NSArray *argv = [[NSProcessInfo processInfo] arguments]; + + MagickCoreGenesis([[argv objectAtIndex: 0] UTF8String], 0); +} + +// Private methods + ++ (NSBitmapImageRep *) imageRepWithImageMagickImage: (Image *)image +{ + ExceptionInfo *exception = AcquireExceptionInfo(); + MagickBooleanType success; + + NSBitmapImageRep *bmp = [[[self alloc] + initWithBitmapDataPlanes: NULL + pixelsWide: image->columns + pixelsHigh: image->rows + bitsPerSample: 8 + samplesPerPixel: 4 + hasAlpha: YES + isPlanar: NO + colorSpaceName: NSDeviceRGBColorSpace + bitmapFormat: NSAlphaNonpremultipliedBitmapFormat + bytesPerRow: image->columns * 4 + bitsPerPixel: 32] autorelease]; + + // Set the resolution metadata + + if (image->units == PixelsPerInchResolution || + image->units == PixelsPerCentimeterResolution) + { + NSSize res; + if (image->units == PixelsPerCentimeterResolution) + { + res = NSMakeSize(image->x_resolution * 2.54, image->y_resolution * 2.54); + } + else + { + res = NSMakeSize(image->x_resolution, image->y_resolution); + } + + if (res.width > 0 && res.height > 0) + { + const NSSize sizeInPoints = NSMakeSize(((CGFloat)image->columns / res.width) * 72.0, + ((CGFloat)image->rows / res.height) * 72.0); + [bmp setSize: sizeInPoints]; + } + } + + // Copy the pixel data to the NSBitmapImageRep + + success = ExportImagePixels(image, 0, 0, image->columns, image->rows, + "RGBA", CharPixel, [bmp bitmapData], exception); + if (!success || exception->severity != UndefinedException) + { + bmp = nil; + } + + DestroyExceptionInfo(exception); + + return bmp; +} + ++ (NSArray*) imageRepsWithData: (NSData *)data allImages: (BOOL)allImages +{ + NSMutableArray *reps = [NSMutableArray array]; + + ExceptionInfo *exception = AcquireExceptionInfo(); + ImageInfo *imageinfo = CloneImageInfo(NULL); + Image *images, *image; + + // Set the background color to transparent + // (otherwise SVG's are rendered against a white background by default) + QueryColorDatabase("none", &imageinfo->background_color, exception); + + images = BlobToImage(imageinfo, [data bytes], [data length], exception); + + if (exception->severity == UndefinedException) + { + for (image = images; image != NULL; image = image->next) + { + NSBitmapImageRep *bmp = [[self class] imageRepWithImageMagickImage: image]; + if (bmp != nil) + { + [reps addObject: bmp]; + } + + if (!allImages) + { + break; + } + } + } + + DestroyExceptionInfo(exception); + DestroyImageInfo(imageinfo); + DestroyImage(images); + + return reps; +} + +// NSImageRep overrides + ++ (BOOL) canInitWithData: (NSData *)data +{ + char buf[32]; + ExceptionInfo *exception; + const MagicInfo *info; + + memset(buf, 0, 32); + [data getBytes: buf length: 32]; + + exception = AcquireExceptionInfo(); + info = GetMagicInfo((const unsigned char *)buf, 32, exception); + DestroyExceptionInfo(exception); + + return (info != NULL); +} + ++ (NSArray *) imageUnfilteredFileTypes +{ + static NSArray *types = nil; + + if (types == nil) + { + NSMutableArray *array = [NSMutableArray array]; + size_t size = 0; + ExceptionInfo *exception = AcquireExceptionInfo(); + const MagickInfo **list = GetMagickInfoList("*", &size, exception); + size_t i; + + for (i=0; iname] lowercaseString]]; + } + RelinquishMagickMemory(list); + DestroyExceptionInfo(exception); + + types = [[NSArray alloc] initWithArray: array]; + } + + return types; +} + ++ (NSArray *) imageUnfilteredPasteboardTypes +{ + static NSArray *types = nil; + + if (types == nil) + { + NSMutableArray *array = [NSMutableArray array]; + NSDictionary *fileTypeToPboardType = [NSDictionary dictionaryWithObjectsAndKeys: + NSPostScriptPboardType, @"ps", + NSPDFPboardType, @"pdf", + NSPICTPboardType, @"pict", + NSTIFFPboardType, @"tiff", + nil]; + + NSEnumerator *enumerator = [[self imageUnfilteredFileTypes] objectEnumerator]; + NSString *fileType; + while (nil != (fileType = [enumerator nextObject])) + { + NSString *pboardType = [fileTypeToPboardType objectForKey: fileType]; + if (pboardType != nil) + { + [array addObject: pboardType]; + } + } + + types = [[NSArray alloc] initWithArray: array]; + } + + return types; +} + +// NSBitmapImageRep overrides + ++ (id) imageRepWithData: (NSData *)data +{ + return [[[self alloc] initWithData: data] autorelease]; +} + +- (id) initWithData: (NSData *)data +{ + NSArray *reps = [[self class] imageRepsWithData: data allImages: NO]; + + [self release]; + + if ([reps count] != 0) + { + return [[reps objectAtIndex: 0] retain]; + } + else + { + return nil; + } +} + ++ (NSArray *) imageRepsWithData: (NSData *)data +{ + return [self imageRepsWithData: data allImages: YES]; +} + +@end + +#endif diff --git a/Source/NSImageRep.m b/Source/NSImageRep.m index 98a11953b..1b05d2f8f 100644 --- a/Source/NSImageRep.m +++ b/Source/NSImageRep.m @@ -45,6 +45,7 @@ #import "AppKit/NSColor.h" #import "AppKit/DPSOperators.h" #import "GNUstepGUI/GSGhostscriptImageRep.h" +#import "GNUstepGUI/GSImageMagickImageRep.h" static NSMutableArray *imageReps = nil; static Class NSImageRep_class = NULL; @@ -58,9 +59,12 @@ static Class NSImageRep_class = NULL; if (self == [NSImageRep class]) { NSImageRep_class = self; - imageReps = [[NSMutableArray alloc] initWithCapacity: 2]; + imageReps = [[NSMutableArray alloc] initWithCapacity: 4]; [imageReps addObject: [NSBitmapImageRep class]]; [imageReps addObject: [GSGhostscriptImageRep class]]; +#if HAVE_IMAGEMAGICK + [imageReps addObject: [GSImageMagickImageRep class]]; +#endif } } diff --git a/configure b/configure index 122ae5faa..5ae57fc90 100755 --- a/configure +++ b/configure @@ -609,6 +609,11 @@ GSCUPS_CFLAGS have_cups BUILD_SPEECH BUILD_SOUND +IMAGEMAGICK_LIBS +IMAGEMAGICK_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG HAVE_LIBPNG_CONFIG EGREP GREP @@ -685,6 +690,7 @@ with_tiff_include enable_png enable_ungif enable_libgif +enable_imagemagick enable_aspell enable_sound enable_speech @@ -699,7 +705,12 @@ CFLAGS LDFLAGS LIBS CPPFLAGS -CPP' +CPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +IMAGEMAGICK_CFLAGS +IMAGEMAGICK_LIBS' # Initialize some variables set by options. @@ -1322,6 +1333,7 @@ Optional Features: --disable-png Disable PNG support --disable-ungif Disable libungif-based GIF support --enable-libgif Enable libgif-based GIF support + --disable-imagemagick Disable ImageMagick support --disable-aspell Disable aspell for spellchecker --disable-sound Disable sound --disable-speech Disable speech server @@ -1348,6 +1360,15 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + IMAGEMAGICK_CFLAGS + C compiler flags for IMAGEMAGICK, overriding pkg-config + IMAGEMAGICK_LIBS + linker flags for IMAGEMAGICK, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -5395,6 +5416,220 @@ $as_echo "$as_me: -gui will be linked against -lX11 to support libgif images" >& fi fi +#-------------------------------------------------------------------- +# Find ImageMagick +#-------------------------------------------------------------------- + +# Check whether --enable-imagemagick was given. +if test "${enable_imagemagick+set}" = set; then : + enableval=$enable_imagemagick; +else + enable_imagemagick=yes +fi + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi +if test "$enable_imagemagick" = "yes"; then : + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for IMAGEMAGICK" >&5 +$as_echo_n "checking for IMAGEMAGICK... " >&6; } + +if test -n "$IMAGEMAGICK_CFLAGS"; then + pkg_cv_IMAGEMAGICK_CFLAGS="$IMAGEMAGICK_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"MagickCore\""; } >&5 + ($PKG_CONFIG --exists --print-errors "MagickCore") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_IMAGEMAGICK_CFLAGS=`$PKG_CONFIG --cflags "MagickCore" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$IMAGEMAGICK_LIBS"; then + pkg_cv_IMAGEMAGICK_LIBS="$IMAGEMAGICK_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"MagickCore\""; } >&5 + ($PKG_CONFIG --exists --print-errors "MagickCore") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_IMAGEMAGICK_LIBS=`$PKG_CONFIG --libs "MagickCore" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + IMAGEMAGICK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "MagickCore" 2>&1` + else + IMAGEMAGICK_PKG_ERRORS=`$PKG_CONFIG --print-errors "MagickCore" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$IMAGEMAGICK_PKG_ERRORS" >&5 + + +$as_echo "#define HAVE_IMAGEMAGICK 0" >>confdefs.h + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "#define HAVE_IMAGEMAGICK 0" >>confdefs.h + +else + IMAGEMAGICK_CFLAGS=$pkg_cv_IMAGEMAGICK_CFLAGS + IMAGEMAGICK_LIBS=$pkg_cv_IMAGEMAGICK_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + GRAPHIC_CFLAGS="$IMAGEMAGICK_CFLAGS $GRAPHIC_CFLAGS" + GRAPHIC_LFLAGS="$IMAGEMAGICK_LIBS $GRAPHIC_LFLAGS" + +$as_echo "#define HAVE_IMAGEMAGICK 1" >>confdefs.h + + +fi + +fi + #-------------------------------------------------------------------- # Check for the spelling lib, for the built-in spell checker... # Note: you might want to disable aspell on MacOSX, as it linkes in diff --git a/configure.ac b/configure.ac index 86d2d5564..b75d9ef50 100644 --- a/configure.ac +++ b/configure.ac @@ -351,6 +351,23 @@ if test "$have_ungif" = no -o "${enable_libgif}" = yes; then fi fi +#-------------------------------------------------------------------- +# Find ImageMagick +#-------------------------------------------------------------------- + +AC_ARG_ENABLE(imagemagick, + [ --disable-imagemagick Disable ImageMagick support],, + enable_imagemagick=yes) +AS_IF([test "$enable_imagemagick" = "yes"], [ + PKG_CHECK_MODULES([IMAGEMAGICK], [MagickCore], + [ + GRAPHIC_CFLAGS="$IMAGEMAGICK_CFLAGS $GRAPHIC_CFLAGS" + GRAPHIC_LFLAGS="$IMAGEMAGICK_LIBS $GRAPHIC_LFLAGS" + AC_DEFINE([HAVE_IMAGEMAGICK], [1], [Have ImageMagick]) + ], + [AC_DEFINE([HAVE_IMAGEMAGICK], [0], [Don't have ImageMagick])]) +]) + #-------------------------------------------------------------------- # Check for the spelling lib, for the built-in spell checker... # Note: you might want to disable aspell on MacOSX, as it linkes in