Refactor window-system configuration
[bpt/emacs.git] / src / image.c
index 8b64bdf..c444c98 100644 (file)
@@ -1,5 +1,6 @@
 /* Functions for image support on window system.
-   Copyright (C) 1989, 1992-2011 Free Software Foundation, Inc.
+
+Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -19,7 +20,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <config.h>
 #include <stdio.h>
 #include <math.h>
-#include <ctype.h>
 #include <unistd.h>
 
 #ifdef HAVE_PNG
@@ -32,6 +32,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <setjmp.h>
 
+#include <c-ctype.h>
+
 /* This makes the fields of a Display accessible, in Xlib header files.  */
 
 #define XLIB_ILLEGAL_ACCESS
@@ -48,11 +50,19 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "termhooks.h"
 #include "font.h"
 
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
-#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef HAVE_WINDOW_SYSTEM
+#include TERM_HEADER
+#endif /* HAVE_WINDOW_SYSTEM */
 
+#ifdef HAVE_X_WINDOWS
 #define COLOR_TABLE_SUPPORT 1
 
 typedef struct x_bitmap_record Bitmap_Record;
@@ -65,11 +75,7 @@ typedef struct x_bitmap_record Bitmap_Record;
 #define PIX_MASK_DRAW  1
 #endif /* HAVE_X_WINDOWS */
 
-
 #ifdef HAVE_NTGUI
-#include "w32.h"
-#include "w32term.h"
-
 /* W32_TODO : Color tables on W32.  */
 #undef COLOR_TABLE_SUPPORT
 
@@ -82,15 +88,9 @@ typedef struct w32_bitmap_record Bitmap_Record;
 #define PIX_MASK_RETAIN        0
 #define PIX_MASK_DRAW  1
 
-#define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
 #define x_defined_color w32_defined_color
 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
 
-/* Functions from w32term.c that depend on XColor (so can't go in w32term.h
-   without modifying lots of files).  */
-extern void x_query_colors (struct frame *f, XColor *colors, int ncolors);
-extern void x_query_color (struct frame *f, XColor *color);
-
 /* Version of libpng that we were compiled with, or -1 if no PNG
    support was compiled in.  This is tested by w32-win.el to correctly
    set up the alist used to search for PNG libraries.  */
@@ -98,10 +98,6 @@ Lisp_Object Qlibpng_version;
 #endif /* HAVE_NTGUI */
 
 #ifdef HAVE_NS
-#include "nsterm.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-
 #undef COLOR_TABLE_SUPPORT
 
 typedef struct ns_bitmap_record Bitmap_Record;
@@ -115,10 +111,8 @@ typedef struct ns_bitmap_record Bitmap_Record;
 #define PIX_MASK_RETAIN        0
 #define PIX_MASK_DRAW  1
 
-#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO (f)->visual
 #define x_defined_color(f, name, color_def, alloc) \
   ns_defined_color (f, name, color_def, alloc, 0)
-#define FRAME_X_SCREEN(f) 0
 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
 #endif /* HAVE_NS */
 
@@ -137,7 +131,6 @@ static unsigned long lookup_rgb_color (struct frame *f, int r, int g, int b);
 static void free_color_table (void);
 static unsigned long *colors_in_color_table (int *n);
 #endif
-static Lisp_Object Finit_image_library (Lisp_Object, Lisp_Object);
 
 /* Code to deal with bitmaps.  Bitmaps are referenced by their bitmap
    id, which is just an int that this section returns.  Bitmaps are
@@ -319,11 +312,11 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
   id = x_allocate_bitmap_record (f);
   dpyinfo->bitmaps[id - 1].img = bitmap;
   dpyinfo->bitmaps[id - 1].refcount = 1;
-  dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (SBYTES (file) + 1);
+  dpyinfo->bitmaps[id - 1].file = xmalloc (SBYTES (file) + 1);
   dpyinfo->bitmaps[id - 1].depth = 1;
   dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap);
   dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap);
-  strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
+  strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file));
   return id;
 #endif
 
@@ -365,7 +358,7 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
   dpyinfo->bitmaps[id - 1].pixmap = bitmap;
   dpyinfo->bitmaps[id - 1].have_mask = 0;
   dpyinfo->bitmaps[id - 1].refcount = 1;
-  dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (SBYTES (file) + 1);
+  dpyinfo->bitmaps[id - 1].file = xmalloc (SBYTES (file) + 1);
   dpyinfo->bitmaps[id - 1].depth = 1;
   dpyinfo->bitmaps[id - 1].height = height;
   dpyinfo->bitmaps[id - 1].width = width;
@@ -521,7 +514,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
        }
     }
 
-  xassert (interrupt_input_blocked);
+  eassert (interrupt_input_blocked);
   gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
   XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
             width, height);
@@ -576,6 +569,7 @@ static void x_emboss (struct frame *, struct image *);
 static int x_build_heuristic_mask (struct frame *, struct image *,
                                    Lisp_Object);
 #ifdef HAVE_NTGUI
+extern Lisp_Object Vlibrary_cache, QCloaded_from;
 #define CACHE_IMAGE_TYPE(type, status) \
   do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
 #else
@@ -599,7 +593,7 @@ define_image_type (struct image_type *type, int loaded)
     {
       /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
          The initialized data segment is read-only.  */
-      struct image_type *p = (struct image_type *) xmalloc (sizeof *p);
+      struct image_type *p = xmalloc (sizeof *p);
       memcpy (p, type, sizeof *p);
       p->next = image_types;
       image_types = p;
@@ -771,10 +765,9 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
       /* Record that we recognized the keyword.  If a keywords
         was found more than once, it's an error.  */
       keywords[i].value = value;
-      ++keywords[i].count;
-
       if (keywords[i].count > 1)
        return 0;
+      ++keywords[i].count;
 
       /* Check type of value against allowed type.  */
       switch (keywords[i].type)
@@ -874,7 +867,7 @@ image_spec_value (Lisp_Object spec, Lisp_Object key, int *found)
 {
   Lisp_Object tail;
 
-  xassert (valid_image_p (spec));
+  eassert (valid_image_p (spec));
 
   for (tail = XCDR (spec);
        CONSP (tail) && CONSP (XCDR (tail));
@@ -976,21 +969,20 @@ or omitted means use the selected frame.  */)
 
 static void free_image (struct frame *f, struct image *img);
 
-#define MAX_IMAGE_SIZE 6.0
+#define MAX_IMAGE_SIZE 10.0
 /* Allocate and return a new image structure for image specification
    SPEC.  SPEC has a hash value of HASH.  */
 
 static struct image *
 make_image (Lisp_Object spec, EMACS_UINT hash)
 {
-  struct image *img = (struct image *) xmalloc (sizeof *img);
+  struct image *img = xzalloc (sizeof *img);
   Lisp_Object file = image_spec_value (spec, QCfile, NULL);
 
-  xassert (valid_image_p (spec));
-  memset (img, 0, sizeof *img);
+  eassert (valid_image_p (spec));
   img->dependencies = NILP (file) ? Qnil : list1 (file);
   img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
-  xassert (img->type != NULL);
+  eassert (img->type != NULL);
   img->spec = spec;
   img->lisp_data = Qnil;
   img->ascent = DEFAULT_IMAGE_ASCENT;
@@ -1062,11 +1054,8 @@ check_image_size (struct frame *f, int width, int height)
 void
 prepare_image_for_display (struct frame *f, struct image *img)
 {
-  EMACS_TIME t;
-
   /* We're about to display IMG, so set its timestamp to `now'.  */
-  EMACS_GET_TIME (t);
-  img->timestamp = EMACS_SECS (t);
+  img->timestamp = current_emacs_time ();
 
   /* If IMG doesn't have a pixmap yet, load it now, using the image
      type dependent loader function.  */
@@ -1352,7 +1341,7 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
   XColor color;
   unsigned long result;
 
-  xassert (STRINGP (color_name));
+  eassert (STRINGP (color_name));
 
   if (x_defined_color (f, SSDATA (color_name), &color, 1)
       && img->ncolors < min (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors,
@@ -1361,9 +1350,7 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
       /* This isn't called frequently so we get away with simply
         reallocating the color vector to the needed size, here.  */
       ptrdiff_t ncolors = img->ncolors + 1;
-      img->colors =
-       (unsigned long *) xrealloc (img->colors,
-                                   ncolors * sizeof *img->colors);
+      img->colors = xrealloc (img->colors, ncolors * sizeof *img->colors);
       img->colors[ncolors - 1] = color.pixel;
       img->ncolors = ncolors;
       result = color.pixel;
@@ -1389,16 +1376,14 @@ static void postprocess_image (struct frame *, struct image *);
 struct image_cache *
 make_image_cache (void)
 {
-  struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c);
+  struct image_cache *c = xzalloc (sizeof *c);
   int size;
 
-  memset (c, 0, sizeof *c);
   size = 50;
-  c->images = (struct image **) xmalloc (size * sizeof *c->images);
+  c->images = xmalloc (size * sizeof *c->images);
   c->size = size;
   size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
-  c->buckets = (struct image **) xmalloc (size);
-  memset (c->buckets, 0, size);
+  c->buckets = xzalloc (size);
   return c;
 }
 
@@ -1464,7 +1449,7 @@ free_image_cache (struct frame *f)
       ptrdiff_t i;
 
       /* Cache should not be referenced by any frame when freed.  */
-      xassert (c->refcount == 0);
+      eassert (c->refcount == 0);
 
       for (i = 0; i < c->used; ++i)
        free_image (f, c->images[i]);
@@ -1514,8 +1499,8 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
       else if (INTEGERP (Vimage_cache_eviction_delay))
        {
          /* Free cache based on timestamp.  */
-         EMACS_TIME t;
-         double old, delay;
+         EMACS_TIME old, t;
+         double delay;
          ptrdiff_t nimages = 0;
 
          for (i = 0; i < c->used; ++i)
@@ -1529,13 +1514,13 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
            delay = 1600 * delay / nimages / nimages;
          delay = max (delay, 1);
 
-         EMACS_GET_TIME (t);
-         old = EMACS_SECS (t) - delay;
+         t = current_emacs_time ();
+         old = sub_emacs_time (t, EMACS_TIME_FROM_DOUBLE (delay));
 
          for (i = 0; i < c->used; ++i)
            {
              struct image *img = c->images[i];
-             if (img && img->timestamp < old)
+             if (img && EMACS_TIME_LT (img->timestamp, old))
                {
                  free_image (f, img);
                  ++nfreed;
@@ -1708,12 +1693,11 @@ lookup_image (struct frame *f, Lisp_Object spec)
 {
   struct image *img;
   EMACS_UINT hash;
-  EMACS_TIME now;
 
   /* F must be a window-system frame, and SPEC must be a valid image
      specification.  */
-  xassert (FRAME_WINDOW_P (f));
-  xassert (valid_image_p (spec));
+  eassert (FRAME_WINDOW_P (f));
+  eassert (valid_image_p (spec));
 
   /* Look up SPEC in the hash table of the image cache.  */
   hash = sxhash (spec, 0);
@@ -1754,6 +1738,7 @@ lookup_image (struct frame *f, Lisp_Object spec)
             `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
             `:background COLOR'.  */
          Lisp_Object ascent, margin, relief, bg;
+         int relief_bound;
 
          ascent = image_spec_value (spec, QCascent, NULL);
          if (INTEGERP (ascent))
@@ -1771,7 +1756,8 @@ lookup_image (struct frame *f, Lisp_Object spec)
            }
 
          relief = image_spec_value (spec, QCrelief, NULL);
-         if (INTEGERP (relief))
+         relief_bound = INT_MAX - max (img->hmargin, img->vmargin);
+         if (RANGED_INTEGERP (- relief_bound, relief, relief_bound))
            {
              img->relief = XINT (relief);
              img->hmargin += eabs (img->relief);
@@ -1800,8 +1786,7 @@ lookup_image (struct frame *f, Lisp_Object spec)
     }
 
   /* We're using IMG, so set its timestamp to `now'.  */
-  EMACS_GET_TIME (now);
-  img->timestamp = EMACS_SECS (now);
+  img->timestamp = current_emacs_time ();
 
   /* Value is the image id.  */
   return img->id;
@@ -1950,7 +1935,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
   Window window = FRAME_X_WINDOW (f);
   Screen *screen = FRAME_X_SCREEN (f);
 
-  xassert (interrupt_input_blocked);
+  eassert (interrupt_input_blocked);
 
   if (depth <= 0)
     depth = DefaultDepthOfScreen (screen);
@@ -1973,7 +1958,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
     }
 
   /* Allocate image raster.  */
-  (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height);
+  (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height);
 
   /* Allocate a pixmap of the same size.  */
   *pixmap = XCreatePixmap (display, window, width, height, depth);
@@ -2088,7 +2073,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
 static void
 x_destroy_x_image (XImagePtr ximg)
 {
-  xassert (interrupt_input_blocked);
+  eassert (interrupt_input_blocked);
   if (ximg)
     {
 #ifdef HAVE_X_WINDOWS
@@ -2117,7 +2102,7 @@ x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int he
 #ifdef HAVE_X_WINDOWS
   GC gc;
 
-  xassert (interrupt_input_blocked);
+  eassert (interrupt_input_blocked);
   gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
   XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height);
   XFreeGC (FRAME_X_DISPLAY (f), gc);
@@ -2132,7 +2117,7 @@ x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int he
 #endif /* HAVE_NTGUI */
 
 #ifdef HAVE_NS
-  xassert (ximg == pixmap);
+  eassert (ximg == pixmap);
   ns_retain_object (ximg);
 #endif
 }
@@ -2187,7 +2172,7 @@ slurp_file (char *file, ptrdiff_t *size)
   if (stat (file, &st) == 0
       && (fp = fopen (file, "rb")) != NULL
       && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
-      && (buf = (unsigned char *) xmalloc (st.st_size),
+      && (buf = xmalloc (st.st_size),
          fread (buf, 1, st.st_size, fp) == st.st_size))
     {
       *size = st.st_size;
@@ -2322,7 +2307,7 @@ xbm_image_p (Lisp_Object object)
   if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
     return 0;
 
-  xassert (EQ (kw[XBM_TYPE].value, Qxbm));
+  eassert (EQ (kw[XBM_TYPE].value, Qxbm));
 
   if (kw[XBM_FILE].count)
     {
@@ -2364,7 +2349,7 @@ xbm_image_p (Lisp_Object object)
             for one line of the image.  */
          for (i = 0; i < height; ++i)
            {
-             Lisp_Object elt = XVECTOR (data)->contents[i];
+             Lisp_Object elt = AREF (data, i);
 
              if (STRINGP (elt))
                {
@@ -2414,12 +2399,12 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival)
  loop:
 
   /* Skip white space.  */
-  while (*s < end && (c = *(*s)++, isspace (c)))
+  while (*s < end && (c = *(*s)++, c_isspace (c)))
     ;
 
   if (*s >= end)
     c = 0;
-  else if (isdigit (c))
+  else if (c_isdigit (c))
     {
       int value = 0, digit;
 
@@ -2431,7 +2416,7 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival)
              while (*s < end)
                {
                  c = *(*s)++;
-                 if (isdigit (c))
+                 if (c_isdigit (c))
                    digit = c - '0';
                  else if (c >= 'a' && c <= 'f')
                    digit = c - 'a' + 10;
@@ -2442,11 +2427,11 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival)
                  value = 16 * value + digit;
                }
            }
-         else if (isdigit (c))
+         else if (c_isdigit (c))
            {
              value = c - '0';
              while (*s < end
-                    && (c = *(*s)++, isdigit (c)))
+                    && (c = *(*s)++, c_isdigit (c)))
                value = 8 * value + c - '0';
            }
        }
@@ -2454,7 +2439,7 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival)
        {
          value = c - '0';
          while (*s < end
-                && (c = *(*s)++, isdigit (c)))
+                && (c = *(*s)++, c_isdigit (c)))
            value = 10 * value + c - '0';
        }
 
@@ -2463,11 +2448,11 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival)
       *ival = value;
       c = XBM_TK_NUMBER;
     }
-  else if (isalpha (c) || c == '_')
+  else if (c_isalpha (c) || c == '_')
     {
       *sval++ = c;
       while (*s < end
-            && (c = *(*s)++, (isalnum (c) || c == '_')))
+            && (c = *(*s)++, (c_isalnum (c) || c == '_')))
        *sval++ = c;
       *sval = 0;
       if (*s < end)
@@ -2507,7 +2492,7 @@ w32_create_pixmap_from_bitmap_data (int width, int height, char *data)
 
   w1 = (width + 7) / 8;         /* nb of 8bits elt in X bitmap */
   w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
-  bits = (unsigned char *) alloca (height * w2);
+  bits = alloca (height * w2);
   memset (bits, 0, height * w2);
   for (i = 0; i < height; i++)
     {
@@ -2709,7 +2694,7 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
     }
   bytes_per_line = (*width + 7) / 8 + padding_p;
   nbytes = bytes_per_line * *height;
-  p = *data = (char *) xmalloc (nbytes);
+  p = *data = xmalloc (nbytes);
 
   if (v10)
     {
@@ -2783,7 +2768,7 @@ xbm_load_image (struct frame *f, struct image *img, unsigned char *contents,
       int non_default_colors = 0;
       Lisp_Object value;
 
-      xassert (img->width > 0 && img->height > 0);
+      eassert (img->width > 0 && img->height > 0);
 
       /* Get foreground and background colors, maybe allocate colors.  */
       value = image_spec_value (img->spec, QCforeground, NULL);
@@ -2843,7 +2828,7 @@ xbm_load (struct frame *f, struct image *img)
   int success_p = 0;
   Lisp_Object file_name;
 
-  xassert (xbm_image_p (img->spec));
+  eassert (xbm_image_p (img->spec));
 
   /* If IMG->spec specifies a file name, create a non-file spec from it.  */
   file_name = image_spec_value (img->spec, QCfile, NULL);
@@ -2889,14 +2874,14 @@ xbm_load (struct frame *f, struct image *img)
       memcpy (fmt, xbm_format, sizeof fmt);
       parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm);
       (void) parsed_p;
-      xassert (parsed_p);
+      eassert (parsed_p);
 
       /* Get specified width, and height.  */
       if (!in_memory_file_p)
        {
          img->width = XFASTINT (fmt[XBM_WIDTH].value);
          img->height = XFASTINT (fmt[XBM_HEIGHT].value);
-         xassert (img->width > 0 && img->height > 0);
+         eassert (img->width > 0 && img->height > 0);
          if (!check_image_size (f, img->width, img->height))
            {
              image_error ("Invalid image size (see `max-image-size')",
@@ -2934,10 +2919,10 @@ xbm_load (struct frame *f, struct image *img)
              char *p;
              int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
 
-             p = bits = (char *) alloca (nbytes * img->height);
+             p = bits = alloca (nbytes * img->height);
              for (i = 0; i < img->height; ++i, p += nbytes)
                {
-                 Lisp_Object line = XVECTOR (data)->contents[i];
+                 Lisp_Object line = AREF (data, i);
                  if (STRINGP (line))
                    memcpy (p, SDATA (line), nbytes);
                  else
@@ -2957,7 +2942,7 @@ xbm_load (struct frame *f, struct image *img)
             invertedBits = bits;
             nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR
               * img->height;
-            bits = (char *) alloca (nbytes);
+            bits = alloca (nbytes);
             for (i = 0; i < nbytes; i++)
               bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
           }
@@ -3122,8 +3107,7 @@ static void
 xpm_init_color_cache (struct frame *f, XpmAttributes *attrs)
 {
   size_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
-  xpm_color_cache = (struct xpm_cached_color **) xmalloc (nbytes);
-  memset (xpm_color_cache, 0, nbytes);
+  xpm_color_cache = xzalloc (nbytes);
   init_color_table ();
 
   if (attrs->valuemask & XpmColorSymbols)
@@ -3187,7 +3171,7 @@ xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
     bucket = xpm_color_bucket (color_name);
 
   nbytes = offsetof (struct xpm_cached_color, name) + strlen (color_name) + 1;
-  p = (struct xpm_cached_color *) xmalloc (nbytes);
+  p = xmalloc (nbytes);
   strcpy (p->name, color_name);
   p->color = *color;
   p->next = xpm_color_cache[bucket];
@@ -3430,7 +3414,7 @@ xpm_load (struct frame *f, struct image *img)
 
       /* Allocate an XpmColorSymbol array.  */
       size = attrs.numsymbols * sizeof *xpm_syms;
-      xpm_syms = (XpmColorSymbol *) alloca (size);
+      xpm_syms = alloca (size);
       memset (xpm_syms, 0, size);
       attrs.colorsymbols = xpm_syms;
 
@@ -3453,14 +3437,14 @@ xpm_load (struct frame *f, struct image *img)
          color = XCDR (XCAR (tail));
          if (STRINGP (name))
            {
-             xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
+             xpm_syms[i].name = alloca (SCHARS (name) + 1);
              strcpy (xpm_syms[i].name, SSDATA (name));
            }
          else
            xpm_syms[i].name = empty_string;
          if (STRINGP (color))
            {
-             xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
+             xpm_syms[i].value = alloca (SCHARS (color) + 1);
              strcpy (xpm_syms[i].value, SSDATA (color));
            }
          else
@@ -3583,7 +3567,7 @@ xpm_load (struct frame *f, struct image *img)
 
       img->width = attrs.width;
       img->height = attrs.height;
-      xassert (img->width > 0 && img->height > 0);
+      eassert (img->width > 0 && img->height > 0);
 
       /* The call to XpmFreeAttributes below frees attrs.alloc_pixels.  */
 #ifdef HAVE_NTGUI
@@ -3671,16 +3655,17 @@ xpm_scan (const unsigned char **s,
   while (*s < end)
     {
       /* Skip white-space.  */
-      while (*s < end && (c = *(*s)++, isspace (c)))
+      while (*s < end && (c = *(*s)++, c_isspace (c)))
        ;
 
       /* gnus-pointer.xpm uses '-' in its identifier.
         sb-dir-plus.xpm uses '+' in its identifier.  */
-      if (isalpha (c) || c == '_' || c == '-' || c == '+')
+      if (c_isalpha (c) || c == '_' || c == '-' || c == '+')
        {
          *beg = *s - 1;
          while (*s < end
-                && (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
+                && (c = **s, c_isalnum (c)
+                    || c == '_' || c == '-' || c == '+'))
              ++*s;
          *len = *s - *beg;
          return XPM_TK_IDENT;
@@ -3747,7 +3732,7 @@ xpm_put_color_table_v (Lisp_Object color_table,
                        int chars_len,
                        Lisp_Object color)
 {
-  XVECTOR (color_table)->contents[*chars_start] = color;
+  ASET (color_table, *chars_start, color);
 }
 
 static Lisp_Object
@@ -3755,7 +3740,7 @@ xpm_get_color_table_v (Lisp_Object color_table,
                        const unsigned char *chars_start,
                        int chars_len)
 {
-  return XVECTOR (color_table)->contents[*chars_start];
+  return AREF (color_table, *chars_start);
 }
 
 static Lisp_Object
@@ -3974,7 +3959,7 @@ xpm_load_image (struct frame *f,
            {
              if (xstrcasecmp (SSDATA (XCDR (specified_color)), "None") == 0)
                color_val = Qt;
-             else if (x_defined_color (f, SDATA (XCDR (specified_color)),
+             else if (x_defined_color (f, SSDATA (XCDR (specified_color)),
                                        &cdef, 0))
                color_val = make_number (cdef.pixel);
            }
@@ -4049,7 +4034,6 @@ xpm_load_image (struct frame *f,
 
  failure:
   image_error ("Invalid XPM file (%s)", img->spec, Qnil);
- error:
   x_destroy_x_image (ximg);
   x_destroy_x_image (mask_img);
   x_clear_image (f, img);
@@ -4082,7 +4066,7 @@ xpm_load (struct frame *f,
          return 0;
        }
 
-      contents = slurp_file (SDATA (file), &size);
+      contents = slurp_file (SSDATA (file), &size);
       if (contents == NULL)
        {
          image_error ("Error loading XPM image `%s'", img->spec, Qnil);
@@ -4158,8 +4142,7 @@ static void
 init_color_table (void)
 {
   int size = CT_SIZE * sizeof (*ct_table);
-  ct_table = (struct ct_color **) xmalloc (size);
-  memset (ct_table, 0, size);
+  ct_table = xzalloc (size);
   ct_colors_allocated = 0;
 }
 
@@ -4254,7 +4237,7 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
       if (rc)
        {
          ++ct_colors_allocated;
-         p = (struct ct_color *) xmalloc (sizeof *p);
+         p = xmalloc (sizeof *p);
          p->r = r;
          p->g = g;
          p->b = b;
@@ -4272,7 +4255,7 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
       color = RGB_TO_ULONG (r, g, b);
 #endif /* HAVE_NTGUI */
       ++ct_colors_allocated;
-      p = (struct ct_color *) xmalloc (sizeof *p);
+      p = xmalloc (sizeof *p);
       p->r = r;
       p->g = g;
       p->b = b;
@@ -4327,7 +4310,7 @@ lookup_pixel_color (struct frame *f, unsigned long pixel)
        {
          ++ct_colors_allocated;
 
-         p = (struct ct_color *) xmalloc (sizeof *p);
+         p = xmalloc (sizeof *p);
          p->r = color.red;
          p->g = color.green;
          p->b = color.blue;
@@ -4359,8 +4342,7 @@ colors_in_color_table (int *n)
     }
   else
     {
-      colors = (unsigned long *) xmalloc (ct_colors_allocated
-                                         * sizeof *colors);
+      colors = xmalloc (ct_colors_allocated * sizeof *colors);
       *n = ct_colors_allocated;
 
       for (i = j = 0; i < CT_SIZE; ++i)
@@ -4449,7 +4431,7 @@ x_to_xcolors (struct frame *f, struct image *img, int rgb_p)
 
   if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width < img->height)
     memory_full (SIZE_MAX);
-  colors = (XColor *) xmalloc (sizeof *colors * img->width * img->height);
+  colors = xmalloc (sizeof *colors * img->width * img->height);
 
 #ifndef HAVE_NTGUI
   /* Get the X image IMG->pixmap.  */
@@ -4468,9 +4450,8 @@ x_to_xcolors (struct frame *f, struct image *img, int rgb_p)
   p = colors;
   for (y = 0; y < img->height; ++y)
     {
-      XColor *row = p;
-
 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
+      XColor *row = p;
       for (x = 0; x < img->width; ++x, ++p)
        p->pixel = GET_PIXEL (ximg, x, y);
       if (rgb_p)
@@ -4603,7 +4584,7 @@ x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjus
 
   if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width < img->height)
     memory_full (SIZE_MAX);
-  new = (XColor *) xmalloc (sizeof *new * img->width * img->height);
+  new = xmalloc (sizeof *new * img->width * img->height);
 
   for (y = 0; y < img->height; ++y)
     {
@@ -4753,14 +4734,12 @@ x_disable_image (struct frame *f, struct image *img)
   if (n_planes < 2 || cross_disabled_images)
     {
 #ifndef HAVE_NTGUI
-      Display *dpy = FRAME_X_DISPLAY (f);
-      GC gc;
-
 #ifndef HAVE_NS  /* TODO: NS support, however this not needed for toolbars */
 
 #define MaskForeground(f)  WHITE_PIX_DEFAULT (f)
 
-      gc = XCreateGC (dpy, img->pixmap, 0, NULL);
+      Display *dpy = FRAME_X_DISPLAY (f);
+      GC gc = XCreateGC (dpy, img->pixmap, 0, NULL);
       XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
       XDrawLine (dpy, img->pixmap, gc, 0, 0,
                 img->width - 1, img->height - 1);
@@ -4856,8 +4835,7 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
 #else
   /* Create the bit array serving as mask.  */
   row_width = (img->width + 7) / 8;
-  mask_img = xmalloc (row_width * img->height);
-  memset (mask_img, 0, row_width * img->height);
+  mask_img = xzalloc (row_width * img->height);
 
   /* Create a memory device context for IMG->pixmap.  */
   frame_dc = get_frame_dc (f);
@@ -5031,7 +5009,7 @@ pbm_scan_number (unsigned char **s, unsigned char *end)
   while (*s < end)
     {
       /* Skip white-space.  */
-      while (*s < end && (c = *(*s)++, isspace (c)))
+      while (*s < end && (c = *(*s)++, c_isspace (c)))
        ;
 
       if (c == '#')
@@ -5040,11 +5018,11 @@ pbm_scan_number (unsigned char **s, unsigned char *end)
          while (*s < end && (c = *(*s)++, c != '\n'))
            ;
        }
-      else if (isdigit (c))
+      else if (c_isdigit (c))
        {
          /* Read decimal number.  */
          val = c - '0';
-         while (*s < end && (c = *(*s)++, isdigit (c)))
+         while (*s < end && (c = *(*s)++, c_isdigit (c)))
            val = 10 * val + c - '0';
          break;
        }
@@ -5073,7 +5051,7 @@ pbm_read_file (Lisp_Object file, int *size)
   if (stat (SDATA (file), &st) == 0
       && (fp = fopen (SDATA (file), "rb")) != NULL
       && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
-      && (buf = (char *) xmalloc (st.st_size),
+      && (buf = xmalloc (st.st_size),
          fread (buf, 1, st.st_size, fp) == st.st_size))
     {
       *size = st.st_size;
@@ -5551,11 +5529,10 @@ init_png_functions (Lisp_Object libraries)
 /* Error and warning handlers installed when the PNG library
    is initialized.  */
 
-static void my_png_error (png_struct *, const char *) NO_RETURN;
-static void
+static _Noreturn void
 my_png_error (png_struct *png_ptr, const char *msg)
 {
-  xassert (png_ptr != NULL);
+  eassert (png_ptr != NULL);
   /* Avoid compiler warning about deprecated direct access to
      png_ptr's fields in libpng versions 1.4.x.  */
   image_error ("PNG error: %s", build_string (msg), Qnil);
@@ -5566,7 +5543,7 @@ my_png_error (png_struct *png_ptr, const char *msg)
 static void
 my_png_warning (png_struct *png_ptr, const char *msg)
 {
-  xassert (png_ptr != NULL);
+  eassert (png_ptr != NULL);
   image_error ("PNG warning: %s", build_string (msg), Qnil);
 }
 
@@ -5836,7 +5813,7 @@ png_load (struct frame *f, struct image *img)
      images with alpha channel, i.e. RGBA.  If conversions above were
      sufficient we should only have 3 or 4 channels here.  */
   channels = fn_png_get_channels (png_ptr, info_ptr);
-  xassert (channels == 3 || channels == 4);
+  eassert (channels == 3 || channels == 4);
 
   /* Number of bytes needed for one row of the image.  */
   row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
@@ -5845,8 +5822,8 @@ png_load (struct frame *f, struct image *img)
   if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
       || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
     memory_full (SIZE_MAX);
-  pixels = (png_byte *) xmalloc (sizeof *pixels * row_bytes * height);
-  rows = (png_byte **) xmalloc (height * sizeof *rows);
+  pixels = xmalloc (sizeof *pixels * row_bytes * height);
+  rows = xmalloc (height * sizeof *rows);
   for (i = 0; i < height; ++i)
     rows[i] = pixels + i * row_bytes;
 
@@ -6133,8 +6110,7 @@ struct my_jpeg_error_mgr
 };
 
 
-static void my_error_exit (j_common_ptr) NO_RETURN;
-static void
+static _Noreturn void
 my_error_exit (j_common_ptr cinfo)
 {
   struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
@@ -6462,8 +6438,7 @@ jpeg_load (struct frame *f, struct image *img)
        a default color, and we don't have to care about which colors
        can be freed safely, and which can't.  */
     init_color_table ();
-    colors = (unsigned long *) alloca (cinfo.actual_number_of_colors
-                                      * sizeof *colors);
+    colors = alloca (cinfo.actual_number_of_colors * sizeof *colors);
 
     for (i = 0; i < cinfo.actual_number_of_colors; ++i)
       {
@@ -6896,7 +6871,7 @@ tiff_load (struct frame *f, struct image *img)
       return 0;
     }
 
-  buf = (uint32 *) xmalloc (sizeof *buf * width * height);
+  buf = xmalloc (sizeof *buf * width * height);
 
   rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
 
@@ -7552,7 +7527,7 @@ imagemagick_image_p (Lisp_Object object)
 }
 
 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
-   Therefore rename the function so it doesnt collide with ImageMagick.  */
+   Therefore rename the function so it doesn't collide with ImageMagick.  */
 #define DrawRectangle DrawRectangleGif
 #include <wand/MagickWand.h>
 
@@ -7564,6 +7539,22 @@ extern WandExport void PixelGetMagickColor (const PixelWand *,
                                            MagickPixelPacket *);
 #endif
 
+/* Log ImageMagick error message.
+   Useful when a ImageMagick function returns the status `MagickFalse'.  */
+
+static void
+imagemagick_error (MagickWand *wand)
+{
+  char *description;
+  ExceptionType severity;
+
+  description = MagickGetException (wand, &severity);
+  image_error ("ImageMagick error: %s",
+              build_string (description),
+              Qnil);
+  description = (char *) MagickRelinquishMemory (description);
+}
+
 /* Helper function for imagemagick_load, which does the actual loading
    given contents and size, apart from frame and image structures,
    passed from imagemagick_load.  Uses librimagemagick to do most of
@@ -7581,19 +7572,14 @@ imagemagick_load_image (struct frame *f, struct image *img,
                        unsigned char *contents, unsigned int size,
                        char *filename)
 {
-  size_t width;
-  size_t height;
-
+  size_t width, height;
   MagickBooleanType status;
-
   XImagePtr ximg;
-  int x;
-  int y;
-
-  MagickWand  *image_wand;
-  MagickWand  *ping_wand;
+  int x, y;
+  MagickWand *image_wand;
+  MagickWand *ping_wand;
   PixelIterator *iterator;
-  PixelWand  **pixels;
+  PixelWand **pixels, *bg_wand = NULL;
   MagickPixelPacket  pixel;
   Lisp_Object image;
   Lisp_Object value;
@@ -7601,12 +7587,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
   EMACS_INT ino;
   int desired_width, desired_height;
   double rotation;
-  EMACS_INT imagemagick_rendermethod;
   int pixelwidth;
-  ImageInfo  *image_info;
-  ExceptionInfo *exception;
-  Image * im_image;
-
 
   /* Handle image index for image types who can contain more than one image.
      Interface :index is same as for GIF.  First we "ping" the image to see how
@@ -7618,17 +7599,20 @@ imagemagick_load_image (struct frame *f, struct image *img,
   image = image_spec_value (img->spec, QCindex, NULL);
   ino = INTEGERP (image) ? XFASTINT (image) : 0;
   ping_wand = NewMagickWand ();
-  MagickSetResolution (ping_wand, 2, 2);
-  if (filename != NULL)
-    {
-      status = MagickPingImage (ping_wand, filename);
-    }
-  else
+  /* MagickSetResolution (ping_wand, 2, 2);   (Bug#10112)  */
+
+  status = filename
+    ? MagickPingImage (ping_wand, filename)
+    : MagickPingImageBlob (ping_wand, contents, size);
+
+  if (status == MagickFalse)
     {
-      status = MagickPingImageBlob (ping_wand, contents, size);
+      imagemagick_error (ping_wand);
+      DestroyMagickWand (ping_wand);
+      return 0;
     }
 
-  if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand)))
+  if (ino < 0 || ino >= MagickGetNumberImages (ping_wand))
     {
       image_error ("Invalid image number `%s' in image `%s'",
                   image, img->spec);
@@ -7645,36 +7629,46 @@ imagemagick_load_image (struct frame *f, struct image *img,
   DestroyMagickWand (ping_wand);
 
   /* Now we know how many images are inside the file.  If it's not a
-     bundle, the number is one.  */
-
-  if (filename != NULL)
-    {
-      image_info = CloneImageInfo ((ImageInfo *) NULL);
-      (void) strcpy (image_info->filename, filename);
-      image_info->number_scenes = 1;
-      image_info->scene = ino;
-      exception = AcquireExceptionInfo ();
+     bundle, the number is one.  Load the image data.  */
 
-      im_image = ReadImage (image_info, exception);
-      DestroyExceptionInfo (exception);
+  image_wand = NewMagickWand ();
 
-      if (im_image == NULL)
-       goto imagemagick_no_wand;
-      image_wand = NewMagickWandFromImage (im_image);
-      DestroyImage (im_image);
-    }
-  else
+  if ((filename
+       ? MagickReadImage (image_wand, filename)
+       : MagickReadImageBlob (image_wand, contents, size))
+      == MagickFalse)
     {
-      image_wand = NewMagickWand ();
-      if (MagickReadImageBlob (image_wand, contents, size) == MagickFalse)
-       goto imagemagick_error;
+      imagemagick_error (image_wand);
+      goto imagemagick_error;
     }
 
+  /* Retrieve the frame's background color, for use later.  */
+  {
+    XColor bgcolor;
+    Lisp_Object specified_bg;
+
+    specified_bg = image_spec_value (img->spec, QCbackground, NULL);
+    if (!STRINGP (specified_bg)
+       || !x_defined_color (f, SSDATA (specified_bg), &bgcolor, 0))
+      {
+#ifndef HAVE_NS
+       bgcolor.pixel = FRAME_BACKGROUND_PIXEL (f);
+       x_query_color (f, &bgcolor);
+#else
+       ns_query_color (FRAME_BACKGROUND_COLOR (f), &bgcolor, 1);
+#endif
+      }
+
+    bg_wand = NewPixelWand ();
+    PixelSetRed   (bg_wand, (double) bgcolor.red   / 65535);
+    PixelSetGreen (bg_wand, (double) bgcolor.green / 65535);
+    PixelSetBlue  (bg_wand, (double) bgcolor.blue  / 65535);
+  }
+
   /* If width and/or height is set in the display spec assume we want
      to scale to those values.  If either h or w is unspecified, the
      unspecified should be calculated from the specified to preserve
      aspect ratio.  */
-
   value = image_spec_value (img->spec, QCwidth, NULL);
   desired_width = (INTEGERP (value)  ? XFASTINT (value) : -1);
   value = image_spec_value (img->spec, QCheight, NULL);
@@ -7695,6 +7689,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
       if (status == MagickFalse)
        {
          image_error ("Imagemagick scale failed", Qnil, Qnil);
+         imagemagick_error (image_wand);
          goto imagemagick_error;
        }
     }
@@ -7739,25 +7734,37 @@ imagemagick_load_image (struct frame *f, struct image *img,
   value = image_spec_value (img->spec, QCrotation, NULL);
   if (FLOATP (value))
     {
-      PixelWand* background = NewPixelWand ();
-      PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
-
       rotation = extract_float (value);
-
-      status = MagickRotateImage (image_wand, background, rotation);
-      DestroyPixelWand (background);
+      status = MagickRotateImage (image_wand, bg_wand, rotation);
       if (status == MagickFalse)
         {
           image_error ("Imagemagick image rotate failed", Qnil, Qnil);
+         imagemagick_error (image_wand);
           goto imagemagick_error;
         }
     }
 
   /* Finally we are done manipulating the image.  Figure out the
-     resulting width/height and transfer ownerwship to Emacs.  */
+     resulting width/height and transfer ownership to Emacs.  */
   height = MagickGetImageHeight (image_wand);
   width = MagickGetImageWidth (image_wand);
 
+  /* Set the canvas background color to the frame or specified
+     background, and flatten the image.  Note: as of ImageMagick
+     6.6.0, SVG image transparency is not handled properly
+     (e.g. etc/images/splash.svg shows a white background always).  */
+  {
+    MagickWand *new_wand;
+    MagickSetImageBackgroundColor (image_wand, bg_wand);
+#ifdef HAVE_MAGICKMERGEIMAGELAYERS
+    new_wand = MagickMergeImageLayers (image_wand, MergeLayer);
+#else
+    new_wand = MagickFlattenImages (image_wand);
+#endif
+    DestroyMagickWand (image_wand);
+    image_wand = new_wand;
+  }
+
   if (! (width <= INT_MAX && height <= INT_MAX
         && check_image_size (f, width, height)))
     {
@@ -7769,9 +7776,51 @@ imagemagick_load_image (struct frame *f, struct image *img,
      went ok.  */
 
   init_color_table ();
-  imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
-                              ? XINT (Vimagemagick_render_type) : 0);
-  if (imagemagick_rendermethod == 0)
+
+#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
+  if (imagemagick_render_type != 0)
+    {
+      /* Magicexportimage is normally faster than pixelpushing.  This
+         method is also well tested.  Some aspects of this method are
+         ad-hoc and needs to be more researched. */
+      int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/
+      const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/
+      /* Try to create a x pixmap to hold the imagemagick pixmap.  */
+      if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
+                                        &ximg, &img->pixmap))
+       {
+#ifdef COLOR_TABLE_SUPPORT
+         free_color_table ();
+#endif
+         image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+         goto imagemagick_error;
+       }
+
+      /* Oddly, the below code doesn't seem to work:*/
+      /* switch(ximg->bitmap_unit){ */
+      /* case 8: */
+      /*   pixelwidth=CharPixel; */
+      /*   break; */
+      /* case   16: */
+      /*   pixelwidth=ShortPixel; */
+      /*   break; */
+      /* case   32: */
+      /*   pixelwidth=LongPixel; */
+      /*   break; */
+      /* } */
+      /*
+        Here im just guessing the format of the bitmap.
+        happens to work fine for:
+        - bw djvu images
+        on rgb display.
+        seems about 3 times as fast as pixel pushing(not carefully measured)
+      */
+      pixelwidth = CharPixel; /*??? TODO figure out*/
+      MagickExportImagePixels (image_wand, 0, 0, width, height,
+                              exportdepth, pixelwidth, ximg->data);
+    }
+  else
+#endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
     {
       size_t image_height;
 
@@ -7786,7 +7835,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
           goto imagemagick_error;
         }
 
-      /* Copy imagegmagick image to x with primitive yet robust pixel
+      /* Copy imagemagick image to x with primitive yet robust pixel
          pusher loop.  This has been tested a lot with many different
          images.  */
 
@@ -7822,67 +7871,12 @@ imagemagick_load_image (struct frame *f, struct image *img,
       DestroyPixelIterator (iterator);
     }
 
-  if (imagemagick_rendermethod == 1)
-    {
-      /* Magicexportimage is normally faster than pixelpushing.  This
-         method is also well tested. Some aspects of this method are
-         ad-hoc and needs to be more researched. */
-      int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/
-      const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
-      /* Try to create a x pixmap to hold the imagemagick pixmap.  */
-      if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
-                                        &ximg, &img->pixmap))
-       {
-#ifdef COLOR_TABLE_SUPPORT
-         free_color_table ();
-#endif
-         image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
-         goto imagemagick_error;
-       }
-
-
-      /* Oddly, the below code doesnt seem to work:*/
-      /* switch(ximg->bitmap_unit){ */
-      /* case 8: */
-      /*   pixelwidth=CharPixel; */
-      /*   break; */
-      /* case   16: */
-      /*   pixelwidth=ShortPixel; */
-      /*   break; */
-      /* case   32: */
-      /*   pixelwidth=LongPixel; */
-      /*   break; */
-      /* } */
-      /*
-        Here im just guessing the format of the bitmap.
-        happens to work fine for:
-        - bw djvu images
-        on rgb display.
-        seems about 3 times as fast as pixel pushing(not carefully measured)
-      */
-      pixelwidth = CharPixel;/*??? TODO figure out*/
-#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
-      MagickExportImagePixels (image_wand,
-                              0, 0,
-                              width, height,
-                              exportdepth,
-                              pixelwidth,
-                              /*&(img->pixmap));*/
-                              ximg->data);
-#else
-      image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!",
-                  Qnil, Qnil);
-#endif
-    }
-
-
 #ifdef COLOR_TABLE_SUPPORT
   /* Remember colors allocated for this image.  */
   img->colors = colors_in_color_table (&img->ncolors);
   free_color_table ();
 #endif /* COLOR_TABLE_SUPPORT */
 
-
   img->width  = width;
   img->height = height;
 
@@ -7891,9 +7885,10 @@ imagemagick_load_image (struct frame *f, struct image *img,
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
 
-
   /* Final cleanup. image_wand should be the only resource left. */
   DestroyMagickWand (image_wand);
+  if (bg_wand) DestroyPixelWand (bg_wand);
+
   /* `MagickWandTerminus' terminates the imagemagick environment.  */
   MagickWandTerminus ();
 
@@ -7901,7 +7896,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
 
  imagemagick_error:
   DestroyMagickWand (image_wand);
- imagemagick_no_wand:
+  if (bg_wand) DestroyPixelWand (bg_wand);
+
   MagickWandTerminus ();
   /* TODO more cleanup.  */
   image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
@@ -7957,23 +7953,30 @@ DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
 Each entry in this list is a symbol named after an ImageMagick format
 tag.  See the ImageMagick manual for a list of ImageMagick formats and
 their descriptions (http://www.imagemagick.org/script/formats.php).
+You can also try the shell command: `identify -list format'.
 
 Note that ImageMagick recognizes many file-types that Emacs does not
-recognize as images, such as C.  See `imagemagick-types-inhibit'.  */)
+recognize as images, such as C.  See `imagemagick-types-enable'
+and `imagemagick-types-inhibit'.  */)
   (void)
 {
   Lisp_Object typelist = Qnil;
   size_t numf = 0;
   ExceptionInfo ex;
-  char **imtypes = GetMagickList ("*", &numf, &ex);
+  char **imtypes;
   size_t i;
   Lisp_Object Qimagemagicktype;
+
+  GetExceptionInfo(&ex);
+  imtypes = GetMagickList ("*", &numf, &ex);
+  DestroyExceptionInfo(&ex);
+
   for (i = 0; i < numf; i++)
     {
       Qimagemagicktype = intern (imtypes[i]);
       typelist = Fcons (Qimagemagicktype, typelist);
     }
-  return typelist;
+  return Fnreverse (typelist);
 }
 
 #endif /* defined (HAVE_IMAGEMAGICK) */
@@ -8478,7 +8481,7 @@ gs_image_p (Lisp_Object object)
       if (ASIZE (tem) != 4)
        return 0;
       for (i = 0; i < 4; ++i)
-       if (!INTEGERP (XVECTOR (tem)->contents[i]))
+       if (!INTEGERP (AREF (tem, i)))
          return 0;
     }
   else
@@ -8522,7 +8525,7 @@ gs_load (struct frame *f, struct image *img)
   img->height = in_height;
 
   /* Create the pixmap.  */
-  xassert (img->pixmap == NO_PIXMAP);
+  eassert (img->pixmap == NO_PIXMAP);
 
   if (x_check_image_size (0, img->width, img->height))
     {
@@ -8546,13 +8549,13 @@ gs_load (struct frame *f, struct image *img)
      don't either.  Let the Lisp loader use `unwind-protect' instead.  */
   printnum1 = FRAME_X_WINDOW (f);
   printnum2 = img->pixmap;
-  sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2);
-  window_and_pixmap_id = build_string (buffer);
+  window_and_pixmap_id
+    = make_formatted_string (buffer, "%"pMu" %"pMu, printnum1, printnum2);
 
   printnum1 = FRAME_FOREGROUND_PIXEL (f);
   printnum2 = FRAME_BACKGROUND_PIXEL (f);
-  sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2);
-  pixel_colors = build_string (buffer);
+  pixel_colors
+    = make_formatted_string (buffer, "%"pMu" %"pMu, printnum1, printnum2);
 
   XSETFRAME (frame, f);
   loader = image_spec_value (img->spec, QCloader, NULL);
@@ -8593,7 +8596,7 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
   /* Kill the GS process.  We should have found PIXMAP in the image
      cache and its image should contain a process object.  */
   img = c->images[i];
-  xassert (PROCESSP (img->lisp_data));
+  eassert (PROCESSP (img->lisp_data));
   Fkill_process (img->lisp_data, Qnil);
   img->lisp_data = Qnil;
 
@@ -8668,7 +8671,7 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
                                Tests
  ***********************************************************************/
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
 
 DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
        doc: /* Value is non-nil if SPEC is a valid image specification.  */)
@@ -8690,7 +8693,7 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
   return make_number (id);
 }
 
-#endif /* GLYPH_DEBUG != 0 */
+#endif /* GLYPH_DEBUG */
 
 
 /***********************************************************************
@@ -8904,7 +8907,7 @@ non-numeric, there is no explicit limit on the size of images.  */);
   defsubr (&Simage_mask_p);
   defsubr (&Simage_metadata);
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
   defsubr (&Simagep);
   defsubr (&Slookup_image);
 #endif
@@ -8929,13 +8932,17 @@ The value can also be nil, meaning the cache is never cleared.
 The function `clear-image-cache' disregards this variable.  */);
   Vimage_cache_eviction_delay = make_number (300);
 #ifdef HAVE_IMAGEMAGICK
-  DEFVAR_LISP ("imagemagick-render-type", Vimagemagick_render_type,
-               doc: /* Choose between ImageMagick render methods.  */);
+  DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type,
+    doc: /* Integer indicating which ImageMagick rendering method to use.
+The options are:
+  0 -- the default method (pixel pushing)
+  1 -- a newer method ("MagickExportImagePixels") that may perform
+       better (speed etc) in some cases, but has not been as thoroughly
+       tested with Emacs as the default method.  This method requires
+       ImageMagick version 6.4.6 (approximately) or later.
+*/);
+  /* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10.  */
+  imagemagick_render_type = 0;
 #endif
 
 }
-
-void
-init_image (void)
-{
-}