aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChong Yidong2012-06-11 22:42:55 +0800
committerChong Yidong2012-06-11 22:42:55 +0800
commit1b9b4cf4c1152f06153ac9c141fb9f724b984884 (patch)
treec058db7e9bf646a7e40ffefa4c4894665876e821 /src
parent05ecb497393551e8bb65fb07fbdc4bbb5f61765a (diff)
downloademacs-1b9b4cf4c1152f06153ac9c141fb9f724b984884.tar.gz
emacs-1b9b4cf4c1152f06153ac9c141fb9f724b984884.zip
Support transparency for ImageMagick images.
* src/image.c (imagemagick_load_image): Implement transparency. * doc/lispref/display.texi (ImageMagick Images): ImageMagick now supports the :background property.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog4
-rw-r--r--src/image.c113
2 files changed, 61 insertions, 56 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 919dcc10098..1aba1913f46 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
12012-06-11 Chong Yidong <cyd@gnu.org>
2
3 * image.c (imagemagick_load_image): Implement transparency.
4
12012-06-10 Andreas Schwab <schwab@linux-m68k.org> 52012-06-10 Andreas Schwab <schwab@linux-m68k.org>
2 6
3 * regex.c (at_begline_loc_p): Also recognize `(?N:' and correctly 7 * regex.c (at_begline_loc_p): Also recognize `(?N:' and correctly
diff --git a/src/image.c b/src/image.c
index b6cdb6c8290..15fd7bbeab7 100644
--- a/src/image.c
+++ b/src/image.c
@@ -7599,19 +7599,14 @@ imagemagick_load_image (struct frame *f, struct image *img,
7599 unsigned char *contents, unsigned int size, 7599 unsigned char *contents, unsigned int size,
7600 char *filename) 7600 char *filename)
7601{ 7601{
7602 size_t width; 7602 size_t width, height;
7603 size_t height;
7604
7605 MagickBooleanType status; 7603 MagickBooleanType status;
7606
7607 XImagePtr ximg; 7604 XImagePtr ximg;
7608 int x; 7605 int x, y;
7609 int y; 7606 MagickWand *image_wand;
7610 7607 MagickWand *ping_wand;
7611 MagickWand *image_wand;
7612 MagickWand *ping_wand;
7613 PixelIterator *iterator; 7608 PixelIterator *iterator;
7614 PixelWand **pixels; 7609 PixelWand **pixels, *bg_wand = NULL;
7615 MagickPixelPacket pixel; 7610 MagickPixelPacket pixel;
7616 Lisp_Object image; 7611 Lisp_Object image;
7617 Lisp_Object value; 7612 Lisp_Object value;
@@ -7620,10 +7615,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
7620 int desired_width, desired_height; 7615 int desired_width, desired_height;
7621 double rotation; 7616 double rotation;
7622 int pixelwidth; 7617 int pixelwidth;
7623 ImageInfo *image_info;
7624 ExceptionInfo *exception;
7625 Image * im_image;
7626
7627 7618
7628 /* Handle image index for image types who can contain more than one image. 7619 /* Handle image index for image types who can contain more than one image.
7629 Interface :index is same as for GIF. First we "ping" the image to see how 7620 Interface :index is same as for GIF. First we "ping" the image to see how
@@ -7637,14 +7628,9 @@ imagemagick_load_image (struct frame *f, struct image *img,
7637 ping_wand = NewMagickWand (); 7628 ping_wand = NewMagickWand ();
7638 /* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */ 7629 /* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */
7639 7630
7640 if (filename != NULL) 7631 status = filename
7641 { 7632 ? MagickPingImage (ping_wand, filename)
7642 status = MagickPingImage (ping_wand, filename); 7633 : MagickPingImageBlob (ping_wand, contents, size);
7643 }
7644 else
7645 {
7646 status = MagickPingImageBlob (ping_wand, contents, size);
7647 }
7648 7634
7649 if (status == MagickFalse) 7635 if (status == MagickFalse)
7650 { 7636 {
@@ -7653,7 +7639,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
7653 return 0; 7639 return 0;
7654 } 7640 }
7655 7641
7656 if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand))) 7642 if (ino < 0 || ino >= MagickGetNumberImages (ping_wand))
7657 { 7643 {
7658 image_error ("Invalid image number `%s' in image `%s'", 7644 image_error ("Invalid image number `%s' in image `%s'",
7659 image, img->spec); 7645 image, img->spec);
@@ -7670,39 +7656,46 @@ imagemagick_load_image (struct frame *f, struct image *img,
7670 DestroyMagickWand (ping_wand); 7656 DestroyMagickWand (ping_wand);
7671 7657
7672 /* Now we know how many images are inside the file. If it's not a 7658 /* Now we know how many images are inside the file. If it's not a
7673 bundle, the number is one. */ 7659 bundle, the number is one. Load the image data. */
7674
7675 if (filename != NULL)
7676 {
7677 image_info = CloneImageInfo ((ImageInfo *) NULL);
7678 (void) strcpy (image_info->filename, filename);
7679 image_info->number_scenes = 1;
7680 image_info->scene = ino;
7681 exception = AcquireExceptionInfo ();
7682 7660
7683 im_image = ReadImage (image_info, exception); 7661 image_wand = NewMagickWand ();
7684 DestroyExceptionInfo (exception);
7685 7662
7686 if (im_image == NULL) 7663 if ((filename
7687 goto imagemagick_no_wand; 7664 ? MagickReadImage (image_wand, filename)
7688 image_wand = NewMagickWandFromImage (im_image); 7665 : MagickReadImageBlob (image_wand, contents, size))
7689 DestroyImage (im_image); 7666 == MagickFalse)
7690 }
7691 else
7692 { 7667 {
7693 image_wand = NewMagickWand (); 7668 imagemagick_error (image_wand);
7694 if (MagickReadImageBlob (image_wand, contents, size) == MagickFalse) 7669 goto imagemagick_error;
7695 {
7696 imagemagick_error (image_wand);
7697 goto imagemagick_error;
7698 }
7699 } 7670 }
7700 7671
7672 /* Retrieve the frame's background color, for use later. */
7673 {
7674 XColor bgcolor;
7675 Lisp_Object specified_bg;
7676
7677 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
7678 if (!STRINGP (specified_bg)
7679 || !x_defined_color (f, SSDATA (specified_bg), &bgcolor, 0))
7680 {
7681#ifndef HAVE_NS
7682 bgcolor.pixel = FRAME_BACKGROUND_PIXEL (f);
7683 x_query_color (f, &bgcolor);
7684#else
7685 ns_query_color (FRAME_BACKGROUND_COLOR (f), &bgcolor, 1);
7686#endif
7687 }
7688
7689 bg_wand = NewPixelWand ();
7690 PixelSetRed (bg_wand, (double) bgcolor.red / 65535);
7691 PixelSetGreen (bg_wand, (double) bgcolor.green / 65535);
7692 PixelSetBlue (bg_wand, (double) bgcolor.blue / 65535);
7693 }
7694
7701 /* If width and/or height is set in the display spec assume we want 7695 /* If width and/or height is set in the display spec assume we want
7702 to scale to those values. If either h or w is unspecified, the 7696 to scale to those values. If either h or w is unspecified, the
7703 unspecified should be calculated from the specified to preserve 7697 unspecified should be calculated from the specified to preserve
7704 aspect ratio. */ 7698 aspect ratio. */
7705
7706 value = image_spec_value (img->spec, QCwidth, NULL); 7699 value = image_spec_value (img->spec, QCwidth, NULL);
7707 desired_width = (INTEGERP (value) ? XFASTINT (value) : -1); 7700 desired_width = (INTEGERP (value) ? XFASTINT (value) : -1);
7708 value = image_spec_value (img->spec, QCheight, NULL); 7701 value = image_spec_value (img->spec, QCheight, NULL);
@@ -7768,13 +7761,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
7768 value = image_spec_value (img->spec, QCrotation, NULL); 7761 value = image_spec_value (img->spec, QCrotation, NULL);
7769 if (FLOATP (value)) 7762 if (FLOATP (value))
7770 { 7763 {
7771 PixelWand* background = NewPixelWand ();
7772 PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
7773
7774 rotation = extract_float (value); 7764 rotation = extract_float (value);
7775 7765 status = MagickRotateImage (image_wand, bg_wand, rotation);
7776 status = MagickRotateImage (image_wand, background, rotation);
7777 DestroyPixelWand (background);
7778 if (status == MagickFalse) 7766 if (status == MagickFalse)
7779 { 7767 {
7780 image_error ("Imagemagick image rotate failed", Qnil, Qnil); 7768 image_error ("Imagemagick image rotate failed", Qnil, Qnil);
@@ -7788,6 +7776,18 @@ imagemagick_load_image (struct frame *f, struct image *img,
7788 height = MagickGetImageHeight (image_wand); 7776 height = MagickGetImageHeight (image_wand);
7789 width = MagickGetImageWidth (image_wand); 7777 width = MagickGetImageWidth (image_wand);
7790 7778
7779 /* Set the canvas background color to the frame or specified
7780 background, and flatten the image. Note: as of ImageMagick
7781 6.6.0, SVG image transparency is not handled properly
7782 (e.g. etc/images/splash.svg shows a white background always). */
7783 {
7784 MagickWand *new_wand;
7785 MagickSetImageBackgroundColor (image_wand, bg_wand);
7786 new_wand = MagickMergeImageLayers (image_wand, MergeLayer);
7787 DestroyMagickWand (image_wand);
7788 image_wand = new_wand;
7789 }
7790
7791 if (! (width <= INT_MAX && height <= INT_MAX 7791 if (! (width <= INT_MAX && height <= INT_MAX
7792 && check_image_size (f, width, height))) 7792 && check_image_size (f, width, height)))
7793 { 7793 {
@@ -7895,7 +7895,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
7895 width, height, 7895 width, height,
7896 exportdepth, 7896 exportdepth,
7897 pixelwidth, 7897 pixelwidth,
7898 /*&(img->pixmap));*/
7899 ximg->data); 7898 ximg->data);
7900#else 7899#else
7901 image_error ("You don't have MagickExportImagePixels, upgrade ImageMagick!", 7900 image_error ("You don't have MagickExportImagePixels, upgrade ImageMagick!",
@@ -7910,7 +7909,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
7910 free_color_table (); 7909 free_color_table ();
7911#endif /* COLOR_TABLE_SUPPORT */ 7910#endif /* COLOR_TABLE_SUPPORT */
7912 7911
7913
7914 img->width = width; 7912 img->width = width;
7915 img->height = height; 7913 img->height = height;
7916 7914
@@ -7919,9 +7917,10 @@ imagemagick_load_image (struct frame *f, struct image *img,
7919 x_put_x_image (f, ximg, img->pixmap, width, height); 7917 x_put_x_image (f, ximg, img->pixmap, width, height);
7920 x_destroy_x_image (ximg); 7918 x_destroy_x_image (ximg);
7921 7919
7922
7923 /* Final cleanup. image_wand should be the only resource left. */ 7920 /* Final cleanup. image_wand should be the only resource left. */
7924 DestroyMagickWand (image_wand); 7921 DestroyMagickWand (image_wand);
7922 if (bg_wand) DestroyPixelWand (bg_wand);
7923
7925 /* `MagickWandTerminus' terminates the imagemagick environment. */ 7924 /* `MagickWandTerminus' terminates the imagemagick environment. */
7926 MagickWandTerminus (); 7925 MagickWandTerminus ();
7927 7926
@@ -7929,6 +7928,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
7929 7928
7930 imagemagick_error: 7929 imagemagick_error:
7931 DestroyMagickWand (image_wand); 7930 DestroyMagickWand (image_wand);
7931 if (bg_wand) DestroyPixelWand (bg_wand);
7932
7932 imagemagick_no_wand: 7933 imagemagick_no_wand:
7933 MagickWandTerminus (); 7934 MagickWandTerminus ();
7934 /* TODO more cleanup. */ 7935 /* TODO more cleanup. */