aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorStefan Monnier2010-09-13 16:40:48 +0200
committerStefan Monnier2010-09-13 16:40:48 +0200
commitcc390e46c7ba95b76ea133d98fd386214cd01709 (patch)
treeead4400d22bd07214b782ff7e46e79d473fac419 /src/image.c
parentc566235d981eba73c88bbff00b6a1d88360b6e9f (diff)
parentc5fe4acb5fb456d6e8e147d8bc7981ce56c5c03d (diff)
downloademacs-cc390e46c7ba95b76ea133d98fd386214cd01709.tar.gz
emacs-cc390e46c7ba95b76ea133d98fd386214cd01709.zip
Merge from trunk
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c710
1 files changed, 623 insertions, 87 deletions
diff --git a/src/image.c b/src/image.c
index 916fcfe8178..499cbf298c1 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
@@ -1735,7 +1735,6 @@ lookup_image (struct frame *f, Lisp_Object spec)
1735 struct image_cache *c; 1735 struct image_cache *c;
1736 struct image *img; 1736 struct image *img;
1737 unsigned hash; 1737 unsigned hash;
1738 struct gcpro gcpro1;
1739 EMACS_TIME now; 1738 EMACS_TIME now;
1740 1739
1741 /* F must be a window-system frame, and SPEC must be a valid image 1740 /* F must be a window-system frame, and SPEC must be a valid image
@@ -1745,8 +1744,6 @@ lookup_image (struct frame *f, Lisp_Object spec)
1745 1744
1746 c = FRAME_IMAGE_CACHE (f); 1745 c = FRAME_IMAGE_CACHE (f);
1747 1746
1748 GCPRO1 (spec);
1749
1750 /* Look up SPEC in the hash table of the image cache. */ 1747 /* Look up SPEC in the hash table of the image cache. */
1751 hash = sxhash (spec, 0); 1748 hash = sxhash (spec, 0);
1752 img = search_image_cache (f, spec, hash); 1749 img = search_image_cache (f, spec, hash);
@@ -1838,8 +1835,6 @@ lookup_image (struct frame *f, Lisp_Object spec)
1838 EMACS_GET_TIME (now); 1835 EMACS_GET_TIME (now);
1839 img->timestamp = EMACS_SECS (now); 1836 img->timestamp = EMACS_SECS (now);
1840 1837
1841 UNGCPRO;
1842
1843 /* Value is the image id. */ 1838 /* Value is the image id. */
1844 return img->id; 1839 return img->id;
1845} 1840}
@@ -2179,16 +2174,13 @@ Lisp_Object
2179x_find_image_file (Lisp_Object file) 2174x_find_image_file (Lisp_Object file)
2180{ 2175{
2181 Lisp_Object file_found, search_path; 2176 Lisp_Object file_found, search_path;
2182 struct gcpro gcpro1, gcpro2;
2183 int fd; 2177 int fd;
2184 2178
2185 file_found = Qnil;
2186 /* TODO I think this should use something like image-load-path 2179 /* TODO I think this should use something like image-load-path
2187 instead. Unfortunately, that can contain non-string elements. */ 2180 instead. Unfortunately, that can contain non-string elements. */
2188 search_path = Fcons (Fexpand_file_name (build_string ("images"), 2181 search_path = Fcons (Fexpand_file_name (build_string ("images"),
2189 Vdata_directory), 2182 Vdata_directory),
2190 Vx_bitmap_file_path); 2183 Vx_bitmap_file_path);
2191 GCPRO2 (file_found, search_path);
2192 2184
2193 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */ 2185 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2194 fd = openp (search_path, file, Qnil, &file_found, Qnil); 2186 fd = openp (search_path, file, Qnil, &file_found, Qnil);
@@ -2201,7 +2193,6 @@ x_find_image_file (Lisp_Object file)
2201 close (fd); 2193 close (fd);
2202 } 2194 }
2203 2195
2204 UNGCPRO;
2205 return file_found; 2196 return file_found;
2206} 2197}
2207 2198
@@ -2875,14 +2866,11 @@ xbm_load (struct frame *f, struct image *img)
2875 Lisp_Object file; 2866 Lisp_Object file;
2876 unsigned char *contents; 2867 unsigned char *contents;
2877 int size; 2868 int size;
2878 struct gcpro gcpro1;
2879 2869
2880 file = x_find_image_file (file_name); 2870 file = x_find_image_file (file_name);
2881 GCPRO1 (file);
2882 if (!STRINGP (file)) 2871 if (!STRINGP (file))
2883 { 2872 {
2884 image_error ("Cannot find image file `%s'", file_name, Qnil); 2873 image_error ("Cannot find image file `%s'", file_name, Qnil);
2885 UNGCPRO;
2886 return 0; 2874 return 0;
2887 } 2875 }
2888 2876
@@ -2890,12 +2878,10 @@ xbm_load (struct frame *f, struct image *img)
2890 if (contents == NULL) 2878 if (contents == NULL)
2891 { 2879 {
2892 image_error ("Error loading XBM image `%s'", img->spec, Qnil); 2880 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
2893 UNGCPRO;
2894 return 0; 2881 return 0;
2895 } 2882 }
2896 2883
2897 success_p = xbm_load_image (f, img, contents, contents + size); 2884 success_p = xbm_load_image (f, img, contents, contents + size);
2898 UNGCPRO;
2899 } 2885 }
2900 else 2886 else
2901 { 2887 {
@@ -3456,12 +3442,31 @@ xpm_load (struct frame *f, struct image *img)
3456 CONSP (tail); 3442 CONSP (tail);
3457 ++i, tail = XCDR (tail)) 3443 ++i, tail = XCDR (tail))
3458 { 3444 {
3459 Lisp_Object name = XCAR (XCAR (tail)); 3445 Lisp_Object name;
3460 Lisp_Object color = XCDR (XCAR (tail)); 3446 Lisp_Object color;
3461 xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1); 3447
3462 strcpy (xpm_syms[i].name, SDATA (name)); 3448 if (!CONSP (XCAR (tail)))
3463 xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1); 3449 {
3464 strcpy (xpm_syms[i].value, SDATA (color)); 3450 xpm_syms[i].name = "";
3451 xpm_syms[i].value = "";
3452 continue;
3453 }
3454 name = XCAR (XCAR (tail));
3455 color = XCDR (XCAR (tail));
3456 if (STRINGP (name))
3457 {
3458 xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
3459 strcpy (xpm_syms[i].name, SDATA (name));
3460 }
3461 else
3462 xpm_syms[i].name = "";
3463 if (STRINGP (color))
3464 {
3465 xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
3466 strcpy (xpm_syms[i].value, SDATA (color));
3467 }
3468 else
3469 xpm_syms[i].value = "";
3465 } 3470 }
3466 } 3471 }
3467 3472
@@ -3487,6 +3492,9 @@ xpm_load (struct frame *f, struct image *img)
3487 if (!STRINGP (file)) 3492 if (!STRINGP (file))
3488 { 3493 {
3489 image_error ("Cannot find image file `%s'", specified_file, Qnil); 3494 image_error ("Cannot find image file `%s'", specified_file, Qnil);
3495#ifdef ALLOC_XPM_COLORS
3496 xpm_free_color_cache ();
3497#endif
3490 return 0; 3498 return 0;
3491 } 3499 }
3492 3500
@@ -3505,6 +3513,14 @@ xpm_load (struct frame *f, struct image *img)
3505 else 3513 else
3506 { 3514 {
3507 Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL); 3515 Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
3516 if (!STRINGP (buffer))
3517 {
3518 image_error ("Invalid image data `%s'", buffer, Qnil);
3519#ifdef ALLOC_XPM_COLORS
3520 xpm_free_color_cache ();
3521#endif
3522 return 0;
3523 }
3508#ifdef HAVE_NTGUI 3524#ifdef HAVE_NTGUI
3509 /* XpmCreatePixmapFromBuffer is not available in the Windows port 3525 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3510 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */ 3526 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
@@ -4071,14 +4087,11 @@ xpm_load (struct frame *f,
4071 Lisp_Object file; 4087 Lisp_Object file;
4072 unsigned char *contents; 4088 unsigned char *contents;
4073 int size; 4089 int size;
4074 struct gcpro gcpro1;
4075 4090
4076 file = x_find_image_file (file_name); 4091 file = x_find_image_file (file_name);
4077 GCPRO1 (file);
4078 if (!STRINGP (file)) 4092 if (!STRINGP (file))
4079 { 4093 {
4080 image_error ("Cannot find image file `%s'", file_name, Qnil); 4094 image_error ("Cannot find image file `%s'", file_name, Qnil);
4081 UNGCPRO;
4082 return 0; 4095 return 0;
4083 } 4096 }
4084 4097
@@ -4086,19 +4099,22 @@ xpm_load (struct frame *f,
4086 if (contents == NULL) 4099 if (contents == NULL)
4087 { 4100 {
4088 image_error ("Error loading XPM image `%s'", img->spec, Qnil); 4101 image_error ("Error loading XPM image `%s'", img->spec, Qnil);
4089 UNGCPRO;
4090 return 0; 4102 return 0;
4091 } 4103 }
4092 4104
4093 success_p = xpm_load_image (f, img, contents, contents + size); 4105 success_p = xpm_load_image (f, img, contents, contents + size);
4094 xfree (contents); 4106 xfree (contents);
4095 UNGCPRO;
4096 } 4107 }
4097 else 4108 else
4098 { 4109 {
4099 Lisp_Object data; 4110 Lisp_Object data;
4100 4111
4101 data = image_spec_value (img->spec, QCdata, NULL); 4112 data = image_spec_value (img->spec, QCdata, NULL);
4113 if (!STRINGP (data))
4114 {
4115 image_error ("Invalid image data `%s'", data, Qnil);
4116 return 0;
4117 }
4102 success_p = xpm_load_image (f, img, SDATA (data), 4118 success_p = xpm_load_image (f, img, SDATA (data),
4103 SDATA (data) + SBYTES (data)); 4119 SDATA (data) + SBYTES (data));
4104 } 4120 }
@@ -5090,14 +5106,11 @@ pbm_load (struct frame *f, struct image *img)
5090 XImagePtr ximg; 5106 XImagePtr ximg;
5091 Lisp_Object file, specified_file; 5107 Lisp_Object file, specified_file;
5092 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; 5108 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5093 struct gcpro gcpro1;
5094 unsigned char *contents = NULL; 5109 unsigned char *contents = NULL;
5095 unsigned char *end, *p; 5110 unsigned char *end, *p;
5096 int size; 5111 int size;
5097 5112
5098 specified_file = image_spec_value (img->spec, QCfile, NULL); 5113 specified_file = image_spec_value (img->spec, QCfile, NULL);
5099 file = Qnil;
5100 GCPRO1 (file);
5101 5114
5102 if (STRINGP (specified_file)) 5115 if (STRINGP (specified_file))
5103 { 5116 {
@@ -5105,7 +5118,6 @@ pbm_load (struct frame *f, struct image *img)
5105 if (!STRINGP (file)) 5118 if (!STRINGP (file))
5106 { 5119 {
5107 image_error ("Cannot find image file `%s'", specified_file, Qnil); 5120 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5108 UNGCPRO;
5109 return 0; 5121 return 0;
5110 } 5122 }
5111 5123
@@ -5113,7 +5125,6 @@ pbm_load (struct frame *f, struct image *img)
5113 if (contents == NULL) 5125 if (contents == NULL)
5114 { 5126 {
5115 image_error ("Error reading `%s'", file, Qnil); 5127 image_error ("Error reading `%s'", file, Qnil);
5116 UNGCPRO;
5117 return 0; 5128 return 0;
5118 } 5129 }
5119 5130
@@ -5124,6 +5135,11 @@ pbm_load (struct frame *f, struct image *img)
5124 { 5135 {
5125 Lisp_Object data; 5136 Lisp_Object data;
5126 data = image_spec_value (img->spec, QCdata, NULL); 5137 data = image_spec_value (img->spec, QCdata, NULL);
5138 if (!STRINGP (data))
5139 {
5140 image_error ("Invalid image data `%s'", data, Qnil);
5141 return 0;
5142 }
5127 p = SDATA (data); 5143 p = SDATA (data);
5128 end = p + SBYTES (data); 5144 end = p + SBYTES (data);
5129 } 5145 }
@@ -5134,7 +5150,6 @@ pbm_load (struct frame *f, struct image *img)
5134 image_error ("Not a PBM image: `%s'", img->spec, Qnil); 5150 image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5135 error: 5151 error:
5136 xfree (contents); 5152 xfree (contents);
5137 UNGCPRO;
5138 return 0; 5153 return 0;
5139 } 5154 }
5140 5155
@@ -5336,7 +5351,6 @@ pbm_load (struct frame *f, struct image *img)
5336 img->width = width; 5351 img->width = width;
5337 img->height = height; */ 5352 img->height = height; */
5338 5353
5339 UNGCPRO;
5340 xfree (contents); 5354 xfree (contents);
5341 return 1; 5355 return 1;
5342} 5356}
@@ -5576,7 +5590,6 @@ png_load (struct frame *f, struct image *img)
5576 Lisp_Object specified_data; 5590 Lisp_Object specified_data;
5577 int x, y, i; 5591 int x, y, i;
5578 XImagePtr ximg, mask_img = NULL; 5592 XImagePtr ximg, mask_img = NULL;
5579 struct gcpro gcpro1;
5580 png_struct *png_ptr = NULL; 5593 png_struct *png_ptr = NULL;
5581 png_info *info_ptr = NULL, *end_info = NULL; 5594 png_info *info_ptr = NULL, *end_info = NULL;
5582 FILE *volatile fp = NULL; 5595 FILE *volatile fp = NULL;
@@ -5593,8 +5606,6 @@ png_load (struct frame *f, struct image *img)
5593 /* Find out what file to load. */ 5606 /* Find out what file to load. */
5594 specified_file = image_spec_value (img->spec, QCfile, NULL); 5607 specified_file = image_spec_value (img->spec, QCfile, NULL);
5595 specified_data = image_spec_value (img->spec, QCdata, NULL); 5608 specified_data = image_spec_value (img->spec, QCdata, NULL);
5596 file = Qnil;
5597 GCPRO1 (file);
5598 5609
5599 if (NILP (specified_data)) 5610 if (NILP (specified_data))
5600 { 5611 {
@@ -5602,7 +5613,6 @@ png_load (struct frame *f, struct image *img)
5602 if (!STRINGP (file)) 5613 if (!STRINGP (file))
5603 { 5614 {
5604 image_error ("Cannot find image file `%s'", specified_file, Qnil); 5615 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5605 UNGCPRO;
5606 return 0; 5616 return 0;
5607 } 5617 }
5608 5618
@@ -5611,7 +5621,6 @@ png_load (struct frame *f, struct image *img)
5611 if (!fp) 5621 if (!fp)
5612 { 5622 {
5613 image_error ("Cannot open image file `%s'", file, Qnil); 5623 image_error ("Cannot open image file `%s'", file, Qnil);
5614 UNGCPRO;
5615 return 0; 5624 return 0;
5616 } 5625 }
5617 5626
@@ -5620,13 +5629,18 @@ png_load (struct frame *f, struct image *img)
5620 || fn_png_sig_cmp (sig, 0, sizeof sig)) 5629 || fn_png_sig_cmp (sig, 0, sizeof sig))
5621 { 5630 {
5622 image_error ("Not a PNG file: `%s'", file, Qnil); 5631 image_error ("Not a PNG file: `%s'", file, Qnil);
5623 UNGCPRO;
5624 fclose (fp); 5632 fclose (fp);
5625 return 0; 5633 return 0;
5626 } 5634 }
5627 } 5635 }
5628 else 5636 else
5629 { 5637 {
5638 if (!STRINGP (specified_data))
5639 {
5640 image_error ("Invalid image data `%s'", specified_data, Qnil);
5641 return 0;
5642 }
5643
5630 /* Read from memory. */ 5644 /* Read from memory. */
5631 tbr.bytes = SDATA (specified_data); 5645 tbr.bytes = SDATA (specified_data);
5632 tbr.len = SBYTES (specified_data); 5646 tbr.len = SBYTES (specified_data);
@@ -5637,7 +5651,6 @@ png_load (struct frame *f, struct image *img)
5637 || fn_png_sig_cmp (tbr.bytes, 0, sizeof sig)) 5651 || fn_png_sig_cmp (tbr.bytes, 0, sizeof sig))
5638 { 5652 {
5639 image_error ("Not a PNG image: `%s'", img->spec, Qnil); 5653 image_error ("Not a PNG image: `%s'", img->spec, Qnil);
5640 UNGCPRO;
5641 return 0; 5654 return 0;
5642 } 5655 }
5643 5656
@@ -5653,7 +5666,6 @@ png_load (struct frame *f, struct image *img)
5653 if (!png_ptr) 5666 if (!png_ptr)
5654 { 5667 {
5655 if (fp) fclose (fp); 5668 if (fp) fclose (fp);
5656 UNGCPRO;
5657 return 0; 5669 return 0;
5658 } 5670 }
5659 5671
@@ -5663,7 +5675,6 @@ png_load (struct frame *f, struct image *img)
5663 { 5675 {
5664 fn_png_destroy_read_struct (&png_ptr, NULL, NULL); 5676 fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
5665 if (fp) fclose (fp); 5677 if (fp) fclose (fp);
5666 UNGCPRO;
5667 return 0; 5678 return 0;
5668 } 5679 }
5669 5680
@@ -5673,7 +5684,6 @@ png_load (struct frame *f, struct image *img)
5673 { 5684 {
5674 fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL); 5685 fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
5675 if (fp) fclose (fp); 5686 if (fp) fclose (fp);
5676 UNGCPRO;
5677 return 0; 5687 return 0;
5678 } 5688 }
5679 5689
@@ -5687,7 +5697,6 @@ png_load (struct frame *f, struct image *img)
5687 xfree (pixels); 5697 xfree (pixels);
5688 xfree (rows); 5698 xfree (rows);
5689 if (fp) fclose (fp); 5699 if (fp) fclose (fp);
5690 UNGCPRO;
5691 return 0; 5700 return 0;
5692 } 5701 }
5693 5702
@@ -5912,7 +5921,6 @@ png_load (struct frame *f, struct image *img)
5912 x_destroy_x_image (mask_img); 5921 x_destroy_x_image (mask_img);
5913 } 5922 }
5914 5923
5915 UNGCPRO;
5916 return 1; 5924 return 1;
5917} 5925}
5918 5926
@@ -6313,13 +6321,10 @@ jpeg_load (struct frame *f, struct image *img)
6313 int rc; 6321 int rc;
6314 unsigned long *colors; 6322 unsigned long *colors;
6315 int width, height; 6323 int width, height;
6316 struct gcpro gcpro1;
6317 6324
6318 /* Open the JPEG file. */ 6325 /* Open the JPEG file. */
6319 specified_file = image_spec_value (img->spec, QCfile, NULL); 6326 specified_file = image_spec_value (img->spec, QCfile, NULL);
6320 specified_data = image_spec_value (img->spec, QCdata, NULL); 6327 specified_data = image_spec_value (img->spec, QCdata, NULL);
6321 file = Qnil;
6322 GCPRO1 (file);
6323 6328
6324 if (NILP (specified_data)) 6329 if (NILP (specified_data))
6325 { 6330 {
@@ -6327,7 +6332,6 @@ jpeg_load (struct frame *f, struct image *img)
6327 if (!STRINGP (file)) 6332 if (!STRINGP (file))
6328 { 6333 {
6329 image_error ("Cannot find image file `%s'", specified_file, Qnil); 6334 image_error ("Cannot find image file `%s'", specified_file, Qnil);
6330 UNGCPRO;
6331 return 0; 6335 return 0;
6332 } 6336 }
6333 6337
@@ -6335,10 +6339,14 @@ jpeg_load (struct frame *f, struct image *img)
6335 if (fp == NULL) 6339 if (fp == NULL)
6336 { 6340 {
6337 image_error ("Cannot open `%s'", file, Qnil); 6341 image_error ("Cannot open `%s'", file, Qnil);
6338 UNGCPRO;
6339 return 0; 6342 return 0;
6340 } 6343 }
6341 } 6344 }
6345 else if (!STRINGP (specified_data))
6346 {
6347 image_error ("Invalid image data `%s'", specified_data, Qnil);
6348 return 0;
6349 }
6342 6350
6343 /* Customize libjpeg's error handling to call my_error_exit when an 6351 /* Customize libjpeg's error handling to call my_error_exit when an
6344 error is detected. This function will perform a longjmp. 6352 error is detected. This function will perform a longjmp.
@@ -6367,8 +6375,6 @@ jpeg_load (struct frame *f, struct image *img)
6367 6375
6368 /* Free pixmap and colors. */ 6376 /* Free pixmap and colors. */
6369 x_clear_image (f, img); 6377 x_clear_image (f, img);
6370
6371 UNGCPRO;
6372 return 0; 6378 return 0;
6373 } 6379 }
6374 6380
@@ -6466,7 +6472,6 @@ jpeg_load (struct frame *f, struct image *img)
6466 /* Put the image into the pixmap. */ 6472 /* Put the image into the pixmap. */
6467 x_put_x_image (f, ximg, img->pixmap, width, height); 6473 x_put_x_image (f, ximg, img->pixmap, width, height);
6468 x_destroy_x_image (ximg); 6474 x_destroy_x_image (ximg);
6469 UNGCPRO;
6470 return 1; 6475 return 1;
6471} 6476}
6472 6477
@@ -6741,14 +6746,11 @@ tiff_load (struct frame *f, struct image *img)
6741 uint32 *buf; 6746 uint32 *buf;
6742 int rc, rc2; 6747 int rc, rc2;
6743 XImagePtr ximg; 6748 XImagePtr ximg;
6744 struct gcpro gcpro1;
6745 tiff_memory_source memsrc; 6749 tiff_memory_source memsrc;
6746 Lisp_Object image; 6750 Lisp_Object image;
6747 6751
6748 specified_file = image_spec_value (img->spec, QCfile, NULL); 6752 specified_file = image_spec_value (img->spec, QCfile, NULL);
6749 specified_data = image_spec_value (img->spec, QCdata, NULL); 6753 specified_data = image_spec_value (img->spec, QCdata, NULL);
6750 file = Qnil;
6751 GCPRO1 (file);
6752 6754
6753 fn_TIFFSetErrorHandler (tiff_error_handler); 6755 fn_TIFFSetErrorHandler (tiff_error_handler);
6754 fn_TIFFSetWarningHandler (tiff_warning_handler); 6756 fn_TIFFSetWarningHandler (tiff_warning_handler);
@@ -6760,7 +6762,6 @@ tiff_load (struct frame *f, struct image *img)
6760 if (!STRINGP (file)) 6762 if (!STRINGP (file))
6761 { 6763 {
6762 image_error ("Cannot find image file `%s'", specified_file, Qnil); 6764 image_error ("Cannot find image file `%s'", specified_file, Qnil);
6763 UNGCPRO;
6764 return 0; 6765 return 0;
6765 } 6766 }
6766 6767
@@ -6770,12 +6771,17 @@ tiff_load (struct frame *f, struct image *img)
6770 if (tiff == NULL) 6771 if (tiff == NULL)
6771 { 6772 {
6772 image_error ("Cannot open `%s'", file, Qnil); 6773 image_error ("Cannot open `%s'", file, Qnil);
6773 UNGCPRO;
6774 return 0; 6774 return 0;
6775 } 6775 }
6776 } 6776 }
6777 else 6777 else
6778 { 6778 {
6779 if (!STRINGP (specified_data))
6780 {
6781 image_error ("Invalid image data `%s'", specified_data, Qnil);
6782 return 0;
6783 }
6784
6779 /* Memory source! */ 6785 /* Memory source! */
6780 memsrc.bytes = SDATA (specified_data); 6786 memsrc.bytes = SDATA (specified_data);
6781 memsrc.len = SBYTES (specified_data); 6787 memsrc.len = SBYTES (specified_data);
@@ -6794,7 +6800,6 @@ tiff_load (struct frame *f, struct image *img)
6794 if (!tiff) 6800 if (!tiff)
6795 { 6801 {
6796 image_error ("Cannot open memory source for `%s'", img->spec, Qnil); 6802 image_error ("Cannot open memory source for `%s'", img->spec, Qnil);
6797 UNGCPRO;
6798 return 0; 6803 return 0;
6799 } 6804 }
6800 } 6805 }
@@ -6808,7 +6813,6 @@ tiff_load (struct frame *f, struct image *img)
6808 image_error ("Invalid image number `%s' in image `%s'", 6813 image_error ("Invalid image number `%s' in image `%s'",
6809 image, img->spec); 6814 image, img->spec);
6810 fn_TIFFClose (tiff); 6815 fn_TIFFClose (tiff);
6811 UNGCPRO;
6812 return 0; 6816 return 0;
6813 } 6817 }
6814 } 6818 }
@@ -6822,7 +6826,6 @@ tiff_load (struct frame *f, struct image *img)
6822 { 6826 {
6823 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 6827 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
6824 fn_TIFFClose (tiff); 6828 fn_TIFFClose (tiff);
6825 UNGCPRO;
6826 return 0; 6829 return 0;
6827 } 6830 }
6828 6831
@@ -6844,7 +6847,6 @@ tiff_load (struct frame *f, struct image *img)
6844 { 6847 {
6845 image_error ("Error reading TIFF image `%s'", img->spec, Qnil); 6848 image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
6846 xfree (buf); 6849 xfree (buf);
6847 UNGCPRO;
6848 return 0; 6850 return 0;
6849 } 6851 }
6850 6852
@@ -6852,7 +6854,6 @@ tiff_load (struct frame *f, struct image *img)
6852 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 6854 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
6853 { 6855 {
6854 xfree (buf); 6856 xfree (buf);
6855 UNGCPRO;
6856 return 0; 6857 return 0;
6857 } 6858 }
6858 6859
@@ -6893,7 +6894,6 @@ tiff_load (struct frame *f, struct image *img)
6893 x_destroy_x_image (ximg); 6894 x_destroy_x_image (ximg);
6894 xfree (buf); 6895 xfree (buf);
6895 6896
6896 UNGCPRO;
6897 return 1; 6897 return 1;
6898} 6898}
6899 6899
@@ -7099,7 +7099,6 @@ gif_load (struct frame *f, struct image *img)
7099 ColorMapObject *gif_color_map; 7099 ColorMapObject *gif_color_map;
7100 unsigned long pixel_colors[256]; 7100 unsigned long pixel_colors[256];
7101 GifFileType *gif; 7101 GifFileType *gif;
7102 struct gcpro gcpro1;
7103 Lisp_Object image; 7102 Lisp_Object image;
7104 int ino, image_height, image_width; 7103 int ino, image_height, image_width;
7105 gif_memory_source memsrc; 7104 gif_memory_source memsrc;
@@ -7107,8 +7106,6 @@ gif_load (struct frame *f, struct image *img)
7107 7106
7108 specified_file = image_spec_value (img->spec, QCfile, NULL); 7107 specified_file = image_spec_value (img->spec, QCfile, NULL);
7109 specified_data = image_spec_value (img->spec, QCdata, NULL); 7108 specified_data = image_spec_value (img->spec, QCdata, NULL);
7110 file = Qnil;
7111 GCPRO1 (file);
7112 7109
7113 if (NILP (specified_data)) 7110 if (NILP (specified_data))
7114 { 7111 {
@@ -7116,7 +7113,6 @@ gif_load (struct frame *f, struct image *img)
7116 if (!STRINGP (file)) 7113 if (!STRINGP (file))
7117 { 7114 {
7118 image_error ("Cannot find image file `%s'", specified_file, Qnil); 7115 image_error ("Cannot find image file `%s'", specified_file, Qnil);
7119 UNGCPRO;
7120 return 0; 7116 return 0;
7121 } 7117 }
7122 7118
@@ -7126,12 +7122,17 @@ gif_load (struct frame *f, struct image *img)
7126 if (gif == NULL) 7122 if (gif == NULL)
7127 { 7123 {
7128 image_error ("Cannot open `%s'", file, Qnil); 7124 image_error ("Cannot open `%s'", file, Qnil);
7129 UNGCPRO;
7130 return 0; 7125 return 0;
7131 } 7126 }
7132 } 7127 }
7133 else 7128 else
7134 { 7129 {
7130 if (!STRINGP (specified_data))
7131 {
7132 image_error ("Invalid image data `%s'", specified_data, Qnil);
7133 return 0;
7134 }
7135
7135 /* Read from memory! */ 7136 /* Read from memory! */
7136 current_gif_memory_src = &memsrc; 7137 current_gif_memory_src = &memsrc;
7137 memsrc.bytes = SDATA (specified_data); 7138 memsrc.bytes = SDATA (specified_data);
@@ -7143,7 +7144,6 @@ gif_load (struct frame *f, struct image *img)
7143 if (!gif) 7144 if (!gif)
7144 { 7145 {
7145 image_error ("Cannot open memory source `%s'", img->spec, Qnil); 7146 image_error ("Cannot open memory source `%s'", img->spec, Qnil);
7146 UNGCPRO;
7147 return 0; 7147 return 0;
7148 } 7148 }
7149 } 7149 }
@@ -7153,7 +7153,6 @@ gif_load (struct frame *f, struct image *img)
7153 { 7153 {
7154 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 7154 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7155 fn_DGifCloseFile (gif); 7155 fn_DGifCloseFile (gif);
7156 UNGCPRO;
7157 return 0; 7156 return 0;
7158 } 7157 }
7159 7158
@@ -7163,7 +7162,6 @@ gif_load (struct frame *f, struct image *img)
7163 { 7162 {
7164 image_error ("Error reading `%s'", img->spec, Qnil); 7163 image_error ("Error reading `%s'", img->spec, Qnil);
7165 fn_DGifCloseFile (gif); 7164 fn_DGifCloseFile (gif);
7166 UNGCPRO;
7167 return 0; 7165 return 0;
7168 } 7166 }
7169 7167
@@ -7174,7 +7172,6 @@ gif_load (struct frame *f, struct image *img)
7174 image_error ("Invalid image number `%s' in image `%s'", 7172 image_error ("Invalid image number `%s' in image `%s'",
7175 image, img->spec); 7173 image, img->spec);
7176 fn_DGifCloseFile (gif); 7174 fn_DGifCloseFile (gif);
7177 UNGCPRO;
7178 return 0; 7175 return 0;
7179 } 7176 }
7180 7177
@@ -7196,7 +7193,6 @@ gif_load (struct frame *f, struct image *img)
7196 { 7193 {
7197 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 7194 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7198 fn_DGifCloseFile (gif); 7195 fn_DGifCloseFile (gif);
7199 UNGCPRO;
7200 return 0; 7196 return 0;
7201 } 7197 }
7202 7198
@@ -7204,7 +7200,6 @@ gif_load (struct frame *f, struct image *img)
7204 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 7200 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7205 { 7201 {
7206 fn_DGifCloseFile (gif); 7202 fn_DGifCloseFile (gif);
7207 UNGCPRO;
7208 return 0; 7203 return 0;
7209 } 7204 }
7210 7205
@@ -7323,7 +7318,6 @@ gif_load (struct frame *f, struct image *img)
7323 x_put_x_image (f, ximg, img->pixmap, width, height); 7318 x_put_x_image (f, ximg, img->pixmap, width, height);
7324 x_destroy_x_image (ximg); 7319 x_destroy_x_image (ximg);
7325 7320
7326 UNGCPRO;
7327 return 1; 7321 return 1;
7328} 7322}
7329 7323
@@ -7342,6 +7336,522 @@ gif_load (struct frame *f, struct image *img)
7342#endif /* HAVE_GIF */ 7336#endif /* HAVE_GIF */
7343 7337
7344 7338
7339/***********************************************************************
7340 imagemagick
7341***********************************************************************/
7342#if defined (HAVE_IMAGEMAGICK)
7343Lisp_Object Vimagemagick_render_type;
7344
7345/* The symbol `imagemagick' identifying images of this type. */
7346
7347Lisp_Object Qimagemagick;
7348Lisp_Object Vimagemagick_render_type;
7349
7350/* Indices of image specification fields in imagemagick_format, below. */
7351
7352enum imagemagick_keyword_index
7353 {
7354 IMAGEMAGICK_TYPE,
7355 IMAGEMAGICK_DATA,
7356 IMAGEMAGICK_FILE,
7357 IMAGEMAGICK_ASCENT,
7358 IMAGEMAGICK_MARGIN,
7359 IMAGEMAGICK_RELIEF,
7360 IMAGEMAGICK_ALGORITHM,
7361 IMAGEMAGICK_HEURISTIC_MASK,
7362 IMAGEMAGICK_MASK,
7363 IMAGEMAGICK_BACKGROUND,
7364 IMAGEMAGICK_HEIGHT,
7365 IMAGEMAGICK_WIDTH,
7366 IMAGEMAGICK_ROTATION,
7367 IMAGEMAGICK_CROP,
7368 IMAGEMAGICK_LAST
7369 };
7370
7371/* Vector of image_keyword structures describing the format
7372 of valid user-defined image specifications. */
7373
7374static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7375 {
7376 {":type", IMAGE_SYMBOL_VALUE, 1},
7377 {":data", IMAGE_STRING_VALUE, 0},
7378 {":file", IMAGE_STRING_VALUE, 0},
7379 {":ascent", IMAGE_ASCENT_VALUE, 0},
7380 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
7381 {":relief", IMAGE_INTEGER_VALUE, 0},
7382 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7383 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7384 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7385 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
7386 {":height", IMAGE_INTEGER_VALUE, 0},
7387 {":width", IMAGE_INTEGER_VALUE, 0},
7388 {":rotation", IMAGE_NUMBER_VALUE, 0},
7389 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
7390 };
7391/* Free X resources of imagemagick image IMG which is used on frame F. */
7392
7393static void
7394imagemagick_clear_image (struct frame *f,
7395 struct image *img)
7396{
7397 x_clear_image (f, img);
7398}
7399
7400
7401
7402/* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do
7403 this by calling parse_image_spec and supplying the keywords that
7404 identify the IMAGEMAGICK format. */
7405
7406static int
7407imagemagick_image_p (Lisp_Object object)
7408{
7409 struct image_keyword fmt[IMAGEMAGICK_LAST];
7410 memcpy (fmt, imagemagick_format, sizeof fmt);
7411
7412 if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
7413 return 0;
7414
7415 /* Must specify either the :data or :file keyword. */
7416 return fmt[IMAGEMAGICK_FILE].count + fmt[IMAGEMAGICK_DATA].count == 1;
7417}
7418
7419/* The GIF library also defines DrawRectangle, but its never used in Emacs.
7420 Therefore rename the function so it doesnt collide with ImageMagick. */
7421#define DrawRectangle DrawRectangleGif
7422#include <wand/MagickWand.h>
7423
7424/* imagemagick_load_image is a helper function for imagemagick_load,
7425 which does the actual loading given contents and size, apart from
7426 frame and image structures, passed from imagemagick_load.
7427
7428 Uses librimagemagick to do most of the image processing.
7429
7430 non-zero when successful.
7431*/
7432
7433static int
7434imagemagick_load_image (/* Pointer to emacs frame structure. */
7435 struct frame *f,
7436 /* Pointer to emacs image structure. */
7437 struct image *img,
7438 /* String containing the IMAGEMAGICK data to
7439 be parsed. */
7440 unsigned char *contents,
7441 /* Size of data in bytes. */
7442 unsigned int size,
7443 /* Filename, either pass filename or
7444 contents/size. */
7445 unsigned char *filename)
7446{
7447 unsigned long width;
7448 unsigned long height;
7449
7450 MagickBooleanType
7451 status;
7452
7453 XImagePtr ximg;
7454 Lisp_Object specified_bg;
7455 XColor background;
7456 int x;
7457 int y;
7458
7459 MagickWand *image_wand;
7460 MagickWand *ping_wand;
7461 PixelIterator *iterator;
7462 PixelWand **pixels;
7463 MagickPixelPacket pixel;
7464 Lisp_Object image;
7465 Lisp_Object value;
7466 Lisp_Object crop, geometry;
7467 long ino;
7468 int desired_width, desired_height;
7469 double rotation;
7470 int imagemagick_rendermethod;
7471 int pixelwidth;
7472 ImageInfo *image_info;
7473 ExceptionInfo *exception;
7474 Image * im_image;
7475
7476
7477 /* Handle image index for image types who can contain more than one
7478 image. Interface :index is same as for GIF. First we "ping" the
7479 image to see how many sub-images it contains. Pinging is faster
7480 than loading the image to find out things about it. */
7481 image = image_spec_value (img->spec, QCindex, NULL);
7482 ino = INTEGERP (image) ? XFASTINT (image) : 0;
7483 ping_wand = NewMagickWand ();
7484 MagickSetResolution (ping_wand, 2, 2);
7485 if (filename != NULL)
7486 {
7487 status = MagickPingImage (ping_wand, filename);
7488 }
7489 else
7490 {
7491 status = MagickPingImageBlob (ping_wand, contents, size);
7492 }
7493
7494 if (ino >= MagickGetNumberImages (ping_wand))
7495 {
7496 image_error ("Invalid image number `%s' in image `%s'",
7497 image, img->spec);
7498 DestroyMagickWand (ping_wand);
7499 return 0;
7500 }
7501
7502 if (MagickGetNumberImages(ping_wand) > 1)
7503 img->data.lisp_val =
7504 Fcons (Qcount,
7505 Fcons (make_number (MagickGetNumberImages (ping_wand)),
7506 img->data.lisp_val));
7507
7508 DestroyMagickWand (ping_wand);
7509 /* Now, after pinging, we know how many images are inside the
7510 file. If its not a bundle, just one. */
7511
7512 if (filename != NULL)
7513 {
7514 image_info = CloneImageInfo ((ImageInfo *) NULL);
7515 (void) strcpy (image_info->filename, filename);
7516 image_info->number_scenes = 1;
7517 image_info->scene = ino;
7518 exception = AcquireExceptionInfo ();
7519
7520 im_image = ReadImage (image_info, exception);
7521 CatchException (exception);
7522
7523 image_wand = NewMagickWandFromImage (im_image);
7524 }
7525 else
7526 {
7527 image_wand = NewMagickWand ();
7528 status = MagickReadImageBlob (image_wand, contents, size);
7529 }
7530 image_error ("im read failed", Qnil, Qnil);
7531 if (status == MagickFalse) goto imagemagick_error;
7532
7533 /* If width and/or height is set in the display spec assume we want
7534 to scale to those values. if either h or w is unspecified, the
7535 unspecified should be calculated from the specified to preserve
7536 aspect ratio. */
7537
7538 value = image_spec_value (img->spec, QCwidth, NULL);
7539 desired_width = (INTEGERP (value) ? XFASTINT (value) : -1);
7540 value = image_spec_value (img->spec, QCheight, NULL);
7541 desired_height = (INTEGERP (value) ? XFASTINT (value) : -1);
7542
7543 height = MagickGetImageHeight (image_wand);
7544 width = MagickGetImageWidth (image_wand);
7545
7546 if(desired_width != -1 && desired_height == -1)
7547 {
7548 /* w known, calculate h. */
7549 desired_height = (double) desired_width / width * height;
7550 }
7551 if(desired_width == -1 && desired_height != -1)
7552 {
7553 /* h known, calculate w. */
7554 desired_width = (double) desired_height / height * width;
7555 }
7556 if(desired_width != -1 && desired_height != -1)
7557 {
7558 status = MagickScaleImage (image_wand, desired_width, desired_height);
7559 if (status == MagickFalse)
7560 {
7561 image_error ("Imagemagick scale failed", Qnil, Qnil);
7562 goto imagemagick_error;
7563 }
7564 }
7565
7566
7567 /* crop behaves similar to image slicing in Emacs but is more memory
7568 efficient. */
7569 crop = image_spec_value (img->spec, QCcrop, NULL);
7570
7571 if (CONSP (crop) && INTEGERP (XCAR (crop)))
7572 {
7573 /* After some testing, it seems MagickCropImage is the fastest
7574 crop function in ImageMagick. This crop function seems to do
7575 less copying than the alternatives, but it still reads the
7576 entire image into memory before croping, which is aparently
7577 difficult to avoid when using imagemagick. */
7578
7579 int w, h, x, y;
7580 w = XFASTINT (XCAR (crop));
7581 crop = XCDR (crop);
7582 if (CONSP (crop) && INTEGERP (XCAR (crop)))
7583 {
7584 h = XFASTINT (XCAR (crop));
7585 crop = XCDR (crop);
7586 if (CONSP (crop) && INTEGERP (XCAR (crop)))
7587 {
7588 x = XFASTINT (XCAR (crop));
7589 crop = XCDR (crop);
7590 if (CONSP (crop) && INTEGERP (XCAR (crop)))
7591 {
7592 y = XFASTINT (XCAR (crop));
7593 MagickCropImage (image_wand, w, h, x, y);
7594 }
7595 }
7596 }
7597 }
7598
7599 /* Furthermore :rotation. we need background color and angle for
7600 rotation. */
7601 /*
7602 TODO background handling for rotation specified_bg =
7603 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
7604 (specified_bg). */
7605 value = image_spec_value (img->spec, QCrotation, NULL);
7606 if (FLOATP (value))
7607 {
7608 PixelWand* background = NewPixelWand ();
7609 PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
7610
7611 rotation = extract_float (value);
7612
7613 status = MagickRotateImage (image_wand, background, rotation);
7614 DestroyPixelWand (background);
7615 if (status == MagickFalse)
7616 {
7617 image_error ("Imagemagick image rotate failed", Qnil, Qnil);
7618 goto imagemagick_error;
7619 }
7620 }
7621
7622 /* Finaly we are done manipulating the image, figure out resulting
7623 width, height, and then transfer ownerwship to Emacs. */
7624 height = MagickGetImageHeight (image_wand);
7625 width = MagickGetImageWidth (image_wand);
7626 if (status == MagickFalse)
7627 {
7628 image_error ("Imagemagick image get size failed", Qnil, Qnil);
7629 goto imagemagick_error;
7630 }
7631
7632 if (! check_image_size (f, width, height))
7633 {
7634 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7635 goto imagemagick_error;
7636 }
7637
7638 /* We can now get a valid pixel buffer from the imagemagick file, if all
7639 went ok. */
7640
7641 init_color_table ();
7642 imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
7643 ? XFASTINT (Vimagemagick_render_type) : 0);
7644 if (imagemagick_rendermethod == 0)
7645 {
7646 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7647 if (!x_create_x_image_and_pixmap (f, width, height, 0,
7648 &ximg, &img->pixmap))
7649 {
7650 image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
7651 goto imagemagick_error;
7652 }
7653
7654 /* Copy imagegmagick image to x with primitive yet robust pixel
7655 pusher loop. This has been tested a lot with many different
7656 images. */
7657
7658 /* Copy pixels from the imagemagick image structure to the x image map. */
7659 iterator = NewPixelIterator (image_wand);
7660 if (iterator == (PixelIterator *) NULL)
7661 {
7662 image_error ("Imagemagick pixel iterator creation failed",
7663 Qnil, Qnil);
7664 goto imagemagick_error;
7665 }
7666
7667 for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++)
7668 {
7669 pixels = PixelGetNextIteratorRow (iterator, &width);
7670 if (pixels == (PixelWand **) NULL)
7671 break;
7672 for (x = 0; x < (long) width; x++)
7673 {
7674 PixelGetMagickColor (pixels[x], &pixel);
7675 XPutPixel (ximg, x, y,
7676 lookup_rgb_color (f,
7677 pixel.red,
7678 pixel.green,
7679 pixel.blue));
7680 }
7681 }
7682 DestroyPixelIterator (iterator);
7683 }
7684
7685 if (imagemagick_rendermethod == 1)
7686 {
7687 /* Magicexportimage is normaly faster than pixelpushing. This
7688 method is also well tested. Some aspects of this method are
7689 ad-hoc and needs to be more researched. */
7690 int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/
7691 char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
7692 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7693 if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
7694 &ximg, &img->pixmap))
7695 {
7696 image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
7697 goto imagemagick_error;
7698 }
7699
7700
7701 /* Oddly, the below code doesnt seem to work:*/
7702 /* switch(ximg->bitmap_unit){ */
7703 /* case 8: */
7704 /* pixelwidth=CharPixel; */
7705 /* break; */
7706 /* case 16: */
7707 /* pixelwidth=ShortPixel; */
7708 /* break; */
7709 /* case 32: */
7710 /* pixelwidth=LongPixel; */
7711 /* break; */
7712 /* } */
7713 /*
7714 Here im just guessing the format of the bitmap.
7715 happens to work fine for:
7716 - bw djvu images
7717 on rgb display.
7718 seems about 3 times as fast as pixel pushing(not carefully measured)
7719 */
7720 pixelwidth = CharPixel;/*??? TODO figure out*/
7721#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
7722 MagickExportImagePixels (image_wand,
7723 0, 0,
7724 width, height,
7725 exportdepth,
7726 pixelwidth,
7727 /*&(img->pixmap));*/
7728 ximg->data);
7729#else
7730 image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!",
7731 Qnil, Qnil);
7732#endif
7733 }
7734
7735
7736#ifdef COLOR_TABLE_SUPPORT
7737 /* Remember colors allocated for this image. */
7738 img->colors = colors_in_color_table (&img->ncolors);
7739 free_color_table ();
7740#endif /* COLOR_TABLE_SUPPORT */
7741
7742
7743 img->width = width;
7744 img->height = height;
7745
7746 /* Put the image into the pixmap, then free the X image and its
7747 buffer. */
7748 x_put_x_image (f, ximg, img->pixmap, width, height);
7749 x_destroy_x_image (ximg);
7750
7751
7752 /* Final cleanup. image_wand should be the only resource left. */
7753 DestroyMagickWand (image_wand);
7754
7755 return 1;
7756
7757 imagemagick_error:
7758 /* TODO more cleanup. */
7759 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
7760 return 0;
7761}
7762
7763
7764/* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if
7765 successful. this function will go into the imagemagick_type structure, and
7766 the prototype thus needs to be compatible with that structure. */
7767
7768static int
7769imagemagick_load (struct frame *f,
7770 struct image *img)
7771{
7772 int success_p = 0;
7773 Lisp_Object file_name;
7774
7775 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7776 file_name = image_spec_value (img->spec, QCfile, NULL);
7777 if (STRINGP (file_name))
7778 {
7779 Lisp_Object file;
7780
7781 file = x_find_image_file (file_name);
7782 if (!STRINGP (file))
7783 {
7784 image_error ("Cannot find image file `%s'", file_name, Qnil);
7785 return 0;
7786 }
7787 success_p = imagemagick_load_image (f, img, 0, 0, SDATA (file));
7788 }
7789 /* Else its not a file, its a lisp object. Load the image from a
7790 lisp object rather than a file. */
7791 else
7792 {
7793 Lisp_Object data;
7794
7795 data = image_spec_value (img->spec, QCdata, NULL);
7796 if (!STRINGP (data))
7797 {
7798 image_error ("Invalid image data `%s'", data, Qnil);
7799 return 0;
7800 }
7801 success_p = imagemagick_load_image (f, img, SDATA (data),
7802 SBYTES (data), NULL);
7803 }
7804
7805 return success_p;
7806}
7807
7808/* Structure describing the image type `imagemagick'. Its the same
7809 type of structure defined for all image formats, handled by Emacs
7810 image functions. See struct image_type in dispextern.h. */
7811
7812static struct image_type imagemagick_type =
7813 {
7814 /* An identifier showing that this is an image structure for the
7815 IMAGEMAGICK format. */
7816 &Qimagemagick,
7817 /* Handle to a function that can be used to identify a IMAGEMAGICK
7818 file. */
7819 imagemagick_image_p,
7820 /* Handle to function used to load a IMAGEMAGICK file. */
7821 imagemagick_load,
7822 /* Handle to function to free resources for IMAGEMAGICK. */
7823 imagemagick_clear_image,
7824 /* An internal field to link to the next image type in a list of
7825 image types, will be filled in when registering the format. */
7826 NULL
7827 };
7828
7829
7830
7831
7832DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
7833 doc: /* Return image file types supported by ImageMagick.
7834Since ImageMagick recognizes a lot of file-types that clash with Emacs,
7835such as .c, we want to be able to alter the list at the lisp level. */)
7836 (void)
7837{
7838 Lisp_Object typelist = Qnil;
7839 unsigned long numf;
7840 ExceptionInfo ex;
7841 char **imtypes = GetMagickList ("*", &numf, &ex);
7842 int i;
7843 Lisp_Object Qimagemagicktype;
7844 for (i = 0; i < numf; i++)
7845 {
7846 Qimagemagicktype = intern (imtypes[i]);
7847 typelist = Fcons (Qimagemagicktype, typelist);
7848 }
7849 return typelist;
7850}
7851
7852#endif /* defined (HAVE_IMAGEMAGICK) */
7853
7854
7345 7855
7346/*********************************************************************** 7856/***********************************************************************
7347 SVG 7857 SVG
@@ -7534,14 +8044,11 @@ svg_load (struct frame *f, struct image *img)
7534 Lisp_Object file; 8044 Lisp_Object file;
7535 unsigned char *contents; 8045 unsigned char *contents;
7536 int size; 8046 int size;
7537 struct gcpro gcpro1;
7538 8047
7539 file = x_find_image_file (file_name); 8048 file = x_find_image_file (file_name);
7540 GCPRO1 (file);
7541 if (!STRINGP (file)) 8049 if (!STRINGP (file))
7542 { 8050 {
7543 image_error ("Cannot find image file `%s'", file_name, Qnil); 8051 image_error ("Cannot find image file `%s'", file_name, Qnil);
7544 UNGCPRO;
7545 return 0; 8052 return 0;
7546 } 8053 }
7547 8054
@@ -7550,13 +8057,11 @@ svg_load (struct frame *f, struct image *img)
7550 if (contents == NULL) 8057 if (contents == NULL)
7551 { 8058 {
7552 image_error ("Error loading SVG image `%s'", img->spec, Qnil); 8059 image_error ("Error loading SVG image `%s'", img->spec, Qnil);
7553 UNGCPRO;
7554 return 0; 8060 return 0;
7555 } 8061 }
7556 /* If the file was slurped into memory properly, parse it. */ 8062 /* If the file was slurped into memory properly, parse it. */
7557 success_p = svg_load_image (f, img, contents, size); 8063 success_p = svg_load_image (f, img, contents, size);
7558 xfree (contents); 8064 xfree (contents);
7559 UNGCPRO;
7560 } 8065 }
7561 /* Else its not a file, its a lisp object. Load the image from a 8066 /* Else its not a file, its a lisp object. Load the image from a
7562 lisp object rather than a file. */ 8067 lisp object rather than a file. */
@@ -7565,6 +8070,11 @@ svg_load (struct frame *f, struct image *img)
7565 Lisp_Object data; 8070 Lisp_Object data;
7566 8071
7567 data = image_spec_value (img->spec, QCdata, NULL); 8072 data = image_spec_value (img->spec, QCdata, NULL);
8073 if (!STRINGP (data))
8074 {
8075 image_error ("Invalid image data `%s'", data, Qnil);
8076 return 0;
8077 }
7568 success_p = svg_load_image (f, img, SDATA (data), SBYTES (data)); 8078 success_p = svg_load_image (f, img, SDATA (data), SBYTES (data));
7569 } 8079 }
7570 8080
@@ -7864,7 +8374,6 @@ gs_load (struct frame *f, struct image *img)
7864{ 8374{
7865 char buffer[100]; 8375 char buffer[100];
7866 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width; 8376 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
7867 struct gcpro gcpro1, gcpro2;
7868 Lisp_Object frame; 8377 Lisp_Object frame;
7869 double in_width, in_height; 8378 double in_width, in_height;
7870 Lisp_Object pixel_colors = Qnil; 8379 Lisp_Object pixel_colors = Qnil;
@@ -7874,10 +8383,10 @@ gs_load (struct frame *f, struct image *img)
7874 = 1/72 in, xdpi and ydpi are stored in the frame's X display 8383 = 1/72 in, xdpi and ydpi are stored in the frame's X display
7875 info. */ 8384 info. */
7876 pt_width = image_spec_value (img->spec, QCpt_width, NULL); 8385 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
7877 in_width = XFASTINT (pt_width) / 72.0; 8386 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
7878 img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx; 8387 img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx;
7879 pt_height = image_spec_value (img->spec, QCpt_height, NULL); 8388 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
7880 in_height = XFASTINT (pt_height) / 72.0; 8389 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
7881 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; 8390 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy;
7882 8391
7883 if (!check_image_size (f, img->width, img->height)) 8392 if (!check_image_size (f, img->width, img->height))
@@ -7906,8 +8415,6 @@ gs_load (struct frame *f, struct image *img)
7906 if successful. We do not record_unwind_protect here because 8415 if successful. We do not record_unwind_protect here because
7907 other places in redisplay like calling window scroll functions 8416 other places in redisplay like calling window scroll functions
7908 don't either. Let the Lisp loader use `unwind-protect' instead. */ 8417 don't either. Let the Lisp loader use `unwind-protect' instead. */
7909 GCPRO2 (window_and_pixmap_id, pixel_colors);
7910
7911 sprintf (buffer, "%lu %lu", 8418 sprintf (buffer, "%lu %lu",
7912 (unsigned long) FRAME_X_WINDOW (f), 8419 (unsigned long) FRAME_X_WINDOW (f),
7913 (unsigned long) img->pixmap); 8420 (unsigned long) img->pixmap);
@@ -7928,7 +8435,6 @@ gs_load (struct frame *f, struct image *img)
7928 make_number (img->height), 8435 make_number (img->height),
7929 window_and_pixmap_id, 8436 window_and_pixmap_id,
7930 pixel_colors); 8437 pixel_colors);
7931 UNGCPRO;
7932 return PROCESSP (img->data.lisp_val); 8438 return PROCESSP (img->data.lisp_val);
7933} 8439}
7934 8440
@@ -8117,6 +8623,16 @@ of `image-library-alist', which see). */)
8117 return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries); 8623 return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries);
8118#endif 8624#endif
8119 8625
8626#if defined (HAVE_IMAGEMAGICK)
8627 if (EQ (type, Qimagemagick))
8628 {
8629 /* MagickWandGenesis() initalizes the imagemagick library. */
8630 MagickWandGenesis ();
8631 return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
8632 libraries);
8633 }
8634#endif
8635
8120#ifdef HAVE_GHOSTSCRIPT 8636#ifdef HAVE_GHOSTSCRIPT
8121 if (EQ (type, Qpostscript)) 8637 if (EQ (type, Qpostscript))
8122 return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries); 8638 return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
@@ -8202,6 +8718,12 @@ non-numeric, there is no explicit limit on the size of images. */);
8202 staticpro (&QCheuristic_mask); 8718 staticpro (&QCheuristic_mask);
8203 QCindex = intern_c_string (":index"); 8719 QCindex = intern_c_string (":index");
8204 staticpro (&QCindex); 8720 staticpro (&QCindex);
8721 QCgeometry = intern (":geometry");
8722 staticpro (&QCgeometry);
8723 QCcrop = intern (":crop");
8724 staticpro (&QCcrop);
8725 QCrotation = intern (":rotation");
8726 staticpro (&QCrotation);
8205 QCmatrix = intern_c_string (":matrix"); 8727 QCmatrix = intern_c_string (":matrix");
8206 staticpro (&QCmatrix); 8728 staticpro (&QCmatrix);
8207 QCcolor_adjustment = intern_c_string (":color-adjustment"); 8729 QCcolor_adjustment = intern_c_string (":color-adjustment");
@@ -8262,6 +8784,12 @@ non-numeric, there is no explicit limit on the size of images. */);
8262 ADD_IMAGE_TYPE (Qpng); 8784 ADD_IMAGE_TYPE (Qpng);
8263#endif 8785#endif
8264 8786
8787#if defined (HAVE_IMAGEMAGICK)
8788 Qimagemagick = intern ("imagemagick");
8789 staticpro (&Qimagemagick);
8790 ADD_IMAGE_TYPE (Qimagemagick);
8791#endif
8792
8265#if defined (HAVE_RSVG) 8793#if defined (HAVE_RSVG)
8266 Qsvg = intern_c_string ("svg"); 8794 Qsvg = intern_c_string ("svg");
8267 staticpro (&Qsvg); 8795 staticpro (&Qsvg);
@@ -8278,6 +8806,9 @@ non-numeric, there is no explicit limit on the size of images. */);
8278#endif /* HAVE_RSVG */ 8806#endif /* HAVE_RSVG */
8279 8807
8280 defsubr (&Sinit_image_library); 8808 defsubr (&Sinit_image_library);
8809#ifdef HAVE_IMAGEMAGICK
8810 defsubr (&Simagemagick_types);
8811#endif
8281 defsubr (&Sclear_image_cache); 8812 defsubr (&Sclear_image_cache);
8282 defsubr (&Simage_flush); 8813 defsubr (&Simage_flush);
8283 defsubr (&Simage_size); 8814 defsubr (&Simage_size);
@@ -8308,6 +8839,11 @@ The value can also be nil, meaning the cache is never cleared.
8308 8839
8309The function `clear-image-cache' disregards this variable. */); 8840The function `clear-image-cache' disregards this variable. */);
8310 Vimage_cache_eviction_delay = make_number (300); 8841 Vimage_cache_eviction_delay = make_number (300);
8842#ifdef HAVE_IMAGEMAGICK
8843 DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type,
8844 doc: /* Choose between ImageMagick render methods. */);
8845#endif
8846
8311} 8847}
8312 8848
8313void 8849void