aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c215
1 files changed, 105 insertions, 110 deletions
diff --git a/src/image.c b/src/image.c
index b6cdb6c8290..bd3a0822fe9 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 7660
7675 if (filename != NULL) 7661 image_wand = NewMagickWand ();
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
7683 im_image = ReadImage (image_info, exception);
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,22 @@ 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#ifdef HAVE_MAGICKMERGEIMAGELAYERS
7787 new_wand = MagickMergeImageLayers (image_wand, MergeLayer);
7788#else
7789 new_wand = MagickFlattenImages (image_wand);
7790#endif
7791 DestroyMagickWand (image_wand);
7792 image_wand = new_wand;
7793 }
7794
7791 if (! (width <= INT_MAX && height <= INT_MAX 7795 if (! (width <= INT_MAX && height <= INT_MAX
7792 && check_image_size (f, width, height))) 7796 && check_image_size (f, width, height)))
7793 { 7797 {
@@ -7800,7 +7804,50 @@ imagemagick_load_image (struct frame *f, struct image *img,
7800 7804
7801 init_color_table (); 7805 init_color_table ();
7802 7806
7803 if (imagemagick_render_type == 0) 7807#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
7808 if (imagemagick_render_type != 0)
7809 {
7810 /* Magicexportimage is normally faster than pixelpushing. This
7811 method is also well tested. Some aspects of this method are
7812 ad-hoc and needs to be more researched. */
7813 int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/
7814 const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/
7815 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7816 if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
7817 &ximg, &img->pixmap))
7818 {
7819#ifdef COLOR_TABLE_SUPPORT
7820 free_color_table ();
7821#endif
7822 image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
7823 goto imagemagick_error;
7824 }
7825
7826 /* Oddly, the below code doesn't seem to work:*/
7827 /* switch(ximg->bitmap_unit){ */
7828 /* case 8: */
7829 /* pixelwidth=CharPixel; */
7830 /* break; */
7831 /* case 16: */
7832 /* pixelwidth=ShortPixel; */
7833 /* break; */
7834 /* case 32: */
7835 /* pixelwidth=LongPixel; */
7836 /* break; */
7837 /* } */
7838 /*
7839 Here im just guessing the format of the bitmap.
7840 happens to work fine for:
7841 - bw djvu images
7842 on rgb display.
7843 seems about 3 times as fast as pixel pushing(not carefully measured)
7844 */
7845 pixelwidth = CharPixel; /*??? TODO figure out*/
7846 MagickExportImagePixels (image_wand, 0, 0, width, height,
7847 exportdepth, pixelwidth, ximg->data);
7848 }
7849 else
7850#endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
7804 { 7851 {
7805 size_t image_height; 7852 size_t image_height;
7806 7853
@@ -7850,59 +7897,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
7850 } 7897 }
7851 DestroyPixelIterator (iterator); 7898 DestroyPixelIterator (iterator);
7852 } 7899 }
7853 else /* imagemagick_render_type != 0 */
7854 {
7855 /* Magicexportimage is normally faster than pixelpushing. This
7856 method is also well tested. Some aspects of this method are
7857 ad-hoc and needs to be more researched. */
7858 int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/
7859 const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
7860 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7861 if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
7862 &ximg, &img->pixmap))
7863 {
7864#ifdef COLOR_TABLE_SUPPORT
7865 free_color_table ();
7866#endif
7867 image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
7868 goto imagemagick_error;
7869 }
7870
7871
7872 /* Oddly, the below code doesn't seem to work:*/
7873 /* switch(ximg->bitmap_unit){ */
7874 /* case 8: */
7875 /* pixelwidth=CharPixel; */
7876 /* break; */
7877 /* case 16: */
7878 /* pixelwidth=ShortPixel; */
7879 /* break; */
7880 /* case 32: */
7881 /* pixelwidth=LongPixel; */
7882 /* break; */
7883 /* } */
7884 /*
7885 Here im just guessing the format of the bitmap.
7886 happens to work fine for:
7887 - bw djvu images
7888 on rgb display.
7889 seems about 3 times as fast as pixel pushing(not carefully measured)
7890 */
7891 pixelwidth = CharPixel;/*??? TODO figure out*/
7892#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
7893 MagickExportImagePixels (image_wand,
7894 0, 0,
7895 width, height,
7896 exportdepth,
7897 pixelwidth,
7898 /*&(img->pixmap));*/
7899 ximg->data);
7900#else
7901 image_error ("You don't have MagickExportImagePixels, upgrade ImageMagick!",
7902 Qnil, Qnil);
7903#endif
7904 }
7905
7906 7900
7907#ifdef COLOR_TABLE_SUPPORT 7901#ifdef COLOR_TABLE_SUPPORT
7908 /* Remember colors allocated for this image. */ 7902 /* Remember colors allocated for this image. */
@@ -7910,7 +7904,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
7910 free_color_table (); 7904 free_color_table ();
7911#endif /* COLOR_TABLE_SUPPORT */ 7905#endif /* COLOR_TABLE_SUPPORT */
7912 7906
7913
7914 img->width = width; 7907 img->width = width;
7915 img->height = height; 7908 img->height = height;
7916 7909
@@ -7919,9 +7912,10 @@ imagemagick_load_image (struct frame *f, struct image *img,
7919 x_put_x_image (f, ximg, img->pixmap, width, height); 7912 x_put_x_image (f, ximg, img->pixmap, width, height);
7920 x_destroy_x_image (ximg); 7913 x_destroy_x_image (ximg);
7921 7914
7922
7923 /* Final cleanup. image_wand should be the only resource left. */ 7915 /* Final cleanup. image_wand should be the only resource left. */
7924 DestroyMagickWand (image_wand); 7916 DestroyMagickWand (image_wand);
7917 if (bg_wand) DestroyPixelWand (bg_wand);
7918
7925 /* `MagickWandTerminus' terminates the imagemagick environment. */ 7919 /* `MagickWandTerminus' terminates the imagemagick environment. */
7926 MagickWandTerminus (); 7920 MagickWandTerminus ();
7927 7921
@@ -7929,7 +7923,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
7929 7923
7930 imagemagick_error: 7924 imagemagick_error:
7931 DestroyMagickWand (image_wand); 7925 DestroyMagickWand (image_wand);
7932 imagemagick_no_wand: 7926 if (bg_wand) DestroyPixelWand (bg_wand);
7927
7933 MagickWandTerminus (); 7928 MagickWandTerminus ();
7934 /* TODO more cleanup. */ 7929 /* TODO more cleanup. */
7935 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil); 7930 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);