aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c535
1 files changed, 534 insertions, 1 deletions
diff --git a/src/image.c b/src/image.c
index 34d89d2e195..ae4bf2fd937 100644
--- a/src/image.c
+++ b/src/image.c
@@ -583,7 +583,7 @@ Lisp_Object Qxbm;
583 583
584Lisp_Object QCascent, QCmargin, QCrelief, Qcount, Qextension_data; 584Lisp_Object QCascent, QCmargin, QCrelief, Qcount, Qextension_data;
585Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; 585Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
586Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask; 586Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask, QCgeometry, QCcrop, QCrotation;
587 587
588/* Other symbols. */ 588/* Other symbols. */
589 589
@@ -7342,6 +7342,510 @@ gif_load (struct frame *f, struct image *img)
7342#endif /* HAVE_GIF */ 7342#endif /* HAVE_GIF */
7343 7343
7344 7344
7345/***********************************************************************
7346 imagemagick
7347***********************************************************************/
7348#if defined (HAVE_IMAGEMAGICK)
7349Lisp_Object Vimagemagick_render_type;
7350
7351/* The symbol `imagemagick' identifying images of this type. */
7352
7353Lisp_Object Qimagemagick;
7354Lisp_Object Vimagemagick_render_type;
7355
7356/* Indices of image specification fields in imagemagick_format, below. */
7357
7358enum imagemagick_keyword_index
7359 {
7360 IMAGEMAGICK_TYPE,
7361 IMAGEMAGICK_DATA,
7362 IMAGEMAGICK_FILE,
7363 IMAGEMAGICK_ASCENT,
7364 IMAGEMAGICK_MARGIN,
7365 IMAGEMAGICK_RELIEF,
7366 IMAGEMAGICK_ALGORITHM,
7367 IMAGEMAGICK_HEURISTIC_MASK,
7368 IMAGEMAGICK_MASK,
7369 IMAGEMAGICK_BACKGROUND,
7370 IMAGEMAGICK_HEIGHT,
7371 IMAGEMAGICK_WIDTH,
7372 IMAGEMAGICK_ROTATION,
7373 IMAGEMAGICK_CROP,
7374 IMAGEMAGICK_LAST
7375 };
7376
7377/* Vector of image_keyword structures describing the format
7378 of valid user-defined image specifications. */
7379
7380static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7381 {
7382 {":type", IMAGE_SYMBOL_VALUE, 1},
7383 {":data", IMAGE_STRING_VALUE, 0},
7384 {":file", IMAGE_STRING_VALUE, 0},
7385 {":ascent", IMAGE_ASCENT_VALUE, 0},
7386 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
7387 {":relief", IMAGE_INTEGER_VALUE, 0},
7388 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7389 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7390 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7391 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
7392 {":height", IMAGE_INTEGER_VALUE, 0},
7393 {":width", IMAGE_INTEGER_VALUE, 0},
7394 {":rotation", IMAGE_NUMBER_VALUE, 0},
7395 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
7396 };
7397/* Free X resources of imagemagick image IMG which is used on frame F. */
7398
7399static void
7400imagemagick_clear_image (struct frame *f,
7401 struct image *img)
7402{
7403 x_clear_image (f, img);
7404}
7405
7406
7407
7408/* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do
7409 this by calling parse_image_spec and supplying the keywords that
7410 identify the IMAGEMAGICK format. */
7411
7412static int
7413imagemagick_image_p (Lisp_Object object)
7414{
7415 struct image_keyword fmt[IMAGEMAGICK_LAST];
7416 bcopy (imagemagick_format, fmt, sizeof fmt);
7417
7418 if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
7419 return 0;
7420
7421 /* Must specify either the :data or :file keyword. */
7422 return fmt[IMAGEMAGICK_FILE].count + fmt[IMAGEMAGICK_DATA].count == 1;
7423}
7424
7425/* The GIF library also defines DrawRectangle, but its never used in Emacs.
7426 Therefore rename the function so it doesnt collide with ImageMagick. */
7427#define DrawRectangle DrawRectangleGif
7428#include <wand/MagickWand.h>
7429
7430/* imagemagick_load_image is a helper function for imagemagick_load,
7431 which does the actual loading given contents and size, apart from
7432 frame and image structures, passed from imagemagick_load.
7433
7434 Uses librimagemagick to do most of the image processing.
7435
7436 non-zero when successful.
7437*/
7438
7439static int
7440imagemagick_load_image (/* Pointer to emacs frame structure. */
7441 struct frame *f,
7442 /* Pointer to emacs image structure. */
7443 struct image *img,
7444 /* String containing the IMAGEMAGICK data to
7445 be parsed. */
7446 unsigned char *contents,
7447 /* Size of data in bytes. */
7448 unsigned int size,
7449 /* Filename, either pass filename or
7450 contents/size. */
7451 unsigned char *filename)
7452{
7453 size_t width;
7454 size_t height;
7455
7456 MagickBooleanType
7457 status;
7458
7459 XImagePtr ximg;
7460 Lisp_Object specified_bg;
7461 XColor background;
7462 int x;
7463 int y;
7464
7465 MagickWand *image_wand;
7466 MagickWand *ping_wand;
7467 PixelIterator *iterator;
7468 PixelWand **pixels;
7469 MagickPixelPacket pixel;
7470 Lisp_Object image;
7471 Lisp_Object value;
7472 Lisp_Object crop, geometry;
7473 long ino;
7474 int desired_width, desired_height;
7475 double rotation;
7476 int imagemagick_rendermethod;
7477 int pixelwidth;
7478 ImageInfo *image_info;
7479 ExceptionInfo *exception;
7480 Image * im_image;
7481
7482
7483 /* Handle image index for image types who can contain more than one
7484 image. Interface :index is same as for GIF. First we "ping" the
7485 image to see how many sub-images it contains. Pinging is faster
7486 than loading the image to find out things about it. */
7487 image = image_spec_value (img->spec, QCindex, NULL);
7488 ino = INTEGERP (image) ? XFASTINT (image) : 0;
7489 ping_wand=NewMagickWand();
7490 MagickSetResolution(ping_wand, 2, 2);
7491 if (filename != NULL)
7492 {
7493 status = MagickPingImage(ping_wand, filename);
7494 }
7495 else
7496 {
7497 status = MagickPingImageBlob(ping_wand, contents, size);
7498 }
7499
7500 if (ino >= MagickGetNumberImages(ping_wand))
7501 {
7502 image_error ("Invalid image number `%s' in image `%s'",
7503 image, img->spec);
7504 UNGCPRO;
7505 return 0;
7506 }
7507
7508 if (MagickGetNumberImages(ping_wand) > 1)
7509 img->data.lisp_val =
7510 Fcons (Qcount,
7511 Fcons (make_number (MagickGetNumberImages(ping_wand)),
7512 img->data.lisp_val));
7513
7514 DestroyMagickWand (ping_wand);
7515 /* Now, after pinging, we know how many images are inside the
7516 file. If its not a bundle, just one. */
7517
7518 if (filename != NULL)
7519 {
7520 image_info=CloneImageInfo((ImageInfo *) NULL);
7521 (void) strcpy(image_info->filename, filename);
7522 image_info -> number_scenes = 1;
7523 image_info -> scene = ino;
7524 exception=AcquireExceptionInfo();
7525
7526 im_image = ReadImage (image_info, exception);
7527 CatchException(exception);
7528
7529 image_wand = NewMagickWandFromImage(im_image);
7530 }
7531 else
7532 {
7533 image_wand = NewMagickWand();
7534 status = MagickReadImageBlob(image_wand, contents, size);
7535 }
7536 image_error ("im read failed", Qnil, Qnil);
7537 if (status == MagickFalse) goto imagemagick_error;
7538
7539 /* If width and/or height is set in the display spec assume we want
7540 to scale to those values. if either h or w is unspecified, the
7541 unspecified should be calculated from the specified to preserve
7542 aspect ratio. */
7543
7544 value = image_spec_value (img->spec, QCwidth, NULL);
7545 desired_width = (INTEGERP (value) ? XFASTINT (value) : -1);
7546 value = image_spec_value (img->spec, QCheight, NULL);
7547 desired_height = (INTEGERP (value) ? XFASTINT (value) : -1);
7548
7549 height = MagickGetImageHeight (image_wand);
7550 width = MagickGetImageWidth (image_wand);
7551
7552 if(desired_width != -1 && desired_height == -1)
7553 {
7554 /* w known, calculate h. */
7555 desired_height = ( (double)desired_width / width ) * height;
7556 }
7557 if(desired_width == -1 && desired_height != -1)
7558 {
7559 /* h known, calculate w. */
7560 desired_width = ( (double)desired_height / height ) * width;
7561 }
7562 if(desired_width != -1 && desired_height != -1)
7563 {
7564 status = MagickScaleImage(image_wand, desired_width, desired_height);
7565 if (status == MagickFalse) {
7566 image_error ("Imagemagick scale failed", Qnil, Qnil);
7567 goto imagemagick_error;
7568 }
7569 }
7570
7571
7572 /* crop behaves similar to image slicing in Emacs but is more memory
7573 efficient */
7574 crop = image_spec_value (img->spec, QCcrop, NULL);
7575
7576 if(CONSP (crop))
7577 {
7578 /*
7579 after some testing, it seems MagickCropImage is the fastest
7580 crop function in ImageMagick. This crop function seems to do
7581 less copying than the alternatives, but it still reads the
7582 entire image into memory before croping, which is aparently
7583 difficult to avoid when using imagemagick. */
7584
7585 int w,h,x,y;
7586 w=XFASTINT(XCAR(crop));
7587 h=XFASTINT(XCAR(XCDR(crop)));
7588 x=XFASTINT(XCAR(XCDR(XCDR(crop))));
7589 y=XFASTINT(XCAR(XCDR(XCDR(XCDR(crop)))));
7590 MagickCropImage(image_wand, w,h, x,y);
7591 }
7592
7593 /* Furthermore :rotation. we need background color and angle for
7594 rotation. */
7595 /*
7596 TODO background handling for rotation specified_bg =
7597 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
7598 (specified_bg). */
7599 value = image_spec_value (img->spec, QCrotation, NULL);
7600 if (FLOATP (value))
7601 {
7602 PixelWand* background = NewPixelWand();
7603 PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
7604
7605 rotation = extract_float (value);
7606
7607 status = MagickRotateImage (image_wand, background, rotation);
7608 DestroyPixelWand (background);
7609 if (status == MagickFalse)
7610 {
7611 image_error ("Imagemagick image rotate failed", Qnil, Qnil);
7612 goto imagemagick_error;
7613 }
7614 }
7615
7616 /* Finaly we are done manipulating the image, figure out resulting
7617 width, height, and then transfer ownerwship to Emacs. */
7618 height = MagickGetImageHeight (image_wand);
7619 width = MagickGetImageWidth (image_wand);
7620 if (status == MagickFalse)
7621 {
7622 image_error ("Imagemagick image get size failed", Qnil, Qnil);
7623 goto imagemagick_error;
7624 }
7625
7626 if (! check_image_size (f, width, height))
7627 {
7628 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7629 goto imagemagick_error;
7630 }
7631
7632 /* We can now get a valid pixel buffer from the imagemagick file, if all
7633 went ok. */
7634
7635 init_color_table ();
7636 imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
7637 ? XFASTINT (Vimagemagick_render_type) : 0);
7638 if (imagemagick_rendermethod == 0)
7639 {
7640 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7641 if (!x_create_x_image_and_pixmap (f, width, height, 0,
7642 &ximg, &img->pixmap))
7643 {
7644 image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
7645 goto imagemagick_error;
7646 }
7647
7648 /* Copy imagegmagick image to x with primitive yet robust pixel
7649 pusher loop. This has been tested a lot with many different
7650 images. */
7651
7652 /* Copy pixels from the imagemagick image structure to the x image map. */
7653 iterator = NewPixelIterator (image_wand);
7654 if ((iterator == (PixelIterator *) NULL))
7655 {
7656 image_error ("Imagemagick pixel iterator creation failed",
7657 Qnil, Qnil);
7658 goto imagemagick_error;
7659 }
7660
7661 for (y = 0; y < (long) MagickGetImageHeight(image_wand); y++)
7662 {
7663 pixels = PixelGetNextIteratorRow (iterator, &width);
7664 if ((pixels == (PixelWand **) NULL))
7665 break;
7666 for (x = 0; x < (long) width; x++)
7667 {
7668 PixelGetMagickColor (pixels[x], &pixel);
7669 XPutPixel (ximg, x, y,
7670 lookup_rgb_color (f,
7671 pixel.red,
7672 pixel.green,
7673 pixel.blue));
7674 }
7675 }
7676 DestroyPixelIterator (iterator);
7677 }
7678
7679 if (imagemagick_rendermethod == 1)
7680 {
7681 /* Magicexportimage is normaly faster than pixelpushing. This
7682 method is also well tested. Some aspects of this method are
7683 ad-hoc and needs to be more researched. */
7684 int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/
7685 char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
7686 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7687 if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
7688 &ximg, &img->pixmap)){
7689 image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
7690 goto imagemagick_error;
7691 }
7692
7693
7694 /* Oddly, the below code doesnt seem to work:*/
7695 /* switch(ximg->bitmap_unit){ */
7696 /* case 8: */
7697 /* pixelwidth=CharPixel; */
7698 /* break; */
7699 /* case 16: */
7700 /* pixelwidth=ShortPixel; */
7701 /* break; */
7702 /* case 32: */
7703 /* pixelwidth=LongPixel; */
7704 /* break; */
7705 /* } */
7706 /*
7707 Here im just guessing the format of the bitmap.
7708 happens to work fine for:
7709 - bw djvu images
7710 on rgb display.
7711 seems about 3 times as fast as pixel pushing(not carefully measured)
7712 */
7713 pixelwidth = CharPixel;/*??? TODO figure out*/
7714#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
7715 MagickExportImagePixels(image_wand,
7716 0, 0,
7717 width, height,
7718 exportdepth,
7719 pixelwidth,
7720 /*&(img->pixmap));*/
7721 ximg->data);
7722#else
7723 image_error("You dont have MagickExportImagePixels, upgrade ImageMagick!",
7724 Qnil, Qnil);
7725#endif
7726 }
7727
7728
7729#ifdef COLOR_TABLE_SUPPORT
7730 /* Remember colors allocated for this image. */
7731 img->colors = colors_in_color_table (&img->ncolors);
7732 free_color_table ();
7733#endif /* COLOR_TABLE_SUPPORT */
7734
7735
7736 img->width = width;
7737 img->height = height;
7738
7739 /* Put the image into the pixmap, then free the X image and its
7740 buffer. */
7741 x_put_x_image (f, ximg, img->pixmap, width, height);
7742 x_destroy_x_image (ximg);
7743
7744
7745 /* Final cleanup. image_wand should be the only resource left. */
7746 DestroyMagickWand (image_wand);
7747
7748 return 1;
7749
7750 imagemagick_error:
7751 /* TODO more cleanup. */
7752 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
7753 return 0;
7754}
7755
7756
7757/* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if
7758 successful. this function will go into the imagemagick_type structure, and
7759 the prototype thus needs to be compatible with that structure. */
7760
7761static int
7762imagemagick_load (struct frame *f,
7763 struct image *img)
7764{
7765 int success_p = 0;
7766 Lisp_Object file_name;
7767
7768 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7769 file_name = image_spec_value (img->spec, QCfile, NULL);
7770 if (STRINGP (file_name))
7771 {
7772 Lisp_Object file;
7773 unsigned char *contents;
7774 int size;
7775 struct gcpro gcpro1;
7776
7777 file = x_find_image_file (file_name);
7778 GCPRO1 (file);
7779 if (!STRINGP (file))
7780 {
7781 image_error ("Cannot find image file `%s'", file_name, Qnil);
7782 UNGCPRO;
7783 return 0;
7784 }
7785 success_p = imagemagick_load_image (f, img, 0, 0, SDATA(file_name));
7786 UNGCPRO;
7787 }
7788 /* Else its not a file, its a lisp object. Load the image from a
7789 lisp object rather than a file. */
7790 else
7791 {
7792 Lisp_Object data;
7793
7794 data = image_spec_value (img->spec, QCdata, NULL);
7795 success_p = imagemagick_load_image (f, img, SDATA (data),
7796 SBYTES (data), NULL);
7797 }
7798
7799 return success_p;
7800}
7801
7802/* Structure describing the image type `imagemagick'. Its the same
7803 type of structure defined for all image formats, handled by Emacs
7804 image functions. See struct image_type in dispextern.h. */
7805
7806static struct image_type imagemagick_type =
7807 {
7808 /* An identifier showing that this is an image structure for the
7809 IMAGEMAGICK format. */
7810 &Qimagemagick,
7811 /* Handle to a function that can be used to identify a IMAGEMAGICK
7812 file. */
7813 imagemagick_image_p,
7814 /* Handle to function used to load a IMAGEMAGICK file. */
7815 imagemagick_load,
7816 /* Handle to function to free resources for IMAGEMAGICK. */
7817 imagemagick_clear_image,
7818 /* An internal field to link to the next image type in a list of
7819 image types, will be filled in when registering the format. */
7820 NULL
7821 };
7822
7823
7824
7825
7826DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
7827 doc: /* Return image file types supported by ImageMagick.
7828 Since ImageMagick recognizes a lot of file-types that clash with Emacs,
7829 such as .c, we want to be able to alter the list at the lisp level. */)
7830 (void)
7831{
7832 Lisp_Object typelist = Qnil;
7833 size_t numf;
7834 ExceptionInfo ex;
7835 char** imtypes = GetMagickList ("*", &numf, &ex);
7836 int i;
7837 Lisp_Object Qimagemagicktype;
7838 for (i = 0; i < numf; i++)
7839 {
7840 Qimagemagicktype = intern (imtypes[i]);
7841 typelist = Fcons (Qimagemagicktype, typelist);
7842 }
7843 return typelist;
7844}
7845
7846#endif /* defined (HAVE_IMAGEMAGICK) */
7847
7848
7345 7849
7346/*********************************************************************** 7850/***********************************************************************
7347 SVG 7851 SVG
@@ -8117,6 +8621,15 @@ of `image-library-alist', which see). */)
8117 return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries); 8621 return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries);
8118#endif 8622#endif
8119 8623
8624#if defined (HAVE_IMAGEMAGICK)
8625 if (EQ (type, Qimagemagick)){
8626 /* MagickWandGenesis() initalizes the imagemagick library. */
8627 MagickWandGenesis();
8628 return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
8629 libraries);
8630 }
8631#endif
8632
8120#ifdef HAVE_GHOSTSCRIPT 8633#ifdef HAVE_GHOSTSCRIPT
8121 if (EQ (type, Qpostscript)) 8634 if (EQ (type, Qpostscript))
8122 return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries); 8635 return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
@@ -8202,6 +8715,12 @@ non-numeric, there is no explicit limit on the size of images. */);
8202 staticpro (&QCheuristic_mask); 8715 staticpro (&QCheuristic_mask);
8203 QCindex = intern_c_string (":index"); 8716 QCindex = intern_c_string (":index");
8204 staticpro (&QCindex); 8717 staticpro (&QCindex);
8718 QCgeometry = intern (":geometry");
8719 staticpro (&QCgeometry);
8720 QCcrop = intern (":crop");
8721 staticpro (&QCcrop);
8722 QCrotation = intern (":rotation");
8723 staticpro (&QCrotation);
8205 QCmatrix = intern_c_string (":matrix"); 8724 QCmatrix = intern_c_string (":matrix");
8206 staticpro (&QCmatrix); 8725 staticpro (&QCmatrix);
8207 QCcolor_adjustment = intern_c_string (":color-adjustment"); 8726 QCcolor_adjustment = intern_c_string (":color-adjustment");
@@ -8262,6 +8781,12 @@ non-numeric, there is no explicit limit on the size of images. */);
8262 ADD_IMAGE_TYPE (Qpng); 8781 ADD_IMAGE_TYPE (Qpng);
8263#endif 8782#endif
8264 8783
8784#if defined (HAVE_IMAGEMAGICK)
8785 Qimagemagick = intern ("imagemagick");
8786 staticpro (&Qimagemagick);
8787 ADD_IMAGE_TYPE (Qimagemagick);
8788#endif
8789
8265#if defined (HAVE_RSVG) 8790#if defined (HAVE_RSVG)
8266 Qsvg = intern_c_string ("svg"); 8791 Qsvg = intern_c_string ("svg");
8267 staticpro (&Qsvg); 8792 staticpro (&Qsvg);
@@ -8278,6 +8803,9 @@ non-numeric, there is no explicit limit on the size of images. */);
8278#endif /* HAVE_RSVG */ 8803#endif /* HAVE_RSVG */
8279 8804
8280 defsubr (&Sinit_image_library); 8805 defsubr (&Sinit_image_library);
8806#ifdef HAVE_IMAGEMAGICK
8807 defsubr (&Simagemagick_types);
8808#endif
8281 defsubr (&Sclear_image_cache); 8809 defsubr (&Sclear_image_cache);
8282 defsubr (&Simage_flush); 8810 defsubr (&Simage_flush);
8283 defsubr (&Simage_size); 8811 defsubr (&Simage_size);
@@ -8308,6 +8836,11 @@ The value can also be nil, meaning the cache is never cleared.
8308 8836
8309The function `clear-image-cache' disregards this variable. */); 8837The function `clear-image-cache' disregards this variable. */);
8310 Vimage_cache_eviction_delay = make_number (300); 8838 Vimage_cache_eviction_delay = make_number (300);
8839#ifdef HAVE_IMAGEMAGICK
8840 DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type,
8841 doc: /* Choose between ImageMagick render methods. */);
8842#endif
8843
8311} 8844}
8312 8845
8313void 8846void