* imagemagick patch v3 @ 2009-08-04 19:55 joakim 2009-08-05 0:43 ` joakim 0 siblings, 1 reply; 8+ messages in thread From: joakim @ 2009-08-04 19:55 UTC (permalink / raw) To: Emacs Development [-- Attachment #1: Type: text/plain, Size: 931 bytes --] Hello, This is the third stab at native imagemagick support for emacs. New features: - :rotation image spec, to rotate image arbitrarily - :width and :height, if you specify them image will be scaled to these sizes - :geometry and :crop, imagemagick specifyers for size and croping, see imagemagick docs - :index, show a particular image within an image archive format(its possible to see a particular page in a pdf for instance) Ok, those features work somewhat well. What doesnt work, and which I would like some help with, is how to make emacs automagically recognize that a image file type is handled by the imagemagick loader. There is some half-baked code in the patch that doesnt work for this. Heres some test code: make && src/emacs -q --eval "(progn (insert \"mupp\")(put-text-property 1 2 'display (list 'image :file \"/tmp/24725.pdf\" :type 'imagemagick :index 0 :geometry \"50%\" :crop \"\" :rotation 90.0) ))" [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: imagemagick3.patch --] [-- Type: text/x-patch, Size: 17983 bytes --] diff --git a/configure.in b/configure.in index f4096db..c4207d8 100644 --- a/configure.in +++ b/configure.in @@ -132,6 +132,8 @@ OPTION_DEFAULT_ON([tiff],[don't compile with TIFF image support]) OPTION_DEFAULT_ON([gif],[don't compile with GIF image support]) OPTION_DEFAULT_ON([png],[don't compile with PNG image support]) OPTION_DEFAULT_ON([rsvg],[don't compile with SVG image support]) +OPTION_DEFAULT_OFF([imagemagick],[compile with ImageMagick image support]) + OPTION_DEFAULT_ON([xft],[don't use XFT for anti aliased fonts]) OPTION_DEFAULT_ON([libotf],[don't use libotf for OpenType font support]) @@ -142,6 +144,8 @@ OPTION_DEFAULT_ON([xaw3d],[don't use Xaw3d]) OPTION_DEFAULT_ON([xim],[don't use X11 XIM]) OPTION_DEFAULT_OFF([ns],[use nextstep (Cocoa or GNUstep) windowing system]) + + OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console]) OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support]) @@ -1589,6 +1593,24 @@ if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes"; then fi fi +HAVE_IMAGEMAGICK=no +if test "${HAVE_X11}" = "yes" ; then + if test "${with_imagemagick}" != "no"; then + IMAGEMAGICK_REQUIRED=1 + IMAGEMAGICK_MODULE="MagickWand >= $IMAGEMAGICK_REQUIRED" + + 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 + fi +fi HAVE_GTK=no if test "${with_gtk}" = "yes" || test "$USE_X_TOOLKIT" = "maybe"; then @@ -2952,6 +2974,7 @@ echo " Does Emacs use -ltiff? ${HAVE_TIFF}" echo " Does Emacs use a gif library? ${HAVE_GIF} $ac_gif_lib_name" echo " Does Emacs use -lpng? ${HAVE_PNG}" echo " Does Emacs use -lrsvg-2? ${HAVE_RSVG}" +echo " Does Emacs use imagemagick? ${HAVE_IMAGEMAGICK}" echo " Does Emacs use -lgpm? ${HAVE_GPM}" echo " Does Emacs use -ldbus? ${HAVE_DBUS}" diff --git a/lisp/image.el b/lisp/image.el index 076a969..a102ffb 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -70,6 +70,7 @@ a non-nil value, TYPE is the image's type.") ("\\.ps\\'" . postscript) ("\\.tiff?\\'" . tiff) ("\\.svgz?\\'" . svg) + ("\\.xcf?\\'" . imagemagick) ) "Alist of (REGEXP . IMAGE-TYPE) pairs used to identify image files. When the name of an image file match REGEXP, it is assumed to diff --git a/src/Makefile.in b/src/Makefile.in index 425cf98..797d6fb 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -253,7 +253,7 @@ DBUS_OBJ = dbusbind.o /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM since it may have -I options that should override those two. */ -ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ +ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${IMAGEMAGICK_CFLAGS} ${DBUS_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@ .SUFFIXES: .m @@ -425,6 +425,9 @@ CFLAGS_SOUND= @CFLAGS_SOUND@ RSVG_LIBS= @RSVG_LIBS@ RSVG_CFLAGS= @RSVG_CFLAGS@ +IMAGEMAGICK_LIBS= @IMAGEMAGICK_LIBS@ +IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@ + #ifndef ORDINARY_LINK /* Fix linking if compiled with GCC. */ #ifdef __GNUC__ @@ -878,7 +881,7 @@ SOME_MACHINE_LISP = ../lisp/mouse.elc \ duplicated symbols. If the standard libraries were compiled with GCC, we might need gnulib again after them. */ -LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \ +LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) ${IMAGEMAGICK_LIBS} $(DBUS_LIBS) \ LIBGPM LIBRESOLV LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \ LIBS_DEBUG $(GETLOADAVG_LIBS) \ @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ @M17N_FLT_LIBS@ \ diff --git a/src/config.in b/src/config.in index 404e00b..111de5d 100644 --- a/src/config.in +++ b/src/config.in @@ -547,6 +547,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ /* Define to 1 if using librsvg. */ #undef HAVE_RSVG +/* Define to 1 if using imagemagick. */ +#undef HAVE_IMAGEMAGICK + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT diff --git a/src/image.c b/src/image.c index fa8c3ea..e9ed2c6 100644 --- a/src/image.c +++ b/src/image.c @@ -838,7 +838,7 @@ extern Lisp_Object QCdata, QCtype; extern Lisp_Object Qcenter; Lisp_Object QCascent, QCmargin, QCrelief, Qcount; Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; -Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask; +Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask, QCgeometry, QCcrop, QCrotation; /* Other symbols. */ @@ -7771,6 +7771,339 @@ gif_load (struct frame *f, struct image *img) #endif /* HAVE_GIF */ +/*********************************************************************** + imagemagick + ***********************************************************************/ +#if defined (HAVE_IMAGEMAGICK) + +/* Function prototypes. */ + +static int imagemagick_image_p P_ ((Lisp_Object object)); +static int imagemagick_load P_ ((struct frame *f, struct image *img)); + +static int imagemagick_load_image P_ ((struct frame *, struct image *, + unsigned char *, unsigned int)); + +/* The symbol `imagemagick' identifying images of this type. */ + +Lisp_Object Qimagemagick; + +/* Indices of image specification fields in imagemagick_format, below. */ + +enum imagemagick_keyword_index +{ + IMAGEMAGICK_TYPE, + IMAGEMAGICK_DATA, + IMAGEMAGICK_FILE, + IMAGEMAGICK_ASCENT, + IMAGEMAGICK_MARGIN, + IMAGEMAGICK_RELIEF, + IMAGEMAGICK_ALGORITHM, + IMAGEMAGICK_HEURISTIC_MASK, + IMAGEMAGICK_MASK, + IMAGEMAGICK_BACKGROUND, + IMAGEMAGICK_LAST +}; + +/* Vector of image_keyword structures describing the format + of valid user-defined image specifications. */ + +static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = +{ + {":type", IMAGE_SYMBOL_VALUE, 1}, + {":data", IMAGE_STRING_VALUE, 0}, + {":file", IMAGE_STRING_VALUE, 0}, + {":ascent", IMAGE_ASCENT_VALUE, 0}, + {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":relief", IMAGE_INTEGER_VALUE, 0}, + {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, + {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, + {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, + {":background", IMAGE_STRING_OR_NIL_VALUE, 0} +}; + +/* 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. */ + x_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 +}; + + +/* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do + this by calling parse_image_spec and supplying the keywords that + identify the IMAGEMAGICK format. */ + +static int +imagemagick_image_p (object) + Lisp_Object object; +{ + struct image_keyword fmt[IMAGEMAGICK_LAST]; + bcopy (imagemagick_format, fmt, sizeof fmt); + + if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick)) + return 0; + + /* Must specify either the :data or :file keyword. */ + return fmt[IMAGEMAGICK_FILE].count + fmt[IMAGEMAGICK_DATA].count == 1; +} + +/* The GIF library also defines DrawRectangle, but its never used in Emacs. + Therefore rename the function so it doesnt collide with ImageMagick */ +#define DrawRectangle DrawRectangleGif +#include <wand/MagickWand.h> + +/* 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 (f, img) + 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; + } + + /* Read the entire file into memory. */ + contents = slurp_file (SDATA (file), &size); + if (contents == NULL) + { + image_error ("Error loading IMAGEMAGICK image `%s'", img->spec, Qnil); + UNGCPRO; + return 0; + } + /* If the file was slurped into memory properly, parse it. */ + success_p = imagemagick_load_image (f, img, contents, size); + xfree (contents); + 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)); + } + + return success_p; +} + +/* 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. + + Returns non-zero when successful. +*/ + +static int +imagemagick_load_image (f, img, contents, size) + /* 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; +{ + long unsigned int width; + long unsigned int height; + + MagickBooleanType + status; + + XImagePtr ximg; + Lisp_Object specified_bg; + XColor background; + int x; + int y; + + MagickWand *image_wand; + PixelIterator *iterator; + PixelWand **pixels; + MagickPixelPacket pixel; + + + /* image_wand will contain the image */ + image_wand=NewMagickWand(); + + /* Parse the contents argument and fill in the rimagemagick_handle. */ + //status=MagickReadImage(image_wand, "/tmp/tst.djvu"); + status=MagickReadImageBlob(image_wand, contents, size); + if (status == MagickFalse) goto imagemagick_error; + + /* handle image index for image types who can contain more than one image. + interface :index is same as for GIF */ + Lisp_Object image; + long ino; + image = image_spec_value (img->spec, QCindex, NULL); + ino = INTEGERP (image) ? XFASTINT (image) : 0; + + /* if (ino >= ) */ + /* { */ + /* image_error ("Invalid image number `%s' in image `%s'", */ + /* image, img->spec); */ + /* UNGCPRO; */ + /* return 0; */ + /* } */ + + MagickSetIteratorIndex(image_wand, ino); + + /* + if width and/or height is set in the display spec + assume we want to scale to those */ + + int desired_width, desired_height; + Lisp_Object value; + 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); + if(desired_width != -1 && desired_height != -1){ + printf("MagickScaleImage %d %d\n",desired_width, desired_height); + MagickScaleImage(image_wand, desired_width, desired_height); + } + + /* also support :geometry and :crop which are imagemagick specific descriptors */ + + Lisp_Object crop, geometry; + crop = image_spec_value (img->spec, QCcrop, NULL); + geometry = image_spec_value (img->spec, QCgeometry, NULL); + if (STRINGP (crop) && STRINGP (geometry)){ + printf("MagickTransformImage %s %s\n",SDATA(crop), SDATA(geometry)); + image_wand=MagickTransformImage(image_wand, SDATA(crop), SDATA(geometry)); + //TODO differ between image_wand and transform_wand + } + + /* furthermore :rotation. we need background color and angle for rotation */ + + /* + specified_bg = image_spec_value (img->spec, QCbackground, NULL); + if (!STRINGP (specified_bg) + */ + double rotation; + value = image_spec_value (img->spec, QCrotation, NULL); + if(FLOATP(value)){ + PixelWand* background = NewPixelWand(); + PixelSetColor(background,"#ffffff"); + + rotation=extract_float(value); + printf("MagickRotateImage %f\n",rotation); + + status=MagickRotateImage(image_wand, background,rotation); + } + + /* finaly we are done manipulating the image, + figure resulting width, height, and then transfer ownerwship to emacs + */ + height=MagickGetImageHeight(image_wand); + width=MagickGetImageWidth(image_wand); + if (status == MagickFalse) 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. */ + + + + /* 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)) + { + return 0; + } + + init_color_table (); + + /* copy pixels from the imagemagick image structure to the x image map */ + iterator=NewPixelIterator(image_wand); + if ((iterator == (PixelIterator *) NULL)) 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)); + } + } + +#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; + + /* Maybe fill in the background field while we have ximg handy. + Casting avoids a GCC warning. */ + IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); + + /* 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); + + //JAVE TODO lots of cleanup + + return 1; + + imagemagick_error: + image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil); + return 0; +} + +#endif /* defined (HAVE_IMAGEMAGICK) */ + + \f /*********************************************************************** SVG @@ -8568,6 +8901,14 @@ of `image-library-alist', which see). */) return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries); #endif +#if defined (HAVE_IMAGEMAGICK) + if (EQ (type, Qimagemagick)){ + /* MagickWandGenesis() initalizes the imagemagick library */ + MagickWandGenesis(); + return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions, libraries); + } +#endif + #ifdef HAVE_GHOSTSCRIPT if (EQ (type, Qpostscript)) return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries); @@ -8653,6 +8994,12 @@ non-numeric, there is no explicit limit on the size of images. */); staticpro (&QCheuristic_mask); QCindex = intern (":index"); staticpro (&QCindex); + QCgeometry = intern (":geometry"); + staticpro (&QCgeometry); + QCcrop = intern (":crop"); + staticpro (&QCcrop); + QCrotation = intern (":rotation"); + staticpro (&QCrotation); QCmatrix = intern (":matrix"); staticpro (&QCmatrix); QCcolor_adjustment = intern (":color-adjustment"); @@ -8713,6 +9060,12 @@ non-numeric, there is no explicit limit on the size of images. */); ADD_IMAGE_TYPE (Qpng); #endif +#if defined (HAVE_IMAGEMAGICK) + Qimagemagick = intern ("imagemagick"); + staticpro (&Qimagemagick); + ADD_IMAGE_TYPE (Qimagemagick); +#endif + #if defined (HAVE_RSVG) Qsvg = intern ("svg"); staticpro (&Qsvg); @@ -8761,6 +9114,20 @@ meaning don't clear the cache. */); void init_image () { + //register imagegemagick types here, they are dynamic + unsigned long numf; + ExceptionInfo ex; + char** imtypes = GetMagickList("*", &numf,&ex); + int i; + Lisp_Object Qimagemagicktype; + for (i = 0; i < numf; i++) { + printf("immagick format::%s\n", *(imtypes+i)); + Qimagemagicktype = intern ( *(imtypes+i)) ; + //staticpro (&Qpng); + ADD_IMAGE_TYPE (Qimagemagicktype); + } + + } /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9 [-- Attachment #3: Type: text/plain, Size: 18 bytes --] -- Joakim Verona ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: imagemagick patch v3 2009-08-04 19:55 imagemagick patch v3 joakim @ 2009-08-05 0:43 ` joakim 2009-08-05 2:15 ` Stefan Monnier 0 siblings, 1 reply; 8+ messages in thread From: joakim @ 2009-08-05 0:43 UTC (permalink / raw) To: Emacs Development [-- Attachment #1: Type: text/plain, Size: 1138 bytes --] joakim@verona.se writes: > Hello, > > This is the third stab at native imagemagick support for emacs. > > New features: > - :rotation image spec, to rotate image arbitrarily > - :width and :height, if you specify them image will be scaled to these > sizes > - :geometry and :crop, imagemagick specifyers for size and croping, see > imagemagick docs > - :index, show a particular image within an image archive format(its > possible to see a particular page in a pdf for instance) > > Ok, those features work somewhat well. What doesnt work, and which I > would like some help with, is how to make emacs automagically recognize > that a image file type is handled by the imagemagick loader. There is > some half-baked code in the patch that doesnt work for this. Attached is v4, which has better support for the above issue. Call (imagemagick-register-types) to register all types handled by imagemagick. > Heres some test code: > > make && src/emacs -q --eval "(progn (insert \"mupp\")(put-text-property 1 2 'display (list 'image :file \"/tmp/24725.pdf\" :type 'imagemagick :index 0 :geometry \"50%\" :crop \"\" :rotation 90.0) ))" > [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: imagemagick4.patch --] [-- Type: text/x-patch, Size: 19621 bytes --] diff --git a/configure.in b/configure.in index f4096db..c4207d8 100644 --- a/configure.in +++ b/configure.in @@ -132,6 +132,8 @@ OPTION_DEFAULT_ON([tiff],[don't compile with TIFF image support]) OPTION_DEFAULT_ON([gif],[don't compile with GIF image support]) OPTION_DEFAULT_ON([png],[don't compile with PNG image support]) OPTION_DEFAULT_ON([rsvg],[don't compile with SVG image support]) +OPTION_DEFAULT_OFF([imagemagick],[compile with ImageMagick image support]) + OPTION_DEFAULT_ON([xft],[don't use XFT for anti aliased fonts]) OPTION_DEFAULT_ON([libotf],[don't use libotf for OpenType font support]) @@ -142,6 +144,8 @@ OPTION_DEFAULT_ON([xaw3d],[don't use Xaw3d]) OPTION_DEFAULT_ON([xim],[don't use X11 XIM]) OPTION_DEFAULT_OFF([ns],[use nextstep (Cocoa or GNUstep) windowing system]) + + OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console]) OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support]) @@ -1589,6 +1593,24 @@ if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes"; then fi fi +HAVE_IMAGEMAGICK=no +if test "${HAVE_X11}" = "yes" ; then + if test "${with_imagemagick}" != "no"; then + IMAGEMAGICK_REQUIRED=1 + IMAGEMAGICK_MODULE="MagickWand >= $IMAGEMAGICK_REQUIRED" + + 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 + fi +fi HAVE_GTK=no if test "${with_gtk}" = "yes" || test "$USE_X_TOOLKIT" = "maybe"; then @@ -2952,6 +2974,7 @@ echo " Does Emacs use -ltiff? ${HAVE_TIFF}" echo " Does Emacs use a gif library? ${HAVE_GIF} $ac_gif_lib_name" echo " Does Emacs use -lpng? ${HAVE_PNG}" echo " Does Emacs use -lrsvg-2? ${HAVE_RSVG}" +echo " Does Emacs use imagemagick? ${HAVE_IMAGEMAGICK}" echo " Does Emacs use -lgpm? ${HAVE_GPM}" echo " Does Emacs use -ldbus? ${HAVE_DBUS}" diff --git a/lisp/image.el b/lisp/image.el index 076a969..8b989fa 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -70,6 +70,8 @@ a non-nil value, TYPE is the image's type.") ("\\.ps\\'" . postscript) ("\\.tiff?\\'" . tiff) ("\\.svgz?\\'" . svg) + ("\\.xcf?\\'" . imagemagick) + ("\\.djvu?\\'" . imagemagick) ) "Alist of (REGEXP . IMAGE-TYPE) pairs used to identify image files. When the name of an image file match REGEXP, it is assumed to @@ -586,6 +588,23 @@ Example: `(defvar ,symbol (find-image ',specs) ,doc)) +(defun imagemagic-register-types () + "Register file types that imagemagick is able to handle." + (let ((im-types (imagemagick-types))) + (while im-types + (let + ((extension (downcase (symbol-name (car im-types))))) + (push + (cons (concat "\\." extension "$") 'image-mode) + auto-mode-alist) + (push + (cons (concat "\\." extension "\\'") 'imagemagick) + image-type-file-name-regexps) + + (setq im-types (cdr im-types)) + ) + ))) + (provide 'image) ;; arch-tag: 8e76a07b-eb48-4f3e-a7a0-1a7ba9f096b3 diff --git a/src/Makefile.in b/src/Makefile.in index 425cf98..797d6fb 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -253,7 +253,7 @@ DBUS_OBJ = dbusbind.o /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM since it may have -I options that should override those two. */ -ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ +ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${IMAGEMAGICK_CFLAGS} ${DBUS_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@ .SUFFIXES: .m @@ -425,6 +425,9 @@ CFLAGS_SOUND= @CFLAGS_SOUND@ RSVG_LIBS= @RSVG_LIBS@ RSVG_CFLAGS= @RSVG_CFLAGS@ +IMAGEMAGICK_LIBS= @IMAGEMAGICK_LIBS@ +IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@ + #ifndef ORDINARY_LINK /* Fix linking if compiled with GCC. */ #ifdef __GNUC__ @@ -878,7 +881,7 @@ SOME_MACHINE_LISP = ../lisp/mouse.elc \ duplicated symbols. If the standard libraries were compiled with GCC, we might need gnulib again after them. */ -LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \ +LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) ${IMAGEMAGICK_LIBS} $(DBUS_LIBS) \ LIBGPM LIBRESOLV LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \ LIBS_DEBUG $(GETLOADAVG_LIBS) \ @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ @M17N_FLT_LIBS@ \ diff --git a/src/config.in b/src/config.in index 404e00b..111de5d 100644 --- a/src/config.in +++ b/src/config.in @@ -547,6 +547,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ /* Define to 1 if using librsvg. */ #undef HAVE_RSVG +/* Define to 1 if using imagemagick. */ +#undef HAVE_IMAGEMAGICK + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT diff --git a/src/image.c b/src/image.c index fa8c3ea..02e0792 100644 --- a/src/image.c +++ b/src/image.c @@ -838,7 +838,7 @@ extern Lisp_Object QCdata, QCtype; extern Lisp_Object Qcenter; Lisp_Object QCascent, QCmargin, QCrelief, Qcount; Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; -Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask; +Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask, QCgeometry, QCcrop, QCrotation; /* Other symbols. */ @@ -7771,6 +7771,339 @@ gif_load (struct frame *f, struct image *img) #endif /* HAVE_GIF */ +/*********************************************************************** + imagemagick + ***********************************************************************/ +#if defined (HAVE_IMAGEMAGICK) + +/* Function prototypes. */ + +static int imagemagick_image_p P_ ((Lisp_Object object)); +static int imagemagick_load P_ ((struct frame *f, struct image *img)); + +static int imagemagick_load_image P_ ((struct frame *, struct image *, + unsigned char *, unsigned int)); + +/* The symbol `imagemagick' identifying images of this type. */ + +Lisp_Object Qimagemagick; + +/* Indices of image specification fields in imagemagick_format, below. */ + +enum imagemagick_keyword_index +{ + IMAGEMAGICK_TYPE, + IMAGEMAGICK_DATA, + IMAGEMAGICK_FILE, + IMAGEMAGICK_ASCENT, + IMAGEMAGICK_MARGIN, + IMAGEMAGICK_RELIEF, + IMAGEMAGICK_ALGORITHM, + IMAGEMAGICK_HEURISTIC_MASK, + IMAGEMAGICK_MASK, + IMAGEMAGICK_BACKGROUND, + IMAGEMAGICK_LAST +}; + +/* Vector of image_keyword structures describing the format + of valid user-defined image specifications. */ + +static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = +{ + {":type", IMAGE_SYMBOL_VALUE, 1}, + {":data", IMAGE_STRING_VALUE, 0}, + {":file", IMAGE_STRING_VALUE, 0}, + {":ascent", IMAGE_ASCENT_VALUE, 0}, + {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":relief", IMAGE_INTEGER_VALUE, 0}, + {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, + {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, + {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, + {":background", IMAGE_STRING_OR_NIL_VALUE, 0} +}; + +/* 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. */ + x_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 +}; + + +/* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do + this by calling parse_image_spec and supplying the keywords that + identify the IMAGEMAGICK format. */ + +static int +imagemagick_image_p (object) + Lisp_Object object; +{ + struct image_keyword fmt[IMAGEMAGICK_LAST]; + bcopy (imagemagick_format, fmt, sizeof fmt); + + if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick)) + return 0; + + /* Must specify either the :data or :file keyword. */ + return fmt[IMAGEMAGICK_FILE].count + fmt[IMAGEMAGICK_DATA].count == 1; +} + +/* The GIF library also defines DrawRectangle, but its never used in Emacs. + Therefore rename the function so it doesnt collide with ImageMagick */ +#define DrawRectangle DrawRectangleGif +#include <wand/MagickWand.h> + +/* 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 (f, img) + 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; + } + + /* Read the entire file into memory. */ + contents = slurp_file (SDATA (file), &size); + if (contents == NULL) + { + image_error ("Error loading IMAGEMAGICK image `%s'", img->spec, Qnil); + UNGCPRO; + return 0; + } + /* If the file was slurped into memory properly, parse it. */ + success_p = imagemagick_load_image (f, img, contents, size); + xfree (contents); + 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)); + } + + return success_p; +} + +/* 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. + + Returns non-zero when successful. +*/ + +static int +imagemagick_load_image (f, img, contents, size) + /* 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; +{ + long unsigned int width; + long unsigned int height; + + MagickBooleanType + status; + + XImagePtr ximg; + Lisp_Object specified_bg; + XColor background; + int x; + int y; + + MagickWand *image_wand; + PixelIterator *iterator; + PixelWand **pixels; + MagickPixelPacket pixel; + + + /* image_wand will contain the image */ + image_wand=NewMagickWand(); + + /* Parse the contents argument and fill in the rimagemagick_handle. */ + //status=MagickReadImage(image_wand, "/tmp/tst.djvu"); + status=MagickReadImageBlob(image_wand, contents, size); + if (status == MagickFalse) goto imagemagick_error; + + /* handle image index for image types who can contain more than one image. + interface :index is same as for GIF */ + Lisp_Object image; + long ino; + image = image_spec_value (img->spec, QCindex, NULL); + ino = INTEGERP (image) ? XFASTINT (image) : 0; + + /* if (ino >= ) */ + /* { */ + /* image_error ("Invalid image number `%s' in image `%s'", */ + /* image, img->spec); */ + /* UNGCPRO; */ + /* return 0; */ + /* } */ + + MagickSetIteratorIndex(image_wand, ino); + + /* + if width and/or height is set in the display spec + assume we want to scale to those */ + + int desired_width, desired_height; + Lisp_Object value; + 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); + if(desired_width != -1 && desired_height != -1){ + printf("MagickScaleImage %d %d\n",desired_width, desired_height); + MagickScaleImage(image_wand, desired_width, desired_height); + } + + /* also support :geometry and :crop which are imagemagick specific descriptors */ + + Lisp_Object crop, geometry; + crop = image_spec_value (img->spec, QCcrop, NULL); + geometry = image_spec_value (img->spec, QCgeometry, NULL); + if (STRINGP (crop) && STRINGP (geometry)){ + printf("MagickTransformImage %s %s\n",SDATA(crop), SDATA(geometry)); + image_wand=MagickTransformImage(image_wand, SDATA(crop), SDATA(geometry)); + //TODO differ between image_wand and transform_wand + } + + /* furthermore :rotation. we need background color and angle for rotation */ + + /* + specified_bg = image_spec_value (img->spec, QCbackground, NULL); + if (!STRINGP (specified_bg) + */ + double rotation; + value = image_spec_value (img->spec, QCrotation, NULL); + if(FLOATP(value)){ + PixelWand* background = NewPixelWand(); + PixelSetColor(background,"#ffffff"); + + rotation=extract_float(value); + printf("MagickRotateImage %f\n",rotation); + + status=MagickRotateImage(image_wand, background,rotation); + } + + /* finaly we are done manipulating the image, + figure resulting width, height, and then transfer ownerwship to emacs + */ + height=MagickGetImageHeight(image_wand); + width=MagickGetImageWidth(image_wand); + if (status == MagickFalse) 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. */ + + + + /* 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)) + { + return 0; + } + + init_color_table (); + + /* copy pixels from the imagemagick image structure to the x image map */ + iterator=NewPixelIterator(image_wand); + if ((iterator == (PixelIterator *) NULL)) 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)); + } + } + +#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; + + /* Maybe fill in the background field while we have ximg handy. + Casting avoids a GCC warning. */ + IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); + + /* 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); + + //JAVE TODO lots of cleanup + + return 1; + + imagemagick_error: + image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil); + return 0; +} + +#endif /* defined (HAVE_IMAGEMAGICK) */ + + \f /*********************************************************************** SVG @@ -8568,6 +8901,14 @@ of `image-library-alist', which see). */) return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries); #endif +#if defined (HAVE_IMAGEMAGICK) + if (EQ (type, Qimagemagick)){ + /* MagickWandGenesis() initalizes the imagemagick library */ + MagickWandGenesis(); + return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions, libraries); + } +#endif + #ifdef HAVE_GHOSTSCRIPT if (EQ (type, Qpostscript)) return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries); @@ -8577,6 +8918,24 @@ of `image-library-alist', which see). */) CACHE_IMAGE_TYPE (type, Qnil); return Qnil; } +DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0,0,0, + doc: /*return image file types supportedby imagemagick */) + () +{ + //get imagemagick filetypes from lisp + Lisp_Object typelist=Qnil; + unsigned long 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; +} + void syms_of_image () @@ -8653,6 +9012,12 @@ non-numeric, there is no explicit limit on the size of images. */); staticpro (&QCheuristic_mask); QCindex = intern (":index"); staticpro (&QCindex); + QCgeometry = intern (":geometry"); + staticpro (&QCgeometry); + QCcrop = intern (":crop"); + staticpro (&QCcrop); + QCrotation = intern (":rotation"); + staticpro (&QCrotation); QCmatrix = intern (":matrix"); staticpro (&QCmatrix); QCcolor_adjustment = intern (":color-adjustment"); @@ -8713,6 +9078,12 @@ non-numeric, there is no explicit limit on the size of images. */); ADD_IMAGE_TYPE (Qpng); #endif +#if defined (HAVE_IMAGEMAGICK) + Qimagemagick = intern ("imagemagick"); + staticpro (&Qimagemagick); + ADD_IMAGE_TYPE (Qimagemagick); +#endif + #if defined (HAVE_RSVG) Qsvg = intern ("svg"); staticpro (&Qsvg); @@ -8729,6 +9100,7 @@ non-numeric, there is no explicit limit on the size of images. */); #endif /* HAVE_RSVG */ defsubr (&Sinit_image_library); + defsubr (&Simagemagick_types); defsubr (&Sclear_image_cache); defsubr (&Simage_refresh); defsubr (&Simage_size); @@ -8761,7 +9133,21 @@ meaning don't clear the cache. */); void init_image () { + //register imagegemagick types here, they are dynamic + //TODO is this really necessary? + unsigned long numf; + ExceptionInfo ex; + char** imtypes = GetMagickList("*", &numf,&ex); + int i; + Lisp_Object Qimagemagicktype; + for (i = 0; i < numf; i++) { + printf("immagick format::%s\n", *(imtypes+i)); + Qimagemagicktype = intern ( *(imtypes+i)) ; + ADD_IMAGE_TYPE (Qimagemagicktype); + } } + + /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9 (do not change this comment) */ [-- Attachment #3: Type: text/plain, Size: 20 bytes --] -- Joakim Verona ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: imagemagick patch v3 2009-08-05 0:43 ` joakim @ 2009-08-05 2:15 ` Stefan Monnier 2009-08-05 8:10 ` joakim 0 siblings, 1 reply; 8+ messages in thread From: Stefan Monnier @ 2009-08-05 2:15 UTC (permalink / raw) To: joakim; +Cc: Emacs Development >> - :width and :height, if you specify them image will be scaled to these >> sizes It would be good to make it possible to specify zoom factors as well rather than resulting size (maybe if those parameters are floats rather than ints?). > + (push > + (cons (concat "\\." extension "$") 'image-mode) > + auto-mode-alist) The "$" should be replaced with "\\'". Stefan ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: imagemagick patch v3 2009-08-05 2:15 ` Stefan Monnier @ 2009-08-05 8:10 ` joakim 2009-08-05 17:23 ` Eli Zaretskii 0 siblings, 1 reply; 8+ messages in thread From: joakim @ 2009-08-05 8:10 UTC (permalink / raw) To: Stefan Monnier; +Cc: Emacs Development Stefan Monnier <monnier@iro.umontreal.ca> writes: >>> - :width and :height, if you specify them image will be scaled to these >>> sizes > > It would be good to make it possible to specify zoom factors as well > rather than resulting size (maybe if those parameters are floats rather > than ints?). This is already supported by the :geometry option which is quite powerful. You can do things like "50%" or "200x100" or "x100" etc. I tried to use existing keywords were available, but :geometry and :crop are very imagemagick specific. Anyway, I think rotation, scaling, and croping is sufficient. There are hundreds of operations in the imagemagick api, and I dont plan on adding more for now. I have toyed with the idea of providing a keyword like :operations, that would contain a list of image operations to be performed, but that will have to wait. >> + (push >> + (cons (concat "\\." extension "$") 'image-mode) >> + auto-mode-alist) > > The "$" should be replaced with "\\'". Ok, but I dont get why? > > > Stefan -- Joakim Verona ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: imagemagick patch v3 2009-08-05 8:10 ` joakim @ 2009-08-05 17:23 ` Eli Zaretskii 2009-08-05 18:19 ` Tassilo Horn 0 siblings, 1 reply; 8+ messages in thread From: Eli Zaretskii @ 2009-08-05 17:23 UTC (permalink / raw) To: joakim; +Cc: monnier, emacs-devel > From: joakim@verona.se > Date: Wed, 05 Aug 2009 10:10:23 +0200 > Cc: Emacs Development <emacs-devel@gnu.org> > > >> + (push > >> + (cons (concat "\\." extension "$") 'image-mode) > >> + auto-mode-alist) > > > > The "$" should be replaced with "\\'". > > Ok, but I dont get why? Because a file name on Posix platforms can include a newline character. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: imagemagick patch v3 2009-08-05 17:23 ` Eli Zaretskii @ 2009-08-05 18:19 ` Tassilo Horn 2009-08-05 18:53 ` Eli Zaretskii 0 siblings, 1 reply; 8+ messages in thread From: Tassilo Horn @ 2009-08-05 18:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, joakim, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: Hi! >> From: joakim@verona.se >> Date: Wed, 05 Aug 2009 10:10:23 +0200 >> Cc: Emacs Development <emacs-devel@gnu.org> >> >> >> + (push >> >> + (cons (concat "\\." extension "$") 'image-mode) >> >> + auto-mode-alist) >> > >> > The "$" should be replaced with "\\'". >> >> Ok, but I dont get why? > > Because a file name on Posix platforms can include a newline > character. I tried that on GNU/Linux, and indeed it does work. The `ls' command lists the file as "multi?line?file", where the question marks represent the newlines. Unfortunately, dired doesn't work with those files. Here's a "screenshot": --8<---------------cut here---------------start------------->8--- drwxr-xr-x 2 horn horn 4.0K 2009-06-30 22:32 kvm drwxr-xr-x 4 horn horn 4.0K 2009-08-05 19:30 Mail -rw-r--r-- 1 horn horn 4 2009-08-05 20:05 multi line file drwxr-xr-x 7 horn horn 12K 2009-08-05 20:04 News drwxr-xr-x 6 horn horn 4.0K 2009-07-27 20:59 opt --8<---------------cut here---------------end--------------->8--- The listing itself is ok, I'd say. But hitting RET on "multi" says "File no longer exists; type `g' to update dired buffer", and RET on "line" or "file" say "No file on this line". Well, not really a problem, though... Bye, Tassilo ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: imagemagick patch v3 2009-08-05 18:19 ` Tassilo Horn @ 2009-08-05 18:53 ` Eli Zaretskii 2009-08-05 19:49 ` Tassilo Horn 0 siblings, 1 reply; 8+ messages in thread From: Eli Zaretskii @ 2009-08-05 18:53 UTC (permalink / raw) To: Tassilo Horn; +Cc: monnier, joakim, emacs-devel > From: Tassilo Horn <tassilo@member.fsf.org> > Cc: joakim@verona.se, monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Wed, 05 Aug 2009 20:19:00 +0200 > > Unfortunately, dired doesn't work with those files. Here's a > "screenshot": > > --8<---------------cut here---------------start------------->8--- > drwxr-xr-x 2 horn horn 4.0K 2009-06-30 22:32 kvm > drwxr-xr-x 4 horn horn 4.0K 2009-08-05 19:30 Mail > -rw-r--r-- 1 horn horn 4 2009-08-05 20:05 multi > line > file > drwxr-xr-x 7 horn horn 12K 2009-08-05 20:04 News > drwxr-xr-x 6 horn horn 4.0K 2009-07-27 20:59 opt > --8<---------------cut here---------------end--------------->8--- > > The listing itself is ok, I'd say. But hitting RET on "multi" says > "File no longer exists; type `g' to update dired buffer", and RET on > "line" or "file" say "No file on this line". Please file a bug report about these problems in Dired. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: imagemagick patch v3 2009-08-05 18:53 ` Eli Zaretskii @ 2009-08-05 19:49 ` Tassilo Horn 0 siblings, 0 replies; 8+ messages in thread From: Tassilo Horn @ 2009-08-05 19:49 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> Unfortunately, dired doesn't work with those files. Here's a >> "screenshot": >> >> --8<---------------cut here---------------start------------->8--- >> drwxr-xr-x 2 horn horn 4.0K 2009-06-30 22:32 kvm >> drwxr-xr-x 4 horn horn 4.0K 2009-08-05 19:30 Mail >> -rw-r--r-- 1 horn horn 4 2009-08-05 20:05 multi >> line >> file >> drwxr-xr-x 7 horn horn 12K 2009-08-05 20:04 News >> drwxr-xr-x 6 horn horn 4.0K 2009-07-27 20:59 opt >> --8<---------------cut here---------------end--------------->8--- >> >> The listing itself is ok, I'd say. But hitting RET on "multi" says >> "File no longer exists; type `g' to update dired buffer", and RET on >> "line" or "file" say "No file on this line". > > Please file a bug report about these problems in Dired. Done: #4049 Bye, Tassilo ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-08-05 19:49 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-08-04 19:55 imagemagick patch v3 joakim 2009-08-05 0:43 ` joakim 2009-08-05 2:15 ` Stefan Monnier 2009-08-05 8:10 ` joakim 2009-08-05 17:23 ` Eli Zaretskii 2009-08-05 18:19 ` Tassilo Horn 2009-08-05 18:53 ` Eli Zaretskii 2009-08-05 19:49 ` Tassilo Horn
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.