aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c399
1 files changed, 309 insertions, 90 deletions
diff --git a/src/image.c b/src/image.c
index 911ca8e6681..1271376bcab 100644
--- a/src/image.c
+++ b/src/image.c
@@ -30,13 +30,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
30#endif 30#endif
31 31
32#include <setjmp.h> 32#include <setjmp.h>
33
34#include <c-ctype.h> 33#include <c-ctype.h>
35 34
36/* This makes the fields of a Display accessible, in Xlib header files. */
37
38#define XLIB_ILLEGAL_ACCESS
39
40#include "lisp.h" 35#include "lisp.h"
41#include "frame.h" 36#include "frame.h"
42#include "window.h" 37#include "window.h"
@@ -145,7 +140,7 @@ static Lisp_Object QCmax_width, QCmax_height;
145 140
146#ifdef HAVE_NS 141#ifdef HAVE_NS
147/* Use with images created by ns_image_for_XPM. */ 142/* Use with images created by ns_image_for_XPM. */
148unsigned long 143static unsigned long
149XGetPixel (XImagePtr ximage, int x, int y) 144XGetPixel (XImagePtr ximage, int x, int y)
150{ 145{
151 return ns_get_pixel (ximage, x, y); 146 return ns_get_pixel (ximage, x, y);
@@ -153,7 +148,7 @@ XGetPixel (XImagePtr ximage, int x, int y)
153 148
154/* Use with images created by ns_image_for_XPM; alpha set to 1; 149/* Use with images created by ns_image_for_XPM; alpha set to 1;
155 pixel is assumed to be in RGB form. */ 150 pixel is assumed to be in RGB form. */
156void 151static void
157XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel) 152XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
158{ 153{
159 ns_put_pixel (ximage, x, y, pixel); 154 ns_put_pixel (ximage, x, y, pixel);
@@ -302,11 +297,10 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
302 id = x_allocate_bitmap_record (f); 297 id = x_allocate_bitmap_record (f);
303 dpyinfo->bitmaps[id - 1].img = bitmap; 298 dpyinfo->bitmaps[id - 1].img = bitmap;
304 dpyinfo->bitmaps[id - 1].refcount = 1; 299 dpyinfo->bitmaps[id - 1].refcount = 1;
305 dpyinfo->bitmaps[id - 1].file = xmalloc (SBYTES (file) + 1); 300 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
306 dpyinfo->bitmaps[id - 1].depth = 1; 301 dpyinfo->bitmaps[id - 1].depth = 1;
307 dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap); 302 dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap);
308 dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap); 303 dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap);
309 strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file));
310 return id; 304 return id;
311#endif 305#endif
312 306
@@ -345,11 +339,10 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
345 dpyinfo->bitmaps[id - 1].pixmap = bitmap; 339 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
346 dpyinfo->bitmaps[id - 1].have_mask = 0; 340 dpyinfo->bitmaps[id - 1].have_mask = 0;
347 dpyinfo->bitmaps[id - 1].refcount = 1; 341 dpyinfo->bitmaps[id - 1].refcount = 1;
348 dpyinfo->bitmaps[id - 1].file = xmalloc (SBYTES (file) + 1); 342 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
349 dpyinfo->bitmaps[id - 1].depth = 1; 343 dpyinfo->bitmaps[id - 1].depth = 1;
350 dpyinfo->bitmaps[id - 1].height = height; 344 dpyinfo->bitmaps[id - 1].height = height;
351 dpyinfo->bitmaps[id - 1].width = width; 345 dpyinfo->bitmaps[id - 1].width = width;
352 strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file));
353 346
354 return id; 347 return id;
355#endif /* HAVE_X_WINDOWS */ 348#endif /* HAVE_X_WINDOWS */
@@ -565,7 +558,6 @@ static void x_emboss (struct frame *, struct image *);
565static void x_build_heuristic_mask (struct frame *, struct image *, 558static void x_build_heuristic_mask (struct frame *, struct image *,
566 Lisp_Object); 559 Lisp_Object);
567#ifdef WINDOWSNT 560#ifdef WINDOWSNT
568extern Lisp_Object Vlibrary_cache;
569#define CACHE_IMAGE_TYPE(type, status) \ 561#define CACHE_IMAGE_TYPE(type, status) \
570 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0) 562 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
571#else 563#else
@@ -1044,7 +1036,7 @@ void
1044prepare_image_for_display (struct frame *f, struct image *img) 1036prepare_image_for_display (struct frame *f, struct image *img)
1045{ 1037{
1046 /* We're about to display IMG, so set its timestamp to `now'. */ 1038 /* We're about to display IMG, so set its timestamp to `now'. */
1047 img->timestamp = current_emacs_time (); 1039 img->timestamp = current_timespec ();
1048 1040
1049 /* If IMG doesn't have a pixmap yet, load it now, using the image 1041 /* If IMG doesn't have a pixmap yet, load it now, using the image
1050 type dependent loader function. */ 1042 type dependent loader function. */
@@ -1362,14 +1354,12 @@ static void cache_image (struct frame *f, struct image *img);
1362struct image_cache * 1354struct image_cache *
1363make_image_cache (void) 1355make_image_cache (void)
1364{ 1356{
1365 struct image_cache *c = xzalloc (sizeof *c); 1357 struct image_cache *c = xmalloc (sizeof *c);
1366 int size;
1367 1358
1368 size = 50; 1359 c->size = 50;
1369 c->images = xmalloc (size * sizeof *c->images); 1360 c->used = c->refcount = 0;
1370 c->size = size; 1361 c->images = xmalloc (c->size * sizeof *c->images);
1371 size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; 1362 c->buckets = xzalloc (IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets);
1372 c->buckets = xzalloc (size);
1373 return c; 1363 return c;
1374} 1364}
1375 1365
@@ -1485,7 +1475,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1485 else if (INTEGERP (Vimage_cache_eviction_delay)) 1475 else if (INTEGERP (Vimage_cache_eviction_delay))
1486 { 1476 {
1487 /* Free cache based on timestamp. */ 1477 /* Free cache based on timestamp. */
1488 EMACS_TIME old, t; 1478 struct timespec old, t;
1489 double delay; 1479 double delay;
1490 ptrdiff_t nimages = 0; 1480 ptrdiff_t nimages = 0;
1491 1481
@@ -1500,13 +1490,13 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1500 delay = 1600 * delay / nimages / nimages; 1490 delay = 1600 * delay / nimages / nimages;
1501 delay = max (delay, 1); 1491 delay = max (delay, 1);
1502 1492
1503 t = current_emacs_time (); 1493 t = current_timespec ();
1504 old = sub_emacs_time (t, EMACS_TIME_FROM_DOUBLE (delay)); 1494 old = timespec_sub (t, dtotimespec (delay));
1505 1495
1506 for (i = 0; i < c->used; ++i) 1496 for (i = 0; i < c->used; ++i)
1507 { 1497 {
1508 struct image *img = c->images[i]; 1498 struct image *img = c->images[i];
1509 if (img && EMACS_TIME_LT (img->timestamp, old)) 1499 if (img && timespec_cmp (img->timestamp, old) < 0)
1510 { 1500 {
1511 free_image (f, img); 1501 free_image (f, img);
1512 ++nfreed; 1502 ++nfreed;
@@ -1769,7 +1759,7 @@ lookup_image (struct frame *f, Lisp_Object spec)
1769 } 1759 }
1770 1760
1771 /* We're using IMG, so set its timestamp to `now'. */ 1761 /* We're using IMG, so set its timestamp to `now'. */
1772 img->timestamp = current_emacs_time (); 1762 img->timestamp = current_timespec ();
1773 1763
1774 /* Value is the image id. */ 1764 /* Value is the image id. */
1775 return img->id; 1765 return img->id;
@@ -2717,10 +2707,13 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
2717 LA1 = xbm_scan (&s, end, buffer, &value) 2707 LA1 = xbm_scan (&s, end, buffer, &value)
2718 2708
2719#define expect(TOKEN) \ 2709#define expect(TOKEN) \
2720 if (LA1 != (TOKEN)) \ 2710 do \
2721 goto failure; \ 2711 { \
2722 else \ 2712 if (LA1 != (TOKEN)) \
2723 match () 2713 goto failure; \
2714 match (); \
2715 } \
2716 while (0)
2724 2717
2725#define expect_ident(IDENT) \ 2718#define expect_ident(IDENT) \
2726 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \ 2719 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
@@ -3332,7 +3325,7 @@ static int
3332xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color, 3325xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color,
3333 void *closure) 3326 void *closure)
3334{ 3327{
3335 return xpm_lookup_color ((struct frame *) closure, color_name, color); 3328 return xpm_lookup_color (closure, color_name, color);
3336} 3329}
3337 3330
3338 3331
@@ -3980,10 +3973,13 @@ xpm_load_image (struct frame *f,
3980 LA1 = xpm_scan (&s, end, &beg, &len) 3973 LA1 = xpm_scan (&s, end, &beg, &len)
3981 3974
3982#define expect(TOKEN) \ 3975#define expect(TOKEN) \
3983 if (LA1 != (TOKEN)) \ 3976 do \
3984 goto failure; \ 3977 { \
3985 else \ 3978 if (LA1 != (TOKEN)) \
3986 match () 3979 goto failure; \
3980 match (); \
3981 } \
3982 while (0)
3987 3983
3988#define expect_ident(IDENT) \ 3984#define expect_ident(IDENT) \
3989 if (LA1 == XPM_TK_IDENT \ 3985 if (LA1 == XPM_TK_IDENT \
@@ -4936,7 +4932,7 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
4936 int row_width; 4932 int row_width;
4937#endif /* HAVE_NTGUI */ 4933#endif /* HAVE_NTGUI */
4938 int x, y; 4934 int x, y;
4939 bool rc, use_img_background; 4935 bool use_img_background;
4940 unsigned long bg = 0; 4936 unsigned long bg = 0;
4941 4937
4942 if (img->mask) 4938 if (img->mask)
@@ -4945,9 +4941,8 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
4945#ifndef HAVE_NTGUI 4941#ifndef HAVE_NTGUI
4946#ifndef HAVE_NS 4942#ifndef HAVE_NS
4947 /* Create an image and pixmap serving as mask. */ 4943 /* Create an image and pixmap serving as mask. */
4948 rc = image_create_x_image_and_pixmap (f, img, img->width, img->height, 1, 4944 if (! image_create_x_image_and_pixmap (f, img, img->width, img->height, 1,
4949 &mask_img, 1); 4945 &mask_img, 1))
4950 if (!rc)
4951 return; 4946 return;
4952#endif /* !HAVE_NS */ 4947#endif /* !HAVE_NS */
4953#else 4948#else
@@ -5652,8 +5647,7 @@ struct png_memory_storage
5652static void 5647static void
5653png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length) 5648png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
5654{ 5649{
5655 struct png_memory_storage *tbr 5650 struct png_memory_storage *tbr = fn_png_get_io_ptr (png_ptr);
5656 = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr);
5657 5651
5658 if (length > tbr->len - tbr->index) 5652 if (length > tbr->len - tbr->index)
5659 fn_png_error (png_ptr, "Read error"); 5653 fn_png_error (png_ptr, "Read error");
@@ -5670,7 +5664,7 @@ png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
5670static void 5664static void
5671png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length) 5665png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
5672{ 5666{
5673 FILE *fp = (FILE *) fn_png_get_io_ptr (png_ptr); 5667 FILE *fp = fn_png_get_io_ptr (png_ptr);
5674 5668
5675 if (fread (data, 1, length, fp) < length) 5669 if (fread (data, 1, length, fp) < length)
5676 fn_png_error (png_ptr, "Read error"); 5670 fn_png_error (png_ptr, "Read error");
@@ -5814,9 +5808,9 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5814 5808
5815 /* Read image info. */ 5809 /* Read image info. */
5816 if (!NILP (specified_data)) 5810 if (!NILP (specified_data))
5817 fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); 5811 fn_png_set_read_fn (png_ptr, &tbr, png_read_from_memory);
5818 else 5812 else
5819 fn_png_set_read_fn (png_ptr, (void *) fp, png_read_from_file); 5813 fn_png_set_read_fn (png_ptr, fp, png_read_from_file);
5820 5814
5821 fn_png_set_sig_bytes (png_ptr, sizeof sig); 5815 fn_png_set_sig_bytes (png_ptr, sizeof sig);
5822 fn_png_read_info (png_ptr, info_ptr); 5816 fn_png_read_info (png_ptr, info_ptr);
@@ -6306,7 +6300,7 @@ our_memory_fill_input_buffer (j_decompress_ptr cinfo)
6306static void 6300static void
6307our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) 6301our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
6308{ 6302{
6309 struct jpeg_source_mgr *src = (struct jpeg_source_mgr *) cinfo->src; 6303 struct jpeg_source_mgr *src = cinfo->src;
6310 6304
6311 if (src) 6305 if (src)
6312 { 6306 {
@@ -6326,19 +6320,17 @@ our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
6326static void 6320static void
6327jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len) 6321jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len)
6328{ 6322{
6329 struct jpeg_source_mgr *src; 6323 struct jpeg_source_mgr *src = cinfo->src;
6330 6324
6331 if (cinfo->src == NULL) 6325 if (! src)
6332 { 6326 {
6333 /* First time for this JPEG object? */ 6327 /* First time for this JPEG object? */
6334 cinfo->src = (struct jpeg_source_mgr *) 6328 src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6335 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 6329 JPOOL_PERMANENT, sizeof *src);
6336 sizeof (struct jpeg_source_mgr)); 6330 cinfo->src = src;
6337 src = (struct jpeg_source_mgr *) cinfo->src;
6338 src->next_input_byte = data; 6331 src->next_input_byte = data;
6339 } 6332 }
6340 6333
6341 src = (struct jpeg_source_mgr *) cinfo->src;
6342 src->init_source = our_common_init_source; 6334 src->init_source = our_common_init_source;
6343 src->fill_input_buffer = our_memory_fill_input_buffer; 6335 src->fill_input_buffer = our_memory_fill_input_buffer;
6344 src->skip_input_data = our_memory_skip_input_data; 6336 src->skip_input_data = our_memory_skip_input_data;
@@ -6430,20 +6422,17 @@ our_stdio_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
6430static void 6422static void
6431jpeg_file_src (j_decompress_ptr cinfo, FILE *fp) 6423jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
6432{ 6424{
6433 struct jpeg_stdio_mgr *src; 6425 struct jpeg_stdio_mgr *src = (struct jpeg_stdio_mgr *) cinfo->src;
6434 6426
6435 if (cinfo->src != NULL) 6427 if (! src)
6436 src = (struct jpeg_stdio_mgr *) cinfo->src;
6437 else
6438 { 6428 {
6439 /* First time for this JPEG object? */ 6429 /* First time for this JPEG object? */
6440 cinfo->src = (struct jpeg_source_mgr *) 6430 src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6441 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 6431 JPOOL_PERMANENT, sizeof *src);
6442 sizeof (struct jpeg_stdio_mgr)); 6432 cinfo->src = (struct jpeg_source_mgr *) src;
6443 src = (struct jpeg_stdio_mgr *) cinfo->src; 6433 src->buffer = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6444 src->buffer = (JOCTET *) 6434 JPOOL_PERMANENT,
6445 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 6435 JPEG_STDIO_BUFFER_SIZE);
6446 JPEG_STDIO_BUFFER_SIZE);
6447 } 6436 }
6448 6437
6449 src->file = fp; 6438 src->file = fp;
@@ -7746,6 +7735,7 @@ enum imagemagick_keyword_index
7746 IMAGEMAGICK_WIDTH, 7735 IMAGEMAGICK_WIDTH,
7747 IMAGEMAGICK_MAX_HEIGHT, 7736 IMAGEMAGICK_MAX_HEIGHT,
7748 IMAGEMAGICK_MAX_WIDTH, 7737 IMAGEMAGICK_MAX_WIDTH,
7738 IMAGEMAGICK_FORMAT,
7749 IMAGEMAGICK_ROTATION, 7739 IMAGEMAGICK_ROTATION,
7750 IMAGEMAGICK_CROP, 7740 IMAGEMAGICK_CROP,
7751 IMAGEMAGICK_LAST 7741 IMAGEMAGICK_LAST
@@ -7770,6 +7760,7 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7770 {":width", IMAGE_INTEGER_VALUE, 0}, 7760 {":width", IMAGE_INTEGER_VALUE, 0},
7771 {":max-height", IMAGE_INTEGER_VALUE, 0}, 7761 {":max-height", IMAGE_INTEGER_VALUE, 0},
7772 {":max-width", IMAGE_INTEGER_VALUE, 0}, 7762 {":max-width", IMAGE_INTEGER_VALUE, 0},
7763 {":format", IMAGE_SYMBOL_VALUE, 0},
7773 {":rotation", IMAGE_NUMBER_VALUE, 0}, 7764 {":rotation", IMAGE_NUMBER_VALUE, 0},
7774 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} 7765 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
7775 }; 7766 };
@@ -7848,6 +7839,233 @@ imagemagick_error (MagickWand *wand)
7848 description = (char *) MagickRelinquishMemory (description); 7839 description = (char *) MagickRelinquishMemory (description);
7849} 7840}
7850 7841
7842/* Possibly give ImageMagick some extra help to determine the image
7843 type by supplying a "dummy" filename based on the Content-Type. */
7844
7845static char *
7846imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent])
7847{
7848 Lisp_Object symbol = intern ("image-format-suffixes");
7849 Lisp_Object val = find_symbol_value (symbol);
7850 Lisp_Object format;
7851
7852 if (! CONSP (val))
7853 return NULL;
7854
7855 format = image_spec_value (spec, intern (":format"), NULL);
7856 val = Fcar_safe (Fcdr_safe (Fassq (format, val)));
7857 if (! STRINGP (val))
7858 return NULL;
7859
7860 /* It's OK to truncate the hint if it has MaxTextExtent or more bytes,
7861 as ImageMagick would ignore the extra bytes anyway. */
7862 snprintf (hint_buffer, MaxTextExtent, "/tmp/foo.%s", SSDATA (val));
7863 return hint_buffer;
7864}
7865
7866/* Animated images (e.g., GIF89a) are composed from one "master image"
7867 (which is the first one, and then there's a number of images that
7868 follow. If following images have non-transparent colors, these are
7869 composed "on top" of the master image. So, in general, one has to
7870 compute ann the preceding images to be able to display a particular
7871 sub-image.
7872
7873 Computing all the preceding images is too slow, so we maintain a
7874 cache of previously computed images. We have to maintain a cache
7875 separate from the image cache, because the images may be scaled
7876 before display. */
7877
7878struct animation_cache
7879{
7880 MagickWand *wand;
7881 int index;
7882 struct timespec update_time;
7883 struct animation_cache *next;
7884 char signature[FLEXIBLE_ARRAY_MEMBER];
7885};
7886
7887static struct animation_cache *animation_cache = NULL;
7888
7889static struct animation_cache *
7890imagemagick_create_cache (char *signature)
7891{
7892 struct animation_cache *cache
7893 = xmalloc (offsetof (struct animation_cache, signature)
7894 + strlen (signature) + 1);
7895 cache->wand = 0;
7896 cache->index = 0;
7897 cache->next = 0;
7898 strcpy (cache->signature, signature);
7899 return cache;
7900}
7901
7902/* Discard cached images that haven't been used for a minute. */
7903static void
7904imagemagick_prune_animation_cache (void)
7905{
7906 struct animation_cache **pcache = &animation_cache;
7907 struct timespec old = timespec_sub (current_timespec (),
7908 make_timespec (60, 0));
7909
7910 while (*pcache)
7911 {
7912 struct animation_cache *cache = *pcache;
7913 if (timespec_cmp (old, cache->update_time) <= 0)
7914 pcache = &cache->next;
7915 else
7916 {
7917 if (cache->wand)
7918 DestroyMagickWand (cache->wand);
7919 *pcache = cache->next;
7920 xfree (cache);
7921 }
7922 }
7923}
7924
7925static struct animation_cache *
7926imagemagick_get_animation_cache (MagickWand *wand)
7927{
7928 char *signature = MagickGetImageSignature (wand);
7929 struct animation_cache *cache;
7930 struct animation_cache **pcache = &animation_cache;
7931
7932 imagemagick_prune_animation_cache ();
7933
7934 while (1)
7935 {
7936 cache = *pcache;
7937 if (! cache)
7938 {
7939 *pcache = cache = imagemagick_create_cache (signature);
7940 break;
7941 }
7942 if (strcmp (signature, cache->signature) == 0)
7943 break;
7944 pcache = &cache->next;
7945 }
7946
7947 DestroyString (signature);
7948 cache->update_time = current_timespec ();
7949 return cache;
7950}
7951
7952static MagickWand *
7953imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
7954{
7955 int i;
7956 MagickWand *composite_wand;
7957 size_t dest_width, dest_height;
7958 struct animation_cache *cache = imagemagick_get_animation_cache (super_wand);
7959
7960 MagickSetIteratorIndex (super_wand, 0);
7961
7962 if (ino == 0 || cache->wand == NULL || cache->index > ino)
7963 {
7964 composite_wand = MagickGetImage (super_wand);
7965 if (cache->wand)
7966 DestroyMagickWand (cache->wand);
7967 }
7968 else
7969 composite_wand = cache->wand;
7970
7971 dest_width = MagickGetImageWidth (composite_wand);
7972 dest_height = MagickGetImageHeight (composite_wand);
7973
7974 for (i = max (1, cache->index + 1); i <= ino; i++)
7975 {
7976 MagickWand *sub_wand;
7977 PixelIterator *source_iterator, *dest_iterator;
7978 PixelWand **source, **dest;
7979 size_t source_width, source_height;
7980 ssize_t source_left, source_top;
7981 MagickPixelPacket pixel;
7982 DisposeType dispose;
7983 ptrdiff_t lines = 0;
7984
7985 MagickSetIteratorIndex (super_wand, i);
7986 sub_wand = MagickGetImage (super_wand);
7987
7988 MagickGetImagePage (sub_wand, &source_width, &source_height,
7989 &source_left, &source_top);
7990
7991 /* This flag says how to handle transparent pixels. */
7992 dispose = MagickGetImageDispose (sub_wand);
7993
7994 source_iterator = NewPixelIterator (sub_wand);
7995 if (! source_iterator)
7996 {
7997 DestroyMagickWand (composite_wand);
7998 DestroyMagickWand (sub_wand);
7999 cache->wand = NULL;
8000 image_error ("Imagemagick pixel iterator creation failed",
8001 Qnil, Qnil);
8002 return NULL;
8003 }
8004
8005 dest_iterator = NewPixelIterator (composite_wand);
8006 if (! dest_iterator)
8007 {
8008 DestroyMagickWand (composite_wand);
8009 DestroyMagickWand (sub_wand);
8010 DestroyPixelIterator (source_iterator);
8011 cache->wand = NULL;
8012 image_error ("Imagemagick pixel iterator creation failed",
8013 Qnil, Qnil);
8014 return NULL;
8015 }
8016
8017 /* The sub-image may not start at origin, so move the destination
8018 iterator to where the sub-image should start. */
8019 if (source_top > 0)
8020 {
8021 PixelSetIteratorRow (dest_iterator, source_top);
8022 lines = source_top;
8023 }
8024
8025 while ((source = PixelGetNextIteratorRow (source_iterator, &source_width))
8026 != NULL)
8027 {
8028 ptrdiff_t x;
8029
8030 /* Sanity check. This shouldn't happen, but apparently
8031 does in some pictures. */
8032 if (++lines >= dest_height)
8033 break;
8034
8035 dest = PixelGetNextIteratorRow (dest_iterator, &dest_width);
8036 for (x = 0; x < source_width; x++)
8037 {
8038 /* Sanity check. This shouldn't happen, but apparently
8039 also does in some pictures. */
8040 if (x + source_left > dest_width)
8041 break;
8042 /* Normally we only copy over non-transparent pixels,
8043 but if the disposal method is "Background", then we
8044 copy over all pixels. */
8045 if (dispose == BackgroundDispose ||
8046 PixelGetAlpha (source[x]))
8047 {
8048 PixelGetMagickColor (source[x], &pixel);
8049 PixelSetMagickColor (dest[x + source_left], &pixel);
8050 }
8051 }
8052 PixelSyncIterator (dest_iterator);
8053 }
8054
8055 DestroyPixelIterator (source_iterator);
8056 DestroyPixelIterator (dest_iterator);
8057 DestroyMagickWand (sub_wand);
8058 }
8059
8060 /* Cache a copy for the next iteration. The current wand will be
8061 destroyed by the caller. */
8062 cache->wand = CloneMagickWand (composite_wand);
8063 cache->index = ino;
8064
8065 return composite_wand;
8066}
8067
8068
7851/* Helper function for imagemagick_load, which does the actual loading 8069/* Helper function for imagemagick_load, which does the actual loading
7852 given contents and size, apart from frame and image structures, 8070 given contents and size, apart from frame and image structures,
7853 passed from imagemagick_load. Uses librimagemagick to do most of 8071 passed from imagemagick_load. Uses librimagemagick to do most of
@@ -7870,7 +8088,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
7870 XImagePtr ximg; 8088 XImagePtr ximg;
7871 int x, y; 8089 int x, y;
7872 MagickWand *image_wand; 8090 MagickWand *image_wand;
7873 MagickWand *ping_wand;
7874 PixelIterator *iterator; 8091 PixelIterator *iterator;
7875 PixelWand **pixels, *bg_wand = NULL; 8092 PixelWand **pixels, *bg_wand = NULL;
7876 MagickPixelPacket pixel; 8093 MagickPixelPacket pixel;
@@ -7881,6 +8098,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
7881 int desired_width, desired_height; 8098 int desired_width, desired_height;
7882 double rotation; 8099 double rotation;
7883 int pixelwidth; 8100 int pixelwidth;
8101 char hint_buffer[MaxTextExtent];
8102 char *filename_hint = NULL;
7884 8103
7885 /* Handle image index for image types who can contain more than one image. 8104 /* Handle image index for image types who can contain more than one image.
7886 Interface :index is same as for GIF. First we "ping" the image to see how 8105 Interface :index is same as for GIF. First we "ping" the image to see how
@@ -7891,48 +8110,48 @@ imagemagick_load_image (struct frame *f, struct image *img,
7891 MagickWandGenesis (); 8110 MagickWandGenesis ();
7892 image = image_spec_value (img->spec, QCindex, NULL); 8111 image = image_spec_value (img->spec, QCindex, NULL);
7893 ino = INTEGERP (image) ? XFASTINT (image) : 0; 8112 ino = INTEGERP (image) ? XFASTINT (image) : 0;
7894 ping_wand = NewMagickWand (); 8113 image_wand = NewMagickWand ();
7895 /* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */
7896 8114
7897 status = filename 8115 if (filename)
7898 ? MagickPingImage (ping_wand, filename) 8116 status = MagickReadImage (image_wand, filename);
7899 : MagickPingImageBlob (ping_wand, contents, size); 8117 else
8118 {
8119 filename_hint = imagemagick_filename_hint (img->spec, hint_buffer);
8120 MagickSetFilename (image_wand, filename_hint);
8121 status = MagickReadImageBlob (image_wand, contents, size);
8122 }
7900 8123
7901 if (status == MagickFalse) 8124 if (status == MagickFalse)
7902 { 8125 {
7903 imagemagick_error (ping_wand); 8126 imagemagick_error (image_wand);
7904 DestroyMagickWand (ping_wand); 8127 DestroyMagickWand (image_wand);
7905 return 0; 8128 return 0;
7906 } 8129 }
7907 8130
7908 if (ino < 0 || ino >= MagickGetNumberImages (ping_wand)) 8131 if (ino < 0 || ino >= MagickGetNumberImages (image_wand))
7909 { 8132 {
7910 image_error ("Invalid image number `%s' in image `%s'", 8133 image_error ("Invalid image number `%s' in image `%s'",
7911 image, img->spec); 8134 image, img->spec);
7912 DestroyMagickWand (ping_wand); 8135 DestroyMagickWand (image_wand);
7913 return 0; 8136 return 0;
7914 } 8137 }
7915 8138
7916 if (MagickGetNumberImages (ping_wand) > 1) 8139 if (MagickGetNumberImages (image_wand) > 1)
7917 img->lisp_data = 8140 img->lisp_data =
7918 Fcons (Qcount, 8141 Fcons (Qcount,
7919 Fcons (make_number (MagickGetNumberImages (ping_wand)), 8142 Fcons (make_number (MagickGetNumberImages (image_wand)),
7920 img->lisp_data)); 8143 img->lisp_data));
7921 8144
7922 DestroyMagickWand (ping_wand); 8145 /* If we have an animated image, get the new wand based on the
7923 8146 "super-wand". */
7924 /* Now we know how many images are inside the file. If it's not a 8147 if (MagickGetNumberImages (image_wand) > 1)
7925 bundle, the number is one. Load the image data. */
7926
7927 image_wand = NewMagickWand ();
7928
7929 if ((filename
7930 ? MagickReadImage (image_wand, filename)
7931 : MagickReadImageBlob (image_wand, contents, size))
7932 == MagickFalse)
7933 { 8148 {
7934 imagemagick_error (image_wand); 8149 MagickWand *super_wand = image_wand;
7935 goto imagemagick_error; 8150 image_wand = imagemagick_compute_animated_image (super_wand, ino);
8151 if (! image_wand)
8152 image_wand = super_wand;
8153 else
8154 DestroyMagickWand (super_wand);
7936 } 8155 }
7937 8156
7938 /* Retrieve the frame's background color, for use later. */ 8157 /* Retrieve the frame's background color, for use later. */
@@ -8120,7 +8339,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
8120 8339
8121 /* Copy pixels from the imagemagick image structure to the x image map. */ 8340 /* Copy pixels from the imagemagick image structure to the x image map. */
8122 iterator = NewPixelIterator (image_wand); 8341 iterator = NewPixelIterator (image_wand);
8123 if (iterator == (PixelIterator *) NULL) 8342 if (! iterator)
8124 { 8343 {
8125#ifdef COLOR_TABLE_SUPPORT 8344#ifdef COLOR_TABLE_SUPPORT
8126 free_color_table (); 8345 free_color_table ();
@@ -8135,7 +8354,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
8135 for (y = 0; y < image_height; y++) 8354 for (y = 0; y < image_height; y++)
8136 { 8355 {
8137 pixels = PixelGetNextIteratorRow (iterator, &width); 8356 pixels = PixelGetNextIteratorRow (iterator, &width);
8138 if (pixels == (PixelWand **) NULL) 8357 if (! pixels)
8139 break; 8358 break;
8140 for (x = 0; x < (long) width; x++) 8359 for (x = 0; x < (long) width; x++)
8141 { 8360 {
@@ -9200,7 +9419,7 @@ A cross is always drawn on black & white displays. */);
9200 9419
9201 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path, 9420 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path,
9202 doc: /* List of directories to search for window system bitmap files. */); 9421 doc: /* List of directories to search for window system bitmap files. */);
9203 Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS); 9422 Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS);
9204 9423
9205 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay, 9424 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
9206 doc: /* Maximum time after which images are removed from the cache. 9425 doc: /* Maximum time after which images are removed from the cache.