comparison src/image.c @ 109860:c92f5e6103a8

mostly cosmetic, moving { instances, changing indentation accordingly.
author Joakim <joakim@localhost.localdomain>
date Mon, 14 Jun 2010 15:57:48 +0200
parents 68616bb3ae25
children 8e0241dfb81c
comparison
equal deleted inserted replaced
109859:68616bb3ae25 109860:c92f5e6103a8
7567 #endif /* HAVE_GIF */ 7567 #endif /* HAVE_GIF */
7568 7568
7569 7569
7570 /*********************************************************************** 7570 /***********************************************************************
7571 imagemagick 7571 imagemagick
7572 ***********************************************************************/ 7572 ***********************************************************************/
7573 #if defined (HAVE_IMAGEMAGICK) 7573 #if defined (HAVE_IMAGEMAGICK)
7574 Lisp_Object Vimagemagick_render_type; 7574 Lisp_Object Vimagemagick_render_type;
7575 /* Function prototypes. */
7576
7577 static int imagemagick_image_p (Lisp_Object object);
7578 static int imagemagick_load (struct frame *f, struct image *img);
7579
7580 static int imagemagick_load_image (struct frame *, struct image *,
7581 unsigned char *, unsigned int, unsigned char *);
7582 7575
7583 /* The symbol `imagemagick' identifying images of this type. */ 7576 /* The symbol `imagemagick' identifying images of this type. */
7584 7577
7585 Lisp_Object Qimagemagick; 7578 Lisp_Object Qimagemagick;
7586 Lisp_Object Vimagemagick_render_type; 7579 Lisp_Object Vimagemagick_render_type;
7587 7580
7588 /* Indices of image specification fields in imagemagick_format, below. */ 7581 /* Indices of image specification fields in imagemagick_format, below. */
7589 7582
7590 enum imagemagick_keyword_index 7583 enum imagemagick_keyword_index
7591 { 7584 {
7592 IMAGEMAGICK_TYPE, 7585 IMAGEMAGICK_TYPE,
7593 IMAGEMAGICK_DATA, 7586 IMAGEMAGICK_DATA,
7594 IMAGEMAGICK_FILE, 7587 IMAGEMAGICK_FILE,
7595 IMAGEMAGICK_ASCENT, 7588 IMAGEMAGICK_ASCENT,
7596 IMAGEMAGICK_MARGIN, 7589 IMAGEMAGICK_MARGIN,
7597 IMAGEMAGICK_RELIEF, 7590 IMAGEMAGICK_RELIEF,
7598 IMAGEMAGICK_ALGORITHM, 7591 IMAGEMAGICK_ALGORITHM,
7599 IMAGEMAGICK_HEURISTIC_MASK, 7592 IMAGEMAGICK_HEURISTIC_MASK,
7600 IMAGEMAGICK_MASK, 7593 IMAGEMAGICK_MASK,
7601 IMAGEMAGICK_BACKGROUND, 7594 IMAGEMAGICK_BACKGROUND,
7602 IMAGEMAGICK_LAST 7595 IMAGEMAGICK_LAST
7603 }; 7596 };
7604 7597
7605 /* Vector of image_keyword structures describing the format 7598 /* Vector of image_keyword structures describing the format
7606 of valid user-defined image specifications. */ 7599 of valid user-defined image specifications. */
7607 7600
7608 static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = 7601 static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7609 { 7602 {
7610 {":type", IMAGE_SYMBOL_VALUE, 1}, 7603 {":type", IMAGE_SYMBOL_VALUE, 1},
7611 {":data", IMAGE_STRING_VALUE, 0}, 7604 {":data", IMAGE_STRING_VALUE, 0},
7612 {":file", IMAGE_STRING_VALUE, 0}, 7605 {":file", IMAGE_STRING_VALUE, 0},
7613 {":ascent", IMAGE_ASCENT_VALUE, 0}, 7606 {":ascent", IMAGE_ASCENT_VALUE, 0},
7614 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 7607 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
7615 {":relief", IMAGE_INTEGER_VALUE, 0}, 7608 {":relief", IMAGE_INTEGER_VALUE, 0},
7616 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7609 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7617 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7610 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7618 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7611 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7619 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 7612 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7620 }; 7613 };
7621 /* Free X resources of imagemagick image IMG which is used on frame F. */ 7614 /* Free X resources of imagemagick image IMG which is used on frame F. */
7622 7615
7623 static void 7616 static void
7624 imagemagick_clear_image (f, img) 7617 imagemagick_clear_image (struct frame *f,
7625 struct frame *f; 7618 struct image *img)
7626 struct image *img;
7627 { 7619 {
7628 printf("clearing imagemagick image\n"); 7620 printf("clearing imagemagick image\n");
7629 x_clear_image (f, img); 7621 x_clear_image (f, img);
7630 } 7622 }
7631 7623
7632 /* Structure describing the image type `imagemagick'. Its the same type of
7633 structure defined for all image formats, handled by Emacs image
7634 functions. See struct image_type in dispextern.h. */
7635
7636 static struct image_type imagemagick_type =
7637 {
7638 /* An identifier showing that this is an image structure for the IMAGEMAGICK format. */
7639 &Qimagemagick,
7640 /* Handle to a function that can be used to identify a IMAGEMAGICK file. */
7641 imagemagick_image_p,
7642 /* Handle to function used to load a IMAGEMAGICK file. */
7643 imagemagick_load,
7644 /* Handle to function to free resources for IMAGEMAGICK. */
7645 imagemagick_clear_image,
7646 /* An internal field to link to the next image type in a list of
7647 image types, will be filled in when registering the format. */
7648 NULL
7649 };
7650 7624
7651 7625
7652 /* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do 7626 /* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do
7653 this by calling parse_image_spec and supplying the keywords that 7627 this by calling parse_image_spec and supplying the keywords that
7654 identify the IMAGEMAGICK format. */ 7628 identify the IMAGEMAGICK format. */
7655 7629
7656 static int 7630 static int
7657 imagemagick_image_p (object) 7631 imagemagick_image_p (Lisp_Object object)
7658 Lisp_Object object;
7659 { 7632 {
7660 struct image_keyword fmt[IMAGEMAGICK_LAST]; 7633 struct image_keyword fmt[IMAGEMAGICK_LAST];
7661 bcopy (imagemagick_format, fmt, sizeof fmt); 7634 bcopy (imagemagick_format, fmt, sizeof fmt);
7662 7635
7663 if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick)) 7636 if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
7670 /* The GIF library also defines DrawRectangle, but its never used in Emacs. 7643 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
7671 Therefore rename the function so it doesnt collide with ImageMagick. */ 7644 Therefore rename the function so it doesnt collide with ImageMagick. */
7672 #define DrawRectangle DrawRectangleGif 7645 #define DrawRectangle DrawRectangleGif
7673 #include <wand/MagickWand.h> 7646 #include <wand/MagickWand.h>
7674 7647
7648 /* imagemagick_load_image is a helper function for imagemagick_load, which does the
7649 actual loading given contents and size, apart from frame and image
7650 structures, passed from imagemagick_load.
7651
7652 Uses librimagemagick to do most of the image processing.
7653
7654 Returns non-zero when successful.
7655 */
7656
7657 static int
7658 imagemagick_load_image (struct frame *f, /* Pointer to emacs frame structure. */
7659 struct image *img, /* Pointer to emacs image structure. */
7660 unsigned char *contents,/* String containing the IMAGEMAGICK data to be parsed. */
7661 unsigned int size, /* Size of data in bytes. */
7662 unsigned char *filename)/* Filename, either pass filename or contents/size. */
7663 {
7664 long unsigned int width;
7665 long unsigned int height;
7666
7667 MagickBooleanType
7668 status;
7669
7670 XImagePtr ximg;
7671 Lisp_Object specified_bg;
7672 XColor background;
7673 int x;
7674 int y;
7675
7676 MagickWand *image_wand;
7677 PixelIterator *iterator;
7678 PixelWand **pixels;
7679 MagickPixelPacket pixel;
7680 Lisp_Object image;
7681 Lisp_Object value;
7682 Lisp_Object crop, geometry;
7683 long ino;
7684 int desired_width, desired_height;
7685 double rotation;
7686 int imagemagick_rendermethod;
7687 int pixelwidth;
7688
7689
7690 /* image_wand will contain the image. */
7691 image_wand = NewMagickWand();
7692
7693 /* Parse the contents argument and initialize image_wand. */
7694 if(filename != NULL)
7695 status = MagickReadImage(image_wand, filename);
7696 else
7697 status = MagickReadImageBlob(image_wand, contents, size);
7698 image_error ("im read failed", Qnil, Qnil);
7699 if (status == MagickFalse) goto imagemagick_error;
7700
7701 /* Handle image index for image types who can contain more than one image.
7702 Interface :index is same as for GIF. */
7703
7704 image = image_spec_value (img->spec, QCindex, NULL);
7705 ino = INTEGERP (image) ? XFASTINT (image) : 0;
7706
7707
7708
7709 if (ino >= MagickGetNumberImages(image_wand))
7710 {
7711 image_error ("Invalid image number `%s' in image `%s'",
7712 image, img->spec);
7713 UNGCPRO;
7714 return 0;
7715 }
7716
7717
7718 if (MagickGetNumberImages(image_wand) > 1)
7719 img->data.lisp_val = Fcons (Qcount,
7720 Fcons (make_number (MagickGetNumberImages(image_wand)),
7721 img->data.lisp_val));
7722 if(ino == 0)
7723 MagickSetFirstIterator(image_wand);
7724 else
7725 MagickSetIteratorIndex(image_wand, ino);
7726
7727 /*
7728 If width and/or height is set in the display spec
7729 assume we want to scale to those. */
7730
7731 value = image_spec_value (img->spec, QCwidth, NULL);
7732 desired_width = (INTEGERP (value) ? XFASTINT (value) : -1);
7733 value = image_spec_value (img->spec, QCheight, NULL);
7734 desired_height = (INTEGERP (value) ? XFASTINT (value) : -1);
7735 if(desired_width != -1 && desired_height != -1)
7736 {
7737 printf("MagickScaleImage %d %d\n", desired_width, desired_height);
7738 status = MagickScaleImage(image_wand, desired_width, desired_height);
7739 if (status == MagickFalse) {
7740 image_error ("Imagemagick scale failed", Qnil, Qnil);
7741 goto imagemagick_error;
7742 }
7743 }
7744
7745 /* Also support :geometry and :crop which are imagemagick specific descriptors. */
7746
7747 crop = image_spec_value (img->spec, QCcrop, NULL);
7748 geometry = image_spec_value (img->spec, QCgeometry, NULL);
7749 if (STRINGP (crop) && STRINGP (geometry))
7750 {
7751 printf("MagickTransformImage %s %s\n", SDATA(crop), SDATA(geometry));
7752 image_wand = MagickTransformImage (image_wand, SDATA (crop), SDATA (geometry));
7753 /* TODO differ between image_wand and transform_wand. */
7754 }
7755
7756 /* Furthermore :rotation. we need background color and angle for rotation. */
7757 /*
7758 TODO background handling for rotation
7759 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
7760 if (!STRINGP (specified_bg)
7761 */
7762 value = image_spec_value (img->spec, QCrotation, NULL);
7763 if (FLOATP (value))
7764 {
7765 PixelWand* background = NewPixelWand();
7766 PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
7767
7768 rotation = extract_float (value);
7769 printf ("MagickRotateImage %f\n", rotation);
7770
7771 status = MagickRotateImage (image_wand, background, rotation);
7772 DestroyPixelWand (background);
7773 if (status == MagickFalse)
7774 {
7775 image_error ("Imagemagick image rotate failed", Qnil, Qnil);
7776 goto imagemagick_error;
7777 }
7778 }
7779
7780 /* Finaly we are done manipulating the image,
7781 figure out resulting width, height, and then transfer ownerwship to Emacs.
7782 */
7783 height = MagickGetImageHeight (image_wand);
7784 width = MagickGetImageWidth (image_wand);
7785 if (status == MagickFalse)
7786 {
7787 image_error ("Imagemagick image get size failed", Qnil, Qnil);
7788 goto imagemagick_error;
7789 }
7790
7791 if (! check_image_size (f, width, height))
7792 {
7793 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7794 goto imagemagick_error;
7795 }
7796
7797 /* We can now get a valid pixel buffer from the imagemagick file, if all
7798 went ok. */
7799
7800
7801 init_color_table ();
7802 imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type) ? XFASTINT (Vimagemagick_render_type) : 0);
7803 if (imagemagick_rendermethod == 0)
7804 {
7805 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7806 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7807 {
7808 image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
7809 goto imagemagick_error;
7810 }
7811
7812 /* Copy imagegmagick image to x with primitive yet robust pixel
7813 pusher loop. This has been tested a lot with many different
7814 images, it doesnt work too well with image archive formats though!
7815
7816 Also seems slow.
7817 */
7818
7819 /* Copy pixels from the imagemagick image structure to the x image map. */
7820 iterator = NewPixelIterator (image_wand);
7821 if ((iterator == (PixelIterator *) NULL))
7822 {
7823 image_error ("Imagemagick pixel iterator creation failed", Qnil, Qnil);
7824 goto imagemagick_error;
7825 }
7826
7827 for (y = 0; y < (long) MagickGetImageHeight(image_wand); y++)
7828 {
7829 pixels = PixelGetNextIteratorRow (iterator, &width);
7830 if ((pixels == (PixelWand **) NULL))
7831 break;
7832 for (x = 0; x < (long) width; x++)
7833 {
7834 PixelGetMagickColor (pixels[x], &pixel);
7835 XPutPixel (ximg, x, y, lookup_rgb_color (f, pixel.red, pixel.green, pixel.blue));
7836 }
7837 }
7838 DestroyPixelIterator (iterator);
7839 }
7840
7841 if (imagemagick_rendermethod == 1)
7842 {
7843 /* Try if magicexportimage is any faster than pixelpushing. */
7844 /* printf("ximg: bitmap_unit:%d format:%d byte_order:%d depth:%d bits_per_pixel:%d\n", */
7845 /* ximg->bitmap_unit,ximg->format,ximg->byte_order,ximg->depth,ximg->bits_per_pixel); */
7846 int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/
7847 char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
7848 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7849 printf("imagedepth:%d exportdepth:%s\n", imagedepth, exportdepth);
7850 if (!x_create_x_image_and_pixmap (f, width, height, imagedepth, &ximg, &img->pixmap)){
7851 image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
7852 goto imagemagick_error;
7853 }
7854
7855
7856 /* Oddly, the below code doesnt seem to work:*/
7857 /* switch(ximg->bitmap_unit){ */
7858 /* case 8: */
7859 /* pixelwidth=CharPixel; */
7860 /* break; */
7861 /* case 16: */
7862 /* pixelwidth=ShortPixel; */
7863 /* break; */
7864 /* case 32: */
7865 /* pixelwidth=LongPixel; */
7866 /* break; */
7867 /* } */
7868 /*
7869 Here im just guessing the format of the bitmap.
7870 happens to work fine for:
7871 - bw djvu images
7872 on rgb display.
7873 seems about 3 times as fast as pixel pushing(not carefully measured)
7874 with color djvu, the bitplanes are mapped to wrong color(seems fixed).
7875
7876 */
7877 pixelwidth = CharPixel;/*??? TODO figure out*/
7878 #ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
7879 MagickExportImagePixels(image_wand,
7880 0, 0,
7881 width, height,
7882 exportdepth,
7883 pixelwidth,
7884 /*&(img->pixmap));*/
7885 ximg->data);
7886 #else
7887 image_error("You dont have MagickExportImagePixels, upgrade ImageMagick if you want to try it!",
7888 Qnil, Qnil);
7889 #endif
7890 }
7891
7892
7893 #ifdef COLOR_TABLE_SUPPORT
7894 /* Remember colors allocated for this image. */
7895 img->colors = colors_in_color_table (&img->ncolors);
7896 free_color_table ();
7897 #endif /* COLOR_TABLE_SUPPORT */
7898
7899
7900 img->width = width;
7901 img->height = height;
7902
7903 /* Maybe fill in the background field while we have ximg handy.
7904 Casting avoids a GCC warning. */
7905 /* IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);*/
7906
7907 /* Put the image into the pixmap, then free the X image and its
7908 buffer. */
7909 x_put_x_image (f, ximg, img->pixmap, width, height);
7910
7911 x_destroy_x_image (ximg);
7912
7913
7914 /* JAVE TODO more cleanup. */
7915 DestroyMagickWand (image_wand);
7916
7917 return 1;
7918
7919 imagemagick_error:
7920 /* TODO more cleanup. */
7921 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
7922 printf("Imagemagick error, see *Messages*\n");
7923 return 0;
7924 }
7925
7926
7675 /* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if 7927 /* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if
7676 successful. this function will go into the imagemagick_type structure, and 7928 successful. this function will go into the imagemagick_type structure, and
7677 the prototype thus needs to be compatible with that structure. */ 7929 the prototype thus needs to be compatible with that structure. */
7678 7930
7679 static int 7931 static int
7680 imagemagick_load (f, img) 7932 imagemagick_load (struct frame *f,
7681 struct frame *f; 7933 struct image *img)
7682 struct image *img;
7683 { 7934 {
7684 int success_p = 0; 7935 int success_p = 0;
7685 Lisp_Object file_name; 7936 Lisp_Object file_name;
7686 7937
7687 /* If IMG->spec specifies a file name, create a non-file spec from it. */ 7938 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7719 else 7970 else
7720 { 7971 {
7721 Lisp_Object data; 7972 Lisp_Object data;
7722 7973
7723 data = image_spec_value (img->spec, QCdata, NULL); 7974 data = image_spec_value (img->spec, QCdata, NULL);
7724 success_p = imagemagick_load_image (f, img, SDATA (data), SBYTES (data),NULL); 7975 success_p = imagemagick_load_image (f, img, SDATA (data), SBYTES (data), NULL);
7725 } 7976 }
7726 7977
7727 return success_p; 7978 return success_p;
7728 } 7979 }
7729 7980
7730 /* imagemagick_load_image is a helper function for imagemagick_load, which does the 7981 /* Structure describing the image type `imagemagick'. Its the same type of
7731 actual loading given contents and size, apart from frame and image 7982 structure defined for all image formats, handled by Emacs image
7732 structures, passed from imagemagick_load. 7983 functions. See struct image_type in dispextern.h. */
7733 7984
7734 Uses librimagemagick to do most of the image processing. 7985 static struct image_type imagemagick_type =
7735 7986 {
7736 Returns non-zero when successful. 7987 /* An identifier showing that this is an image structure for the IMAGEMAGICK format. */
7737 */ 7988 &Qimagemagick,
7738 7989 /* Handle to a function that can be used to identify a IMAGEMAGICK file. */
7739 static int 7990 imagemagick_image_p,
7740 imagemagick_load_image (f, img, contents, size, filename) 7991 /* Handle to function used to load a IMAGEMAGICK file. */
7741 /* Pointer to emacs frame structure. */ 7992 imagemagick_load,
7742 struct frame *f; 7993 /* Handle to function to free resources for IMAGEMAGICK. */
7743 /* Pointer to emacs image structure. */ 7994 imagemagick_clear_image,
7744 struct image *img; 7995 /* An internal field to link to the next image type in a list of
7745 /* String containing the IMAGEMAGICK data to be parsed. */ 7996 image types, will be filled in when registering the format. */
7746 unsigned char *contents; 7997 NULL
7747 /* Size of data in bytes. */ 7998 };
7748 unsigned int size; 7999
7749 /* Filename, either pass filename or contents/size. */ 8000
7750 unsigned char *filename; 8001
7751 { 8002
7752 long unsigned int width; 8003 DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
7753 long unsigned int height;
7754
7755 MagickBooleanType
7756 status;
7757
7758 XImagePtr ximg;
7759 Lisp_Object specified_bg;
7760 XColor background;
7761 int x;
7762 int y;
7763
7764 MagickWand *image_wand;
7765 PixelIterator *iterator;
7766 PixelWand **pixels;
7767 MagickPixelPacket pixel;
7768
7769
7770 /* image_wand will contain the image. */
7771 image_wand = NewMagickWand();
7772
7773 /* Parse the contents argument and initialize image_wand. */
7774 if(filename!=NULL)
7775 status=MagickReadImage(image_wand, filename);
7776 else
7777 status=MagickReadImageBlob(image_wand, contents, size);
7778 image_error ("im read failed", Qnil, Qnil);
7779 if (status == MagickFalse) goto imagemagick_error;
7780
7781 /* Handle image index for image types who can contain more than one image.
7782 Interface :index is same as for GIF. */
7783 Lisp_Object image;
7784 long ino;
7785 image = image_spec_value (img->spec, QCindex, NULL);
7786 ino = INTEGERP (image) ? XFASTINT (image) : 0;
7787
7788
7789
7790 if (ino >= MagickGetNumberImages(image_wand))
7791 {
7792 image_error ("Invalid image number `%s' in image `%s'",
7793 image, img->spec);
7794 UNGCPRO;
7795 return 0;
7796 }
7797
7798
7799 if (MagickGetNumberImages(image_wand) > 1)
7800 img->data.lisp_val = Fcons (Qcount,
7801 Fcons (make_number (MagickGetNumberImages(image_wand)),
7802 img->data.lisp_val));
7803 if(ino==0)
7804 MagickSetFirstIterator(image_wand);
7805 else
7806 MagickSetIteratorIndex(image_wand, ino);
7807
7808 /*
7809 If width and/or height is set in the display spec
7810 assume we want to scale to those. */
7811
7812 int desired_width, desired_height;
7813 Lisp_Object value;
7814 value = image_spec_value (img->spec, QCwidth, NULL);
7815 desired_width = (INTEGERP (value) ? XFASTINT (value) : -1);
7816 value = image_spec_value (img->spec, QCheight, NULL);
7817 desired_height = (INTEGERP (value) ? XFASTINT (value) : -1);
7818 if(desired_width != -1 && desired_height != -1){
7819 printf("MagickScaleImage %d %d\n",desired_width, desired_height);
7820 status=MagickScaleImage(image_wand, desired_width, desired_height);
7821 if (status == MagickFalse) {
7822 image_error ("Imagemagick scale failed", Qnil, Qnil);
7823 goto imagemagick_error;
7824 }
7825
7826 }
7827
7828 /* Also support :geometry and :crop which are imagemagick specific descriptors. */
7829
7830 Lisp_Object crop, geometry;
7831 crop = image_spec_value (img->spec, QCcrop, NULL);
7832 geometry = image_spec_value (img->spec, QCgeometry, NULL);
7833 if (STRINGP (crop) && STRINGP (geometry)){
7834 printf("MagickTransformImage %s %s\n",SDATA(crop), SDATA(geometry));
7835 image_wand = MagickTransformImage (image_wand, SDATA (crop), SDATA (geometry));
7836 /* TODO differ between image_wand and transform_wand. */
7837 }
7838
7839 /* Furthermore :rotation. we need background color and angle for rotation. */
7840 /*
7841 TODO background handling for rotation
7842 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
7843 if (!STRINGP (specified_bg)
7844 */
7845 double rotation;
7846 value = image_spec_value (img->spec, QCrotation, NULL);
7847 if (FLOATP (value)){
7848 PixelWand* background = NewPixelWand();
7849 PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
7850
7851 rotation = extract_float (value);
7852 printf ("MagickRotateImage %f\n",rotation);
7853
7854 status=MagickRotateImage (image_wand, background,rotation);
7855 DestroyPixelWand (background);
7856 if (status == MagickFalse) {
7857 image_error ("Imagemagick image rotate failed", Qnil, Qnil);
7858 goto imagemagick_error;
7859 }
7860 }
7861
7862 /* Finaly we are done manipulating the image,
7863 figure out resulting width, height, and then transfer ownerwship to Emacs.
7864 */
7865 height=MagickGetImageHeight (image_wand);
7866 width=MagickGetImageWidth (image_wand);
7867 if (status == MagickFalse) {
7868 image_error ("Imagemagick image get size failed", Qnil, Qnil);
7869 goto imagemagick_error;
7870 }
7871
7872 if (! check_image_size (f, width, height))
7873 {
7874 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7875 goto imagemagick_error;
7876 }
7877
7878 /* We can now get a valid pixel buffer from the imagemagick file, if all
7879 went ok. */
7880
7881
7882 init_color_table ();
7883 int imagemagick_rendermethod=(INTEGERP (Vimagemagick_render_type) ? XFASTINT (Vimagemagick_render_type) : 0);
7884 if (imagemagick_rendermethod==0){
7885 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7886 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)){
7887 image_error("Imagemagick X bitmap allocation failure",Qnil,Qnil);
7888 goto imagemagick_error;
7889 }
7890
7891 /* Copy imagegmagick image to x with primitive yet robust pixel
7892 pusher loop. This has been tested a lot with many different
7893 images, it doesnt work too well with image archive formats though!
7894
7895 Also seems slow.
7896 */
7897
7898 /* Copy pixels from the imagemagick image structure to the x image map. */
7899 iterator = NewPixelIterator (image_wand);
7900 if ((iterator == (PixelIterator *) NULL)) {
7901 image_error ("Imagemagick pixel iterator creation failed", Qnil, Qnil);
7902 goto imagemagick_error;
7903 }
7904
7905 for (y=0; y < (long) MagickGetImageHeight(image_wand); y++)
7906 {
7907 pixels = PixelGetNextIteratorRow (iterator, &width);
7908 if ((pixels == (PixelWand **) NULL))
7909 break;
7910 for (x=0; x < (long) width; x++)
7911 {
7912 PixelGetMagickColor (pixels[x], &pixel);
7913 XPutPixel (ximg, x, y, lookup_rgb_color (f, pixel.red, pixel.green, pixel.blue));
7914 }
7915 }
7916 DestroyPixelIterator (iterator);
7917 }
7918
7919 if (imagemagick_rendermethod==1){
7920 /* Try if magicexportimage is any faster than pixelpushing. */
7921 /* printf("ximg: bitmap_unit:%d format:%d byte_order:%d depth:%d bits_per_pixel:%d\n", */
7922 /* ximg->bitmap_unit,ximg->format,ximg->byte_order,ximg->depth,ximg->bits_per_pixel); */
7923 int imagedepth=24;/*MagickGetImageDepth(image_wand);*/
7924 char* exportdepth= imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
7925 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7926 printf("imagedepth:%d exportdepth:%s\n", imagedepth, exportdepth);
7927 if (!x_create_x_image_and_pixmap (f, width, height, imagedepth, &ximg, &img->pixmap)){
7928 image_error("Imagemagick X bitmap allocation failure",Qnil,Qnil);
7929 goto imagemagick_error;
7930 }
7931
7932
7933 /* Oddly, the below code doesnt seem to work:*/
7934 int pixelwidth;
7935 /* switch(ximg->bitmap_unit){ */
7936 /* case 8: */
7937 /* pixelwidth=CharPixel; */
7938 /* break; */
7939 /* case 16: */
7940 /* pixelwidth=ShortPixel; */
7941 /* break; */
7942 /* case 32: */
7943 /* pixelwidth=LongPixel; */
7944 /* break; */
7945 /* } */
7946 /*
7947 Here im just guessing the format of the bitmap.
7948 happens to work fine for:
7949 - bw djvu images
7950 on rgb display.
7951 seems about 3 times as fast as pixel pushing(not carefully measured)
7952 with color djvu, the bitplanes are mapped to wrong color(seems fixed).
7953
7954 */
7955 pixelwidth=CharPixel;/*??? TODO figure out*/
7956 #ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
7957 MagickExportImagePixels(image_wand,
7958 0,0,
7959 width,height,
7960 exportdepth,
7961 pixelwidth,
7962 /*&(img->pixmap));*/
7963 ximg->data);
7964 #else
7965 image_error("You dont have MagickExportImagePixels, upgrade ImageMagick if you want to try it!",Qnil,Qnil);
7966 #endif
7967 }
7968
7969
7970 #ifdef COLOR_TABLE_SUPPORT
7971 /* Remember colors allocated for this image. */
7972 img->colors = colors_in_color_table (&img->ncolors);
7973 free_color_table ();
7974 #endif /* COLOR_TABLE_SUPPORT */
7975
7976
7977 img->width = width;
7978 img->height = height;
7979
7980 /* Maybe fill in the background field while we have ximg handy.
7981 Casting avoids a GCC warning. */
7982 /* IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);*/
7983
7984 /* Put the image into the pixmap, then free the X image and its
7985 buffer. */
7986 x_put_x_image (f, ximg, img->pixmap, width, height);
7987
7988 x_destroy_x_image (ximg);
7989
7990
7991 /* JAVE TODO more cleanup. */
7992 DestroyMagickWand (image_wand);
7993
7994 return 1;
7995
7996 imagemagick_error:
7997 /* TODO more cleanup. */
7998 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
7999 printf("Imagemagick error, see *Messages*\n");
8000 return 0;
8001 }
8002
8003 DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0,0,0,
8004 doc: /* Return image file types supported by ImageMagick. 8004 doc: /* Return image file types supported by ImageMagick.
8005 Since ImageMagick recognizes a lot of file-types that clash with Emacs, 8005 Since ImageMagick recognizes a lot of file-types that clash with Emacs,
8006 such as .c, we want to be able to alter the list at the lisp level. */) 8006 such as .c, we want to be able to alter the list at the lisp level. */)
8007 () 8007 ()
8008 { 8008 {
8009 Lisp_Object typelist = Qnil; 8009 Lisp_Object typelist = Qnil;
8010 unsigned long numf; 8010 unsigned long numf;
8011 ExceptionInfo ex; 8011 ExceptionInfo ex;
8012 char** imtypes = GetMagickList ("*", &numf, &ex); 8012 char** imtypes = GetMagickList ("*", &numf, &ex);
8013 int i; 8013 int i;
8014 Lisp_Object Qimagemagicktype; 8014 Lisp_Object Qimagemagicktype;
8015 for (i = 0; i < numf; i++) { 8015 for (i = 0; i < numf; i++)
8016 Qimagemagicktype = intern (*( imtypes + i)); 8016 {
8017 typelist = Fcons (Qimagemagicktype, typelist); 8017 Qimagemagicktype = intern (imtypes[i]);
8018 } 8018 typelist = Fcons (Qimagemagicktype, typelist);
8019 return typelist; 8019 }
8020 return typelist;
8020 } 8021 }
8021 8022
8022 #endif /* defined (HAVE_IMAGEMAGICK) */ 8023 #endif /* defined (HAVE_IMAGEMAGICK) */
8023 8024
8024 8025
9034 automatically removes it from the image cache. If the cache contains 9035 automatically removes it from the image cache. If the cache contains
9035 a large number of images, the actual eviction time may be shorter. 9036 a large number of images, the actual eviction time may be shorter.
9036 The value can also be nil, meaning the cache is never cleared. 9037 The value can also be nil, meaning the cache is never cleared.
9037 The function `clear-image-cache' disregards this variable. */); 9038 The function `clear-image-cache' disregards this variable. */);
9038 Vimage_cache_eviction_delay = make_number (300); 9039 Vimage_cache_eviction_delay = make_number (300);
9039 }
9040
9041 #ifdef HAVE_IMAGEMAGICK 9040 #ifdef HAVE_IMAGEMAGICK
9042 DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type, 9041 DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type,
9043 doc: /* */); 9042 doc: /* Choose between ImageMagick render methods. */);
9044 #endif 9043 #endif
9044
9045 }
9046
9045 9047
9046 void 9048 void
9047 init_image () 9049 init_image ()
9048 { 9050 {
9049 9051