* 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.