From: Joakim Verona Date: Tue, 17 Aug 2010 21:19:11 +0000 (+0200) Subject: merge from trunk X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~438^2~45^2~511^2~35 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a8101f663e6cbff953b67b8bef33bc0171818477;p=emacs.git merge from trunk --- a8101f663e6cbff953b67b8bef33bc0171818477 diff --cc configure index d1f5f6cde78,3eaf150a25e..b9f9337c6e2 --- a/configure +++ b/configure @@@ -2666,10 -2675,11 +2672,11 @@@ if test "${with_x_toolkit+set}" = set; a | at | ath | athe | athen | athena ) val=athena ;; m | mo | mot | moti | motif ) val=motif ;; g | gt | gtk ) val=gtk ;; + gtk3 ) val=gtk3 ;; * ) -as_fn_error $? "\`--with-x-toolkit=$withval' is invalid; +as_fn_error "\`--with-x-toolkit=$withval' is invalid; - this option's value should be \`yes', \`no', \`lucid', \`athena', \`motif' or \`gtk'. - \`yes' and \`gtk' are synonyms. \`athena' and \`lucid' are synonyms." "$LINENO" 5 + this option's value should be \`yes', \`no', \`lucid', \`athena', \`motif', \`gtk' or + \`gtk3'. \`yes' and \`gtk' are synonyms. \`athena' and \`lucid' are synonyms." "$LINENO" 5 ;; esac with_x_toolkit=$val @@@ -7015,7 -7026,229 +7029,229 @@@ els fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 + $as_echo_n "checking whether byte ordering is bigendian... " >&6; } + if test "${ac_cv_c_bigendian+set}" = set; then : + $as_echo_n "(cached) " >&6 + else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + #ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + + _ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + #include + #include + + int + main () + { + #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; + } + _ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + #include + #include + + int + main () + { + #if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; + } + _ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes + else + ac_cv_c_bigendian=no + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + #include + + int + main () + { + #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; + } + _ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + #include + + int + main () + { + #ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; + } + _ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes + else + ac_cv_c_bigendian=no + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + + int + main () + { + return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; + } + _ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + $ac_includes_default + int + main () + { + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; + } + _ACEOF + if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no + else + ac_cv_c_bigendian=yes + fi + rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + + fi + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 + $as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h + ;; #( + no) + ;; #( + universal) + + $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + ;; #( + *) - as_fn_error $? "unknown endianness ++ as_fn_error "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 @@@ -8485,6 -8613,112 +8752,112 @@@ f HAVE_GTK=no + if test "${with_gtk3}" = "yes"; then + GLIB_REQUIRED=2.6 + GTK_REQUIRED=2.90 + GTK_MODULES="gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED" + + + succeeded=no + + # 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_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 + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; + 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 + + + + if test "$PKG_CONFIG" = "no" ; then + pkg_check_gtk=no + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $GTK_MODULES" >&5 + $as_echo_n "checking for $GTK_MODULES... " >&6; } + + if $PKG_CONFIG --exists "$GTK_MODULES" 2>&5; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + $as_echo "yes" >&6; } + succeeded=yes + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking GTK_CFLAGS" >&5 + $as_echo_n "checking GTK_CFLAGS... " >&6; } + GTK_CFLAGS=`$PKG_CONFIG --cflags "$GTK_MODULES"|sed -e 's,///*,/,g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTK_CFLAGS" >&5 + $as_echo "$GTK_CFLAGS" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking GTK_LIBS" >&5 + $as_echo_n "checking GTK_LIBS... " >&6; } + GTK_LIBS=`$PKG_CONFIG --libs "$GTK_MODULES"|sed -e 's,///*,/,g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTK_LIBS" >&5 + $as_echo "$GTK_LIBS" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + $as_echo "no" >&6; } + GTK_CFLAGS="" + GTK_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + GTK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$GTK_MODULES"` + + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + pkg_check_gtk=yes + else + pkg_check_gtk=no + fi + + if test "$pkg_check_gtk" = "no" && test "$USE_X_TOOLKIT" != "maybe"; then - as_fn_error $? "$GTK_PKG_ERRORS" "$LINENO" 5 ++ as_fn_error "$GTK_PKG_ERRORS" "$LINENO" 5 + fi + fi + + if test "$pkg_check_gtk" != "yes"; then + HAVE_GTK=no if test "${with_gtk}" = "yes" || test "$USE_X_TOOLKIT" = "maybe"; then GLIB_REQUIRED=2.6 GTK_REQUIRED=2.6 @@@ -8585,10 -8819,10 +8958,10 @@@ $as_echo "no" >&6; fi if test "$pkg_check_gtk" = "no" && test "$USE_X_TOOLKIT" != "maybe"; then - as_fn_error $? "$GTK_PKG_ERRORS" "$LINENO" 5 + as_fn_error "$GTK_PKG_ERRORS" "$LINENO" 5 fi fi - + fi GTK_OBJ= if test x"$pkg_check_gtk" = xyes; then @@@ -8788,7 -8968,23 +9107,24 @@@ f $as_echo "#define HAVE_GTK_AND_PTHREAD 1" >>confdefs.h fi - fi + + for ac_func in gtk_widget_get_window gtk_widget_set_has_window \ + gtk_dialog_get_action_area gtk_widget_get_sensitive \ + gtk_widget_get_mapped gtk_adjustment_get_page_size \ + gtk_orientable_set_orientation + do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` + ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : ++eval as_val=\$$as_ac_var ++ if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF + #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 + _ACEOF + + fi + done + + fi HAVE_DBUS=no diff --cc configure.in index 15bdaf01f4f,ada0b189d3c..c989b0358ab --- a/configure.in +++ b/configure.in @@@ -1841,27 -1837,22 +1838,41 @@@ if test "${HAVE_X11}" = "yes" || test " fi fi +HAVE_IMAGEMAGICK=no +if test "${with_imagemagick}" != "no"; then + IMAGEMAGICK_MODULE="Wand" + PKG_CHECK_MODULES(IMAGEMAGICK, $IMAGEMAGICK_MODULE, :, :) + AC_SUBST(IMAGEMAGICK_CFLAGS) + AC_SUBST(IMAGEMAGICK_LIBS) + + if test ".${IMAGEMAGICK_CFLAGS}" != "."; then + HAVE_IMAGEMAGICK=yes + AC_DEFINE(HAVE_IMAGEMAGICK, 1, [Define to 1 if using imagemagick.]) + CFLAGS="$CFLAGS $IMAGEMAGICK_CFLAGS" + LIBS="$IMAGEMAGICK_LIBS $LIBS" + fi + + AC_DEFINE(HAVE_MAGICKEXPORTIMAGEPIXELS, 1, [Define to 1 if MagickExportImagePixels is defined.]) + AC_CHECK_FUNCS_ONCE(MagickExportImagePixels) + +fi + HAVE_GTK=no + if test "${with_gtk3}" = "yes"; then + GLIB_REQUIRED=2.6 + GTK_REQUIRED=2.90 + GTK_MODULES="gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED" + + dnl Checks for libraries. + PKG_CHECK_MODULES(GTK, $GTK_MODULES, pkg_check_gtk=yes, pkg_check_gtk=no) + if test "$pkg_check_gtk" = "no" && test "$USE_X_TOOLKIT" != "maybe"; then + AC_MSG_ERROR($GTK_PKG_ERRORS) + fi + fi + + if test "$pkg_check_gtk" != "yes"; then + HAVE_GTK=no if test "${with_gtk}" = "yes" || test "$USE_X_TOOLKIT" = "maybe"; then GLIB_REQUIRED=2.6 GTK_REQUIRED=2.6 diff --cc src/Makefile.in index fd95fe6d280,a8d400c7c39..9ee5631ef70 --- a/src/Makefile.in +++ b/src/Makefile.in @@@ -313,9 -315,10 +320,10 @@@ MKDEPDIR=@MKDEPDIR ## FIXME? MYCPPFLAGS only referenced in etc/DEBUG. ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} \ ${C_SWITCH_MACHINE} ${C_SWITCH_SYSTEM} ${C_SWITCH_X_SITE} \ - ${C_SWITCH_X_SYSTEM} ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} \ + ${C_SWITCH_X_SYSTEM} ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${IMAGEMAGICK_CFLAGS} ${DBUS_CFLAGS} \ - ${GCONF_CFLAGS} ${CFLAGS} ${FREETYPE_CFLAGS} ${FONTCONFIG_CFLAGS} \ - ${LIBOTF_CFLAGS} ${M17N_FLT_CFLAGS} ${DEPFLAGS} + ${GCONF_CFLAGS} ${FREETYPE_CFLAGS} ${FONTCONFIG_CFLAGS} \ + ${LIBOTF_CFLAGS} ${M17N_FLT_CFLAGS} ${DEPFLAGS} ${PROFILING_CFLAGS} \ + ${C_WARNINGS_SWITCH} ${CFLAGS} ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS) .SUFFIXES: .m diff --cc src/config.in index 5fb97662583,ea17a54d913..604a737a8b0 --- a/src/config.in +++ b/src/config.in @@@ -285,12 -294,6 +294,9 @@@ along with GNU Emacs. If not, see + +/* imagemagick_load_image is a helper function for imagemagick_load, + which does the actual loading given contents and size, apart from + frame and image structures, passed from imagemagick_load. + + Uses librimagemagick to do most of the image processing. + + non-zero when successful. +*/ + +static int +imagemagick_load_image (/* Pointer to emacs frame structure. */ + struct frame *f, + /* Pointer to emacs image structure. */ + struct image *img, + /* String containing the IMAGEMAGICK data to + be parsed. */ + unsigned char *contents, + /* Size of data in bytes. */ + unsigned int size, + /* Filename, either pass filename or + contents/size. */ + unsigned char *filename) +{ - long unsigned int width; - long unsigned int height; ++ size_t width; ++ size_t height; + + MagickBooleanType + status; + + XImagePtr ximg; + Lisp_Object specified_bg; + XColor background; + int x; + int y; + + MagickWand *image_wand; + MagickWand *ping_wand; + PixelIterator *iterator; + PixelWand **pixels; + MagickPixelPacket pixel; + Lisp_Object image; + Lisp_Object value; + Lisp_Object crop, geometry; + long ino; + int desired_width, desired_height; + double rotation; + int imagemagick_rendermethod; + int pixelwidth; + ImageInfo *image_info; + ExceptionInfo *exception; + Image * im_image; + + + /* Handle image index for image types who can contain more than one + image. Interface :index is same as for GIF. First we "ping" the + image to see how many sub-images it contains. Pinging is faster + than loading the image to find out things about it. + */ + printf("im ping file %s\n", filename); + image = image_spec_value (img->spec, QCindex, NULL); + ino = INTEGERP (image) ? XFASTINT (image) : 0; + ping_wand=NewMagickWand(); + MagickSetResolution(ping_wand, 2, 2); + if (filename != NULL) + { + status = MagickPingImage(ping_wand, filename); + } + else + { + status = MagickPingImageBlob(ping_wand, contents, size); + } + + if (ino >= MagickGetNumberImages(ping_wand)) + { + image_error ("Invalid image number `%s' in image `%s'", + image, img->spec); + UNGCPRO; + return 0; + } + + if (MagickGetNumberImages(ping_wand) > 1) + img->data.lisp_val = + Fcons (Qcount, + Fcons (make_number (MagickGetNumberImages(ping_wand)), + img->data.lisp_val)); + + DestroyMagickWand (ping_wand); + /* Now, after pinging, we know how many images are inside the + file. If its not a bundle, just one. + */ + + if (filename != NULL) + { + printf("im read file %s\n", filename); + image_info=CloneImageInfo((ImageInfo *) NULL); + (void) strcpy(image_info->filename, filename); + image_info -> number_scenes = 1; + image_info -> scene = ino; + exception=AcquireExceptionInfo(); + + im_image = ReadImage (image_info, exception); + CatchException(exception); + + printf("im wand from image\n"); + image_wand = NewMagickWandFromImage(im_image); + } + else + { + image_wand = NewMagickWand(); + status = MagickReadImageBlob(image_wand, contents, size); + } + image_error ("im read failed", Qnil, Qnil); + if (status == MagickFalse) goto imagemagick_error; + + + /* if(ino == 0) */ + /* MagickSetFirstIterator(image_wand); */ + /* else */ + /* MagickSetIteratorIndex(image_wand, ino); */ + + //MagickSetFirstIterator(image_wand); + + + /* If width and/or height is set in the display spec assume we want + to scale to those values. if either h or w is unspecified, the + unspecified should be calculated from the specified to preserve + aspect ratio. */ + + value = image_spec_value (img->spec, QCwidth, NULL); + desired_width = (INTEGERP (value) ? XFASTINT (value) : -1); + value = image_spec_value (img->spec, QCheight, NULL); + desired_height = (INTEGERP (value) ? XFASTINT (value) : -1); + + height = MagickGetImageHeight (image_wand); + width = MagickGetImageWidth (image_wand); + + if(desired_width != -1 && desired_height == -1) + { + /* w known, calculate h*/ + desired_height = ( (double)desired_width / width ) * height; + } + if(desired_width == -1 && desired_height != -1) + { + /* h known, calculate w*/ + desired_width = ( (double)desired_height / height ) * width; + } + if(desired_width != -1 && desired_height != -1) + { + printf("MagickScaleImage %d %d\n", desired_width, desired_height); + status = MagickScaleImage(image_wand, desired_width, desired_height); + if (status == MagickFalse) { + image_error ("Imagemagick scale failed", Qnil, Qnil); + goto imagemagick_error; + } + } + + + /* crop behaves similar to image slicing in Emacs but is more memory + efficient */ + crop = image_spec_value (img->spec, QCcrop, NULL); + + if(CONSP (crop)) + { + /* + after some testing, it seems MagickCropImage is the fastest + crop function in ImageMagick. This crop function seems to do + less copying than the alternatives, but it still reads the + entire image into memory before croping, which is aparently + difficult to avoid when using imagemagick. + */ + + int w,h,x,y; + w=XFASTINT(XCAR(crop)); + h=XFASTINT(XCAR(XCDR(crop))); + x=XFASTINT(XCAR(XCDR(XCDR(crop)))); + y=XFASTINT(XCAR(XCDR(XCDR(XCDR(crop))))); + printf("MagickCropImage(image_wand, %d,%d, %d,%d)\n", w, h, x, y); + MagickCropImage(image_wand, w,h, x,y); + } + + /* Furthermore :rotation. we need background color and angle for + rotation. */ + /* + TODO background handling for rotation specified_bg = + image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP + (specified_bg) + */ + value = image_spec_value (img->spec, QCrotation, NULL); + if (FLOATP (value)) + { + PixelWand* background = NewPixelWand(); + PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/ + + rotation = extract_float (value); + printf ("MagickRotateImage %f\n", rotation); + + status = MagickRotateImage (image_wand, background, rotation); + DestroyPixelWand (background); + if (status == MagickFalse) + { + image_error ("Imagemagick image rotate failed", Qnil, Qnil); + goto imagemagick_error; + } + } + + /* Finaly we are done manipulating the image, figure out resulting + width, height, and then transfer ownerwship to Emacs. + */ + height = MagickGetImageHeight (image_wand); + width = MagickGetImageWidth (image_wand); + if (status == MagickFalse) + { + image_error ("Imagemagick image get size failed", Qnil, Qnil); + goto imagemagick_error; + } + + if (! check_image_size (f, width, height)) + { + image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); + goto imagemagick_error; + } + + /* We can now get a valid pixel buffer from the imagemagick file, if all + went ok. */ + + + init_color_table (); + imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type) + ? XFASTINT (Vimagemagick_render_type) : 0); + if (imagemagick_rendermethod == 0) + { + /* Try to create a x pixmap to hold the imagemagick pixmap. */ + if (!x_create_x_image_and_pixmap (f, width, height, 0, + &ximg, &img->pixmap)) + { + image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil); + goto imagemagick_error; + } + + /* Copy imagegmagick image to x with primitive yet robust pixel + pusher loop. This has been tested a lot with many different + images. + */ + + /* Copy pixels from the imagemagick image structure to the x image map. */ + iterator = NewPixelIterator (image_wand); + if ((iterator == (PixelIterator *) NULL)) + { + image_error ("Imagemagick pixel iterator creation failed", + Qnil, Qnil); + goto imagemagick_error; + } + + for (y = 0; y < (long) MagickGetImageHeight(image_wand); y++) + { + pixels = PixelGetNextIteratorRow (iterator, &width); + if ((pixels == (PixelWand **) NULL)) + break; + for (x = 0; x < (long) width; x++) + { + PixelGetMagickColor (pixels[x], &pixel); + XPutPixel (ximg, x, y, + lookup_rgb_color (f, + pixel.red, + pixel.green, + pixel.blue)); + } + } + DestroyPixelIterator (iterator); + } + + if (imagemagick_rendermethod == 1) + { + /* Try if magicexportimage is any faster than pixelpushing. */ + int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/ + char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/ + /* Try to create a x pixmap to hold the imagemagick pixmap. */ + printf("imagedepth:%d exportdepth:%s\n", imagedepth, exportdepth); + if (!x_create_x_image_and_pixmap (f, width, height, imagedepth, + &ximg, &img->pixmap)){ + image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil); + goto imagemagick_error; + } + + + /* Oddly, the below code doesnt seem to work:*/ + /* switch(ximg->bitmap_unit){ */ + /* case 8: */ + /* pixelwidth=CharPixel; */ + /* break; */ + /* case 16: */ + /* pixelwidth=ShortPixel; */ + /* break; */ + /* case 32: */ + /* pixelwidth=LongPixel; */ + /* break; */ + /* } */ + /* + Here im just guessing the format of the bitmap. + happens to work fine for: + - bw djvu images + on rgb display. + seems about 3 times as fast as pixel pushing(not carefully measured) + */ + pixelwidth = CharPixel;/*??? TODO figure out*/ +#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS + MagickExportImagePixels(image_wand, + 0, 0, + width, height, + exportdepth, + pixelwidth, + /*&(img->pixmap));*/ + ximg->data); +#else + image_error("You dont have MagickExportImagePixels, upgrade ImageMagick!", + Qnil, Qnil); +#endif + } + + +#ifdef COLOR_TABLE_SUPPORT + /* Remember colors allocated for this image. */ + img->colors = colors_in_color_table (&img->ncolors); + free_color_table (); +#endif /* COLOR_TABLE_SUPPORT */ + + + img->width = width; + img->height = height; + + /* Put the image into the pixmap, then free the X image and its + buffer. */ + x_put_x_image (f, ximg, img->pixmap, width, height); + x_destroy_x_image (ximg); + + + /* Final cleanup. image_wand should be the only resource left. */ + DestroyMagickWand (image_wand); + + return 1; + + imagemagick_error: + /* TODO more cleanup. */ + image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil); + printf("Imagemagick error, see *Messages*\n"); + return 0; +} + + +/* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if + successful. this function will go into the imagemagick_type structure, and + the prototype thus needs to be compatible with that structure. */ + +static int +imagemagick_load (struct frame *f, + struct image *img) +{ + int success_p = 0; + Lisp_Object file_name; + + /* If IMG->spec specifies a file name, create a non-file spec from it. */ + file_name = image_spec_value (img->spec, QCfile, NULL); + if (STRINGP (file_name)) + { + Lisp_Object file; + unsigned char *contents; + int size; + struct gcpro gcpro1; + + file = x_find_image_file (file_name); + GCPRO1 (file); + if (!STRINGP (file)) + { + image_error ("Cannot find image file `%s'", file_name, Qnil); + UNGCPRO; + return 0; + } + success_p = imagemagick_load_image (f, img, 0, 0, SDATA(file_name)); + UNGCPRO; + } + /* Else its not a file, its a lisp object. Load the image from a + lisp object rather than a file. */ + else + { + Lisp_Object data; + + data = image_spec_value (img->spec, QCdata, NULL); + success_p = imagemagick_load_image (f, img, SDATA (data), + SBYTES (data), NULL); + } + + return success_p; +} + +/* Structure describing the image type `imagemagick'. Its the same + type of structure defined for all image formats, handled by Emacs + image functions. See struct image_type in dispextern.h. */ + +static struct image_type imagemagick_type = + { + /* An identifier showing that this is an image structure for the + IMAGEMAGICK format. */ + &Qimagemagick, + /* Handle to a function that can be used to identify a IMAGEMAGICK + file. */ + imagemagick_image_p, + /* Handle to function used to load a IMAGEMAGICK file. */ + imagemagick_load, + /* Handle to function to free resources for IMAGEMAGICK. */ + imagemagick_clear_image, + /* An internal field to link to the next image type in a list of + image types, will be filled in when registering the format. */ + NULL + }; + + + + +DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0, + doc: /* Return image file types supported by ImageMagick. + Since ImageMagick recognizes a lot of file-types that clash with Emacs, + such as .c, we want to be able to alter the list at the lisp level. */) - () ++ (void) +{ + Lisp_Object typelist = Qnil; - unsigned long numf; ++ size_t numf; + ExceptionInfo ex; + char** imtypes = GetMagickList ("*", &numf, &ex); + int i; + Lisp_Object Qimagemagicktype; + for (i = 0; i < numf; i++) + { + Qimagemagicktype = intern (imtypes[i]); + typelist = Fcons (Qimagemagicktype, typelist); + } + return typelist; +} + +#endif /* defined (HAVE_IMAGEMAGICK) */ + + /*********************************************************************** SVG @@@ -8846,13 -8073,12 +8600,12 @@@ DEFUN ("lookup-image", Flookup_image, S DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0, doc: /* Initialize image library implementing image type TYPE. -Return non-nil if TYPE is a supported image type. + Return non-nil if TYPE is a supported image type. - Image types pbm and xbm are prebuilt; other types are loaded here. - Libraries to load are specified in alist LIBRARIES (usually, the value - of `image-library-alist', which see). */) - (type, libraries) - Lisp_Object type, libraries; + Image types pbm and xbm are prebuilt; other types are loaded here. + Libraries to load are specified in alist LIBRARIES (usually, the value + of `image-library-alist', which see). */) + (Lisp_Object type, Lisp_Object libraries) { Lisp_Object tested; @@@ -8910,12 -8127,9 +8663,10 @@@ return Qnil; } + void - syms_of_image () + syms_of_image (void) { - extern Lisp_Object Qrisky_local_variable; /* Syms_of_xdisp has already run. */ - /* Initialize this only once, since that's what we do with Vimage_types and they are supposed to be in sync. Initializing here gives correct operation on GNU/Linux of calling dump-emacs after loading some images. */ @@@ -9102,28 -8300,20 +8853,28 @@@ listed; they are always supported. */) Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS); DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay, - doc: /* Maximum time after which images are removed from the cache. -When an image has not been displayed this many seconds, Emacs -automatically removes it from the image cache. If the cache contains -a large number of images, the actual eviction time may be shorter. -The value can also be nil, meaning the cache is never cleared. - -The function `clear-image-cache' disregards this variable. */); + doc: /* Maximum time after which images are removed from the cache. + When an image has not been displayed this many seconds, Emacs + automatically removes it from the image cache. If the cache contains + a large number of images, the actual eviction time may be shorter. + The value can also be nil, meaning the cache is never cleared. + The function `clear-image-cache' disregards this variable. */); Vimage_cache_eviction_delay = make_number (300); +#ifdef HAVE_IMAGEMAGICK + DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type, + doc: /* Choose between ImageMagick render methods. */); +#endif + } + void - init_image () + init_image (void) { + } + + /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9 (do not change this comment) */