]> code.delx.au - gnu-emacs/blobdiff - src/image.c
Fix bug #13108 introduced by the fix to bug #12930.
[gnu-emacs] / src / image.c
index a3b64b7499759bd81ca5b164bc5041f1fafe11f0..538ae2b77723c54ba3b5774517d2b4489c84c695 100644 (file)
@@ -1,5 +1,6 @@
 /* Functions for image support on window system.
-   Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc.
+
+Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -18,8 +19,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 +31,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 +49,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,10 +74,12 @@ 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"
+
+/* We need (or want) w32.h only when we're _not_ compiling for Cygwin.  */
+#ifdef WINDOWSNT
+# include "w32.h"
+#endif
 
 /* W32_TODO : Color tables on W32.  */
 #undef COLOR_TABLE_SUPPORT
@@ -82,15 +93,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 +103,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 +116,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 +136,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
@@ -193,11 +191,11 @@ x_bitmap_width (FRAME_PTR f, ptrdiff_t id)
 }
 
 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
-int
+ptrdiff_t
 x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id)
 {
   /* HAVE_NTGUI needs the explicit cast here.  */
-  return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
+  return (ptrdiff_t) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
 }
 #endif
 
@@ -319,11 +317,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 +363,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;
@@ -414,9 +412,9 @@ x_destroy_bitmap (FRAME_PTR f, ptrdiff_t id)
 
       if (--bm->refcount == 0)
        {
-         BLOCK_INPUT;
+         block_input ();
          free_bitmap_record (dpyinfo, bm);
-         UNBLOCK_INPUT;
+         unblock_input ();
        }
     }
 }
@@ -436,6 +434,9 @@ x_destroy_all_bitmaps (Display_Info *dpyinfo)
   dpyinfo->bitmaps_last = 0;
 }
 
+static bool x_create_x_image_and_pixmap (struct frame *, int, int, int,
+                                        XImagePtr *, Pixmap *);
+static void x_destroy_x_image (XImagePtr ximg);
 
 #ifdef HAVE_X_WINDOWS
 
@@ -447,23 +448,17 @@ static unsigned long four_corners_best (XImagePtr ximg,
                                         unsigned long width,
                                         unsigned long height);
 
-static int x_create_x_image_and_pixmap (struct frame *f, int width, int height,
-                                        int depth, XImagePtr *ximg,
-                                        Pixmap *pixmap);
-
-static void x_destroy_x_image (XImagePtr ximg);
-
 
 /* Create a mask of a bitmap. Note is this not a perfect mask.
    It's nicer with some borders in this context */
 
-int
+void
 x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
 {
   Pixmap pixmap, mask;
   XImagePtr ximg, mask_img;
   unsigned long width, height;
-  int result;
+  bool result;
   unsigned long bg;
   unsigned long x, y, xp, xm, yp, ym;
   GC gc;
@@ -471,29 +466,29 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
 
   if (!(id > 0))
-    return -1;
+    return;
 
   pixmap = x_bitmap_pixmap (f, id);
   width = x_bitmap_width (f, id);
   height = x_bitmap_height (f, id);
 
-  BLOCK_INPUT;
+  block_input ();
   ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height,
                    ~0, ZPixmap);
 
   if (!ximg)
     {
-      UNBLOCK_INPUT;
-      return -1;
+      unblock_input ();
+      return;
     }
 
   result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask);
 
-  UNBLOCK_INPUT;
+  unblock_input ();
   if (!result)
     {
       XDestroyImage (ximg);
-      return -1;
+      return;
     }
 
   bg = four_corners_best (ximg, NULL, width, height);
@@ -521,7 +516,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
        }
     }
 
-  xassert (interrupt_input_blocked);
+  eassert (input_blocked_p ());
   gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
   XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
             width, height);
@@ -532,8 +527,6 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
 
   XDestroyImage (ximg);
   x_destroy_x_image (mask_img);
-
-  return 0;
 }
 
 #endif /* HAVE_X_WINDOWS */
@@ -566,16 +559,15 @@ static Lisp_Object QCcrop, QCrotation;
 static Lisp_Object Qcount, Qextension_data, Qdelay;
 static Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
 
-/* Function prototypes.  */
+/* Forward function prototypes.  */
 
-static Lisp_Object define_image_type (struct image_type *type, int loaded);
-static struct image_type *lookup_image_type (Lisp_Object symbol);
-static void image_error (const char *format, Lisp_Object, Lisp_Object);
+static struct image_type *lookup_image_type (Lisp_Object);
 static void x_laplace (struct frame *, struct image *);
 static void x_emboss (struct frame *, struct image *);
-static int x_build_heuristic_mask (struct frame *, struct image *,
-                                   Lisp_Object);
-#ifdef HAVE_NTGUI
+static void x_build_heuristic_mask (struct frame *, struct image *,
+                                    Lisp_Object);
+#ifdef WINDOWSNT
+extern Lisp_Object Vlibrary_cache;
 #define CACHE_IMAGE_TYPE(type, status) \
   do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
 #else
@@ -588,60 +580,61 @@ static int x_build_heuristic_mask (struct frame *, struct image *,
 /* Define a new image type from TYPE.  This adds a copy of TYPE to
    image_types and caches the loading status of TYPE.  */
 
-static Lisp_Object
-define_image_type (struct image_type *type, int loaded)
+static struct image_type *
+define_image_type (struct image_type *type)
 {
-  Lisp_Object success;
+  struct image_type *p = NULL;
+  Lisp_Object target_type = *type->type;
+  bool type_valid = 1;
 
-  if (!loaded)
-    success = Qnil;
-  else
+  block_input ();
+
+  for (p = image_types; p; p = p->next)
+    if (EQ (*p->type, target_type))
+      goto done;
+
+  if (type->init)
+    {
+#if defined HAVE_NTGUI && defined WINDOWSNT
+      /* If we failed to load the library before, don't try again.  */
+      Lisp_Object tested = Fassq (target_type, Vlibrary_cache);
+      if (CONSP (tested) && NILP (XCDR (tested)))
+       type_valid = 0;
+      else
+#endif
+       {
+         type_valid = type->init ();
+         CACHE_IMAGE_TYPE (target_type, type_valid ? Qt : Qnil);
+       }
+    }
+
+  if (type_valid)
     {
       /* 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);
-      memcpy (p, type, sizeof *p);
+      p = xmalloc (sizeof *p);
+      *p = *type;
       p->next = image_types;
       image_types = p;
-      success = Qt;
     }
 
-  CACHE_IMAGE_TYPE (*type->type, success);
-  return success;
-}
-
-
-/* Look up image type SYMBOL, and return a pointer to its image_type
-   structure.  Value is null if SYMBOL is not a known image type.  */
-
-static inline struct image_type *
-lookup_image_type (Lisp_Object symbol)
-{
-  struct image_type *type;
-
-  /* We must initialize the image-type if it hasn't been already.  */
-  if (NILP (Finit_image_library (symbol, Vdynamic_library_alist)))
-    return 0;                  /* unimplemented */
-
-  for (type = image_types; type; type = type->next)
-    if (EQ (symbol, *type->type))
-      break;
-
-  return type;
+ done:
+  unblock_input ();
+  return p;
 }
 
 
-/* Value is non-zero if OBJECT is a valid Lisp image specification.  A
+/* Value is true if OBJECT is a valid Lisp image specification.  A
    valid image specification is a list whose car is the symbol
    `image', and whose rest is a property list.  The property list must
    contain a value for key `:type'.  That value must be the name of a
    supported image type.  The rest of the property list depends on the
    image type.  */
 
-int
+bool
 valid_image_p (Lisp_Object object)
 {
-  int valid_p = 0;
+  bool valid_p = 0;
 
   if (IMAGEP (object))
     {
@@ -711,8 +704,8 @@ struct image_keyword
   /* The type of value allowed.  */
   enum image_value_type type;
 
-  /* Non-zero means key must be present.  */
-  int mandatory_p;
+  /* True means key must be present.  */
+  bool mandatory_p;
 
   /* Used to recognize duplicate keywords in a property list.  */
   int count;
@@ -722,18 +715,13 @@ struct image_keyword
 };
 
 
-static int parse_image_spec (Lisp_Object, struct image_keyword *,
-                             int, Lisp_Object);
-static Lisp_Object image_spec_value (Lisp_Object, Lisp_Object, int *);
-
-
 /* Parse image spec SPEC according to KEYWORDS.  A valid image spec
    has the format (image KEYWORD VALUE ...).  One of the keyword/
    value pairs must be `:type TYPE'.  KEYWORDS is a vector of
    image_keywords structures of size NKEYWORDS describing other
-   allowed keyword/value pairs.  Value is non-zero if SPEC is valid.  */
+   allowed keyword/value pairs.  Value is true if SPEC is valid.  */
 
-static int
+static bool
 parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
                  int nkeywords, Lisp_Object type)
 {
@@ -847,7 +835,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
          break;
 
        default:
-         abort ();
+         emacs_abort ();
          break;
        }
 
@@ -865,15 +853,15 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
 
 
 /* Return the value of KEY in image specification SPEC.  Value is nil
-   if KEY is not present in SPEC.  if FOUND is not null, set *FOUND
-   to 1 if KEY was found in SPEC, set it to 0 otherwise.  */
+   if KEY is not present in SPEC.  Set *FOUND depending on whether KEY
+   was found in SPEC.  */
 
 static Lisp_Object
-image_spec_value (Lisp_Object spec, Lisp_Object key, int *found)
+image_spec_value (Lisp_Object spec, Lisp_Object key, bool *found)
 {
   Lisp_Object tail;
 
-  xassert (valid_image_p (spec));
+  eassert (valid_image_p (spec));
 
   for (tail = XCDR (spec);
        CONSP (tail) && CONSP (XCDR (tail));
@@ -973,8 +961,6 @@ or omitted means use the selected frame.  */)
                 Image type independent image structures
  ***********************************************************************/
 
-static void free_image (struct frame *f, struct image *img);
-
 #define MAX_IMAGE_SIZE 10.0
 /* Allocate and return a new image structure for image specification
    SPEC.  SPEC has a hash value of HASH.  */
@@ -982,14 +968,13 @@ static void free_image (struct frame *f, struct image *img);
 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;
@@ -1025,10 +1010,9 @@ free_image (struct frame *f, struct image *img)
     }
 }
 
-/* Return 1 if the given widths and heights are valid for display;
-   otherwise, return 0. */
+/* Return true if the given widths and heights are valid for display.  */
 
-static int
+static bool
 check_image_size (struct frame *f, int width, int height)
 {
   int w, h;
@@ -1061,16 +1045,13 @@ 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.  */
   if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
-    img->load_failed_p = img->type->load (f, img) == 0;
+    img->load_failed_p = ! img->type->load (f, img);
 
 }
 
@@ -1203,7 +1184,7 @@ image_background (struct image *img, struct frame *f, XImagePtr_or_DC ximg)
   if (! img->background_valid)
     /* IMG doesn't have a background yet, try to guess a reasonable value.  */
     {
-      int free_ximg = !ximg;
+      bool free_ximg = !ximg;
 #ifdef HAVE_NTGUI
       HGDIOBJ prev;
 #endif /* HAVE_NTGUI */
@@ -1244,7 +1225,7 @@ image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_D
     {
       if (img->mask)
        {
-         int free_mask = !mask;
+         bool free_mask = !mask;
 #ifdef HAVE_NTGUI
          HGDIOBJ prev;
 #endif /* HAVE_NTGUI */
@@ -1282,23 +1263,13 @@ image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_D
                  Helper functions for X image types
  ***********************************************************************/
 
-static void x_clear_image_1 (struct frame *, struct image *, int,
-                             int, int);
-static void x_clear_image (struct frame *f, struct image *img);
-static unsigned long x_alloc_image_color (struct frame *f,
-                                          struct image *img,
-                                          Lisp_Object color_name,
-                                          unsigned long dflt);
-
-
-/* Clear X resources of image IMG on frame F.  PIXMAP_P non-zero means
-   free the pixmap if any.  MASK_P non-zero means clear the mask
-   pixmap if any.  COLORS_P non-zero means free colors allocated for
-   the image, if any.  */
+/* Clear X resources of image IMG on frame F.  PIXMAP_P means free the
+   pixmap if any.  MASK_P means clear the mask pixmap if any.
+   COLORS_P means free colors allocated for the image, if any.  */
 
 static void
-x_clear_image_1 (struct frame *f, struct image *img, int pixmap_p, int mask_p,
-                int colors_p)
+x_clear_image_1 (struct frame *f, struct image *img, bool pixmap_p,
+                bool mask_p, bool colors_p)
 {
   if (pixmap_p && img->pixmap)
     {
@@ -1333,9 +1304,9 @@ x_clear_image_1 (struct frame *f, struct image *img, int pixmap_p, int mask_p,
 static void
 x_clear_image (struct frame *f, struct image *img)
 {
-  BLOCK_INPUT;
+  block_input ();
   x_clear_image_1 (f, img, 1, 1, 1);
-  UNBLOCK_INPUT;
+  unblock_input ();
 }
 
 
@@ -1351,7 +1322,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,
@@ -1360,9 +1331,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;
@@ -1380,7 +1349,6 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
  ***********************************************************************/
 
 static void cache_image (struct frame *f, struct image *img);
-static void postprocess_image (struct frame *, struct image *);
 
 /* Return a new, initialized image cache that is allocated from the
    heap.  Call free_image_cache to free an image cache.  */
@@ -1388,16 +1356,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;
 }
 
@@ -1463,7 +1429,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]);
@@ -1494,7 +1460,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
 
       /* Block input so that we won't be interrupted by a SIGIO
         while being in an inconsistent state.  */
-      BLOCK_INPUT;
+      block_input ();
 
       if (!NILP (filter))
        {
@@ -1513,8 +1479,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)
@@ -1528,13 +1494,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;
@@ -1560,7 +1526,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
          ++windows_or_buffers_changed;
        }
 
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 }
 
@@ -1655,7 +1621,7 @@ postprocess_image (struct frame *f, struct image *img)
        x_build_heuristic_mask (f, img, mask);
       else
        {
-         int found_p;
+         bool found_p;
 
          mask = image_spec_value (spec, QCmask, &found_p);
 
@@ -1707,12 +1673,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);
@@ -1726,10 +1691,10 @@ lookup_image (struct frame *f, Lisp_Object spec)
   /* If not found, create a new image and cache it.  */
   if (img == NULL)
     {
-      BLOCK_INPUT;
+      block_input ();
       img = make_image (spec, hash);
       cache_image (f, img);
-      img->load_failed_p = img->type->load (f, img) == 0;
+      img->load_failed_p = ! img->type->load (f, img);
       img->frame_foreground = FRAME_FOREGROUND_PIXEL (f);
       img->frame_background = FRAME_BACKGROUND_PIXEL (f);
 
@@ -1797,12 +1762,11 @@ lookup_image (struct frame *f, Lisp_Object spec)
            postprocess_image (f, img);
        }
 
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 
   /* 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;
@@ -1876,7 +1840,7 @@ mark_image_cache (struct image_cache *c)
                          X / NS / W32 support code
  ***********************************************************************/
 
-#ifdef HAVE_NTGUI
+#ifdef WINDOWSNT
 
 /* Macro for defining functions that will be loaded from image DLLs.  */
 #define DEF_IMGLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
@@ -1887,18 +1851,13 @@ mark_image_cache (struct image_cache *c)
     if (!fn_##func) return 0;                                          \
   }
 
-#endif /* HAVE_NTGUI */
-
-static int x_create_x_image_and_pixmap (struct frame *, int, int, int,
-                                        XImagePtr *, Pixmap *);
-static void x_destroy_x_image (XImagePtr);
-static void x_put_x_image (struct frame *, XImagePtr, Pixmap, int, int);
+#endif /* WINDOWSNT */
 
-/* Return nonzero if XIMG's size WIDTH x HEIGHT doesn't break the
+/* Return true if XIMG's size WIDTH x HEIGHT doesn't break the
    windowing system.
    WIDTH and HEIGHT must both be positive.
    If XIMG is null, assume it is a bitmap.  */
-static int
+static bool
 x_check_image_size (XImagePtr ximg, int width, int height)
 {
 #ifdef HAVE_X_WINDOWS
@@ -1937,12 +1896,12 @@ x_check_image_size (XImagePtr ximg, int width, int height)
    frame F.  Set *XIMG and *PIXMAP to the XImage and Pixmap created.
    Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
    via xmalloc.  Print error messages via image_error if an error
-   occurs.  Value is non-zero if successful.
+   occurs.  Value is true if successful.
 
    On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
    should indicate the bit depth of the image.  */
 
-static int
+static bool
 x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
                             XImagePtr *ximg, Pixmap *pixmap)
 {
@@ -1951,7 +1910,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 (input_blocked_p ());
 
   if (depth <= 0)
     depth = DefaultDepthOfScreen (screen);
@@ -1974,7 +1933,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);
@@ -2089,7 +2048,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 (input_blocked_p ());
   if (ximg)
     {
 #ifdef HAVE_X_WINDOWS
@@ -2118,7 +2077,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 (input_blocked_p ());
   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);
@@ -2133,7 +2092,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
 }
@@ -2181,14 +2140,13 @@ x_find_image_file (Lisp_Object file)
 static unsigned char *
 slurp_file (char *file, ptrdiff_t *size)
 {
-  FILE *fp = NULL;
+  FILE *fp = fopen (file, "rb");
   unsigned char *buf = NULL;
   struct stat st;
 
-  if (stat (file, &st) == 0
-      && (fp = fopen (file, "rb")) != NULL
+  if (fp && fstat (fileno (fp), &st) == 0
       && 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;
@@ -2214,15 +2172,9 @@ slurp_file (char *file, ptrdiff_t *size)
                              XBM images
  ***********************************************************************/
 
-static int xbm_scan (unsigned char **, unsigned char *, char *, int *);
-static int xbm_load (struct frame *f, struct image *img);
-static int xbm_load_image (struct frame *f, struct image *img,
-                           unsigned char *, unsigned char *);
-static int xbm_image_p (Lisp_Object object);
-static int xbm_read_bitmap_data (struct frame *f,
-                                 unsigned char *, unsigned char *,
-                                 int *, int *, char **, int);
-static int xbm_file_p (Lisp_Object);
+static bool xbm_load (struct frame *f, struct image *img);
+static bool xbm_image_p (Lisp_Object object);
+static bool xbm_file_p (Lisp_Object);
 
 
 /* Indices of image specification fields in xbm_format, below.  */
@@ -2273,6 +2225,7 @@ static struct image_type xbm_type =
   xbm_image_p,
   xbm_load,
   x_clear_image,
+  NULL,
   NULL
 };
 
@@ -2285,10 +2238,10 @@ enum xbm_token
 };
 
 
-/* Return non-zero if OBJECT is a valid XBM-type image specification.
+/* Return true if OBJECT is a valid XBM-type image specification.
    A valid specification is a list starting with the symbol `image'
    The rest of the list is a property list which must contain an
-   entry `:type xbm..
+   entry `:type xbm'.
 
    If the specification specifies a file to load, it must contain
    an entry `:file FILENAME' where FILENAME is a string.
@@ -2314,7 +2267,7 @@ enum xbm_token
    foreground and background of the frame on which the image is
    displayed is used.  */
 
-static int
+static bool
 xbm_image_p (Lisp_Object object)
 {
   struct image_keyword kw[XBM_LAST];
@@ -2323,7 +2276,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)
     {
@@ -2365,7 +2318,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))
                {
@@ -2415,12 +2368,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;
 
@@ -2432,7 +2385,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;
@@ -2443,11 +2396,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';
            }
        }
@@ -2455,7 +2408,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';
        }
 
@@ -2464,11 +2417,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)
@@ -2508,7 +2461,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++)
     {
@@ -2572,7 +2525,7 @@ convert_mono_to_color_image (struct frame *f, struct image *img,
 static void
 Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
                                RGB_PIXEL_COLOR fg, RGB_PIXEL_COLOR bg,
-                               int non_default_colors)
+                               bool non_default_colors)
 {
 #ifdef HAVE_NTGUI
   img->pixmap
@@ -2604,20 +2557,20 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
    X versions.  CONTENTS is a pointer to a buffer to parse; END is the
    buffer's end.  Set *WIDTH and *HEIGHT to the width and height of
    the image.  Return in *DATA the bitmap data allocated with xmalloc.
-   Value is non-zero if successful.  DATA null means just test if
-   CONTENTS looks like an in-memory XBM file.  If INHIBIT_IMAGE_ERROR
-   is non-zero, inhibit the call to image_error when the image size is
-   invalid (the bitmap remains unread).  */
+   Value is true if successful.  DATA null means just test if
+   CONTENTS looks like an in-memory XBM file.  If INHIBIT_IMAGE_ERROR,
+   inhibit the call to image_error when the image size is invalid (the
+   bitmap remains unread).  */
 
-static int
+static bool
 xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *end,
                      int *width, int *height, char **data,
-                     int inhibit_image_error)
+                     bool inhibit_image_error)
 {
   unsigned char *s = contents;
   char buffer[BUFSIZ];
-  int padding_p = 0;
-  int v10 = 0;
+  bool padding_p = 0;
+  bool v10 = 0;
   int bytes_per_line, i, nbytes;
   char *p;
   int value;
@@ -2710,7 +2663,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)
     {
@@ -2764,16 +2717,16 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
 
 
 /* Load XBM image IMG which will be displayed on frame F from buffer
-   CONTENTS.  END is the end of the buffer.  Value is non-zero if
+   CONTENTS.  END is the end of the buffer.  Value is true if
    successful.  */
 
-static int
+static bool
 xbm_load_image (struct frame *f, struct image *img, unsigned char *contents,
                unsigned char *end)
 {
-  int rc;
+  bool rc;
   char *data;
-  int success_p = 0;
+  bool success_p = 0;
 
   rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height,
                             &data, 0);
@@ -2781,10 +2734,10 @@ xbm_load_image (struct frame *f, struct image *img, unsigned char *contents,
     {
       unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
       unsigned long background = FRAME_BACKGROUND_PIXEL (f);
-      int non_default_colors = 0;
+      bool 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);
@@ -2822,9 +2775,9 @@ xbm_load_image (struct frame *f, struct image *img, unsigned char *contents,
 }
 
 
-/* Value is non-zero if DATA looks like an in-memory XBM file.  */
+/* Value is true if DATA looks like an in-memory XBM file.  */
 
-static int
+static bool
 xbm_file_p (Lisp_Object data)
 {
   int w, h;
@@ -2836,15 +2789,15 @@ xbm_file_p (Lisp_Object data)
 
 
 /* Fill image IMG which is used on frame F with pixmap data.  Value is
-   non-zero if successful.  */
+   true if successful.  */
 
-static int
+static bool
 xbm_load (struct frame *f, struct image *img)
 {
-  int success_p = 0;
+  bool 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);
@@ -2877,10 +2830,10 @@ xbm_load (struct frame *f, struct image *img)
       Lisp_Object data;
       unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
       unsigned long background = FRAME_BACKGROUND_PIXEL (f);
-      int non_default_colors = 0;
+      bool non_default_colors = 0;
       char *bits;
-      int parsed_p;
-      int in_memory_file_p = 0;
+      bool parsed_p;
+      bool in_memory_file_p = 0;
 
       /* See if data looks like an in-memory XBM file.  */
       data = image_spec_value (img->spec, QCdata, NULL);
@@ -2889,15 +2842,14 @@ xbm_load (struct frame *f, struct image *img)
       /* Parse the image specification.  */
       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')",
@@ -2935,10 +2887,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
@@ -2950,7 +2902,7 @@ xbm_load (struct frame *f, struct image *img)
          else
            bits = (char *) XBOOL_VECTOR (data)->data;
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
           {
             char *invertedBits;
             int nbytes, i;
@@ -2958,7 +2910,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]);
           }
@@ -2994,9 +2946,8 @@ xbm_load (struct frame *f, struct image *img)
 
 #if defined (HAVE_XPM) || defined (HAVE_NS)
 
-static int xpm_image_p (Lisp_Object object);
-static int xpm_load (struct frame *f, struct image *img);
-static int xpm_valid_color_symbols_p (Lisp_Object);
+static bool xpm_image_p (Lisp_Object object);
+static bool xpm_load (struct frame *f, struct image *img);
 
 #endif /* HAVE_XPM || HAVE_NS */
 
@@ -3062,6 +3013,12 @@ static const struct image_keyword xpm_format[XPM_LAST] =
   {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
+#if defined HAVE_NTGUI && defined WINDOWSNT
+static bool init_xpm_functions (void);
+#else
+#define init_xpm_functions NULL
+#endif
+
 /* Structure describing the image type XPM.  */
 
 static struct image_type xpm_type =
@@ -3070,6 +3027,7 @@ static struct image_type xpm_type =
   xpm_image_p,
   xpm_load,
   x_clear_image,
+  init_xpm_functions,
   NULL
 };
 
@@ -3087,10 +3045,6 @@ static struct image_type xpm_type =
 
 #ifdef ALLOC_XPM_COLORS
 
-static void xpm_init_color_cache (struct frame *, XpmAttributes *);
-static void xpm_free_color_cache (void);
-static int xpm_lookup_color (struct frame *, char *, XColor *);
-static int xpm_color_bucket (char *);
 static struct xpm_cached_color *xpm_cache_color (struct frame *, char *,
                                                  XColor *, int);
 
@@ -3123,8 +3077,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)
@@ -3188,7 +3141,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];
@@ -3198,10 +3151,10 @@ xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
 
 /* Look up color COLOR_NAME for frame F in the color cache.  If found,
    return the cached definition in *COLOR.  Otherwise, make a new
-   entry in the cache and allocate the color.  Value is zero if color
+   entry in the cache and allocate the color.  Value is false if color
    allocation failed.  */
 
-static int
+static bool
 xpm_lookup_color (struct frame *f, char *color_name, XColor *color)
 {
   struct xpm_cached_color *p;
@@ -3259,7 +3212,7 @@ xpm_free_colors (Display *dpy, Colormap cmap, Pixel *pixels, int npixels, void *
 #endif /* ALLOC_XPM_COLORS */
 
 
-#ifdef HAVE_NTGUI
+#ifdef WINDOWSNT
 
 /* XPM library details.  */
 
@@ -3270,12 +3223,12 @@ DEF_IMGLIB_FN (int, XpmReadFileToImage, (Display *, char *, xpm_XImage **,
                                    xpm_XImage **, XpmAttributes *));
 DEF_IMGLIB_FN (void, XImageFree, (xpm_XImage *));
 
-static int
-init_xpm_functions (Lisp_Object libraries)
+static bool
+init_xpm_functions (void)
 {
   HMODULE library;
 
-  if (!(library = w32_delayed_load (libraries, Qxpm)))
+  if (!(library = w32_delayed_load (Qxpm)))
     return 0;
 
   LOAD_IMGLIB_FN (library, XpmFreeAttributes);
@@ -3285,14 +3238,21 @@ init_xpm_functions (Lisp_Object libraries)
   return 1;
 }
 
-#endif /* HAVE_NTGUI */
+#endif /* WINDOWSNT */
 
+#if defined HAVE_NTGUI && !defined WINDOWSNT
+/* Glue for code below */
+#define fn_XpmReadFileToImage XpmReadFileToImage
+#define fn_XpmCreateImageFromBuffer XpmCreateImageFromBuffer
+#define fn_XImageFree XImageFree
+#define fn_XpmFreeAttributes XpmFreeAttributes
+#endif /* HAVE_NTGUI && !WINDOWSNT */
 
-/* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
+/* Value is true if COLOR_SYMBOLS is a valid color symbols list
    for XPM images.  Such a list must consist of conses whose car and
    cdr are strings.  */
 
-static int
+static bool
 xpm_valid_color_symbols_p (Lisp_Object color_symbols)
 {
   while (CONSP (color_symbols))
@@ -3309,9 +3269,9 @@ xpm_valid_color_symbols_p (Lisp_Object color_symbols)
 }
 
 
-/* Value is non-zero if OBJECT is a valid XPM image specification.  */
+/* Value is true if OBJECT is a valid XPM image specification.  */
 
-static int
+static bool
 xpm_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[XPM_LAST];
@@ -3368,11 +3328,11 @@ x_create_bitmap_from_xpm_data (struct frame *f, const char **bits)
 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
 
 /* Load image IMG which will be displayed on frame F.  Value is
-   non-zero if successful.  */
+   true if successful.  */
 
 #ifdef HAVE_XPM
 
-static int
+static bool
 xpm_load (struct frame *f, struct image *img)
 {
   int rc;
@@ -3431,7 +3391,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;
 
@@ -3454,14 +3414,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
@@ -3584,7 +3544,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
@@ -3672,16 +3632,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;
@@ -3748,7 +3709,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
@@ -3756,7 +3717,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
@@ -3825,7 +3786,7 @@ xpm_str_to_color_key (const char *s)
   return -1;
 }
 
-static int
+static bool
 xpm_load_image (struct frame *f,
                 struct image *img,
                 const unsigned char *contents,
@@ -3840,7 +3801,8 @@ xpm_load_image (struct frame *f,
   void (*put_color_table) (Lisp_Object, const unsigned char *, int, Lisp_Object);
   Lisp_Object (*get_color_table) (Lisp_Object, const unsigned char *, int);
   Lisp_Object frame, color_symbols, color_table;
-  int best_key, have_mask = 0;
+  int best_key;
+  bool have_mask = 0;
   XImagePtr ximg = NULL, mask_img = NULL;
 
 #define match() \
@@ -3975,7 +3937,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);
            }
@@ -4050,7 +4012,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);
@@ -4061,11 +4022,11 @@ xpm_load_image (struct frame *f,
 #undef expect_ident
 }
 
-static int
+static bool
 xpm_load (struct frame *f,
           struct image *img)
 {
-  int success_p = 0;
+  bool success_p = 0;
   Lisp_Object file_name;
 
   /* If IMG->spec specifies a file name, create a non-file spec from it.  */
@@ -4083,7 +4044,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);
@@ -4159,8 +4120,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;
 }
 
@@ -4237,7 +4197,7 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
 #ifdef HAVE_X_WINDOWS
       XColor color;
       Colormap cmap;
-      int rc;
+      bool rc;
 #else
       COLORREF color;
 #endif
@@ -4255,7 +4215,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;
@@ -4273,7 +4233,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;
@@ -4305,7 +4265,7 @@ lookup_pixel_color (struct frame *f, unsigned long pixel)
     {
       XColor color;
       Colormap cmap;
-      int rc;
+      bool rc;
 
       if (ct_colors_allocated_max <= ct_colors_allocated)
        return FRAME_FOREGROUND_PIXEL (f);
@@ -4316,19 +4276,19 @@ lookup_pixel_color (struct frame *f, unsigned long pixel)
       x_query_color (f, &color);
       rc = x_alloc_nearest_color (f, cmap, &color);
 #else
-      BLOCK_INPUT;
+      block_input ();
       cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
       color.pixel = pixel;
       XQueryColor (NULL, cmap, &color);
       rc = x_alloc_nearest_color (f, cmap, &color);
-      UNBLOCK_INPUT;
+      unblock_input ();
 #endif /* HAVE_X_WINDOWS */
 
       if (rc)
        {
          ++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;
@@ -4360,8 +4320,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)
@@ -4400,14 +4359,6 @@ init_color_table (void)
                              Algorithms
  ***********************************************************************/
 
-static XColor *x_to_xcolors (struct frame *, struct image *, int);
-static void x_from_xcolors (struct frame *, struct image *, XColor *);
-static void x_detect_edges (struct frame *, struct image *, int[9], int);
-
-#ifdef HAVE_NTGUI
-static void XPutPixel (XImagePtr , int, int, COLORREF);
-#endif /* HAVE_NTGUI */
-
 /* Edge detection matrices for different edge-detection
    strategies.  */
 
@@ -4433,12 +4384,12 @@ static int laplace_matrix[9] = {
 
 /* On frame F, return an array of XColor structures describing image
    IMG->pixmap.  Each XColor structure has its pixel color set.  RGB_P
-   non-zero means also fill the red/green/blue members of the XColor
+   means also fill the red/green/blue members of the XColor
    structures.  Value is a pointer to the array of XColors structures,
    allocated with xmalloc; it must be freed by the caller.  */
 
 static XColor *
-x_to_xcolors (struct frame *f, struct image *img, int rgb_p)
+x_to_xcolors (struct frame *f, struct image *img, bool rgb_p)
 {
   int x, y;
   XColor *colors, *p;
@@ -4450,7 +4401,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.  */
@@ -4469,9 +4420,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)
@@ -4604,7 +4554,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)
     {
@@ -4754,14 +4704,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);
@@ -4817,9 +4765,9 @@ x_disable_image (struct frame *f, struct image *img)
    determine the background color of IMG.  If it is a list '(R G B)',
    with R, G, and B being integers >= 0, take that as the color of the
    background.  Otherwise, determine the background color of IMG
-   heuristically.  Value is non-zero if successful. */
+   heuristically.  */
 
-static int
+static void
 x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
 {
   XImagePtr_or_DC ximg;
@@ -4831,7 +4779,8 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
   char *mask_img;
   int row_width;
 #endif /* HAVE_NTGUI */
-  int x, y, rc, use_img_background;
+  int x, y;
+  bool rc, use_img_background;
   unsigned long bg = 0;
 
   if (img->mask)
@@ -4847,7 +4796,7 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
   rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1,
                                    &mask_img, &img->mask);
   if (!rc)
-    return 0;
+    return;
 #endif /* !HAVE_NS */
 
   /* Get the X image of IMG->pixmap.  */
@@ -4857,8 +4806,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);
@@ -4938,8 +4886,6 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
 #endif /* HAVE_NTGUI */
 
   Destroy_Image (ximg, prev);
-
-  return 1;
 }
 
 \f
@@ -4947,9 +4893,8 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
                       PBM (mono, gray, color)
  ***********************************************************************/
 
-static int pbm_image_p (Lisp_Object object);
-static int pbm_load (struct frame *f, struct image *img);
-static int pbm_scan_number (unsigned char **, unsigned char *);
+static bool pbm_image_p (Lisp_Object object);
+static bool pbm_load (struct frame *f, struct image *img);
 
 /* The symbol `pbm' identifying images of this type.  */
 
@@ -4999,13 +4944,14 @@ static struct image_type pbm_type =
   pbm_image_p,
   pbm_load,
   x_clear_image,
+  NULL,
   NULL
 };
 
 
-/* Return non-zero if OBJECT is a valid PBM image specification.  */
+/* Return true if OBJECT is a valid PBM image specification.  */
 
-static int
+static bool
 pbm_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[PBM_LAST];
@@ -5032,7 +4978,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 == '#')
@@ -5041,11 +4987,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;
        }
@@ -5057,51 +5003,13 @@ pbm_scan_number (unsigned char **s, unsigned char *end)
 }
 
 
-#ifdef HAVE_NTGUI
-#if 0  /* Unused. ++kfs  */
-
-/* Read FILE into memory.  Value is a pointer to a buffer allocated
-   with xmalloc holding FILE's contents.  Value is null if an error
-   occurred.  *SIZE is set to the size of the file.  */
-
-static char *
-pbm_read_file (Lisp_Object file, int *size)
-{
-  FILE *fp = NULL;
-  char *buf = NULL;
-  struct stat st;
-
-  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),
-         fread (buf, 1, st.st_size, fp) == st.st_size))
-    {
-      *size = st.st_size;
-      fclose (fp);
-    }
-  else
-    {
-      if (fp)
-       fclose (fp);
-      if (buf)
-       {
-         xfree (buf);
-         buf = NULL;
-       }
-    }
-
-  return buf;
-}
-#endif
-#endif /* HAVE_NTGUI */
-
 /* Load PBM image IMG for use on frame F.  */
 
-static int
+static bool
 pbm_load (struct frame *f, struct image *img)
 {
-  int raw_p, x, y;
+  bool raw_p;
+  int x, y;
   int width, height, max_color_idx = 0;
   XImagePtr ximg;
   Lisp_Object file, specified_file;
@@ -5364,8 +5272,8 @@ pbm_load (struct frame *f, struct image *img)
 
 /* Function prototypes.  */
 
-static int png_image_p (Lisp_Object object);
-static int png_load (struct frame *f, struct image *img);
+static bool png_image_p (Lisp_Object object);
+static bool png_load (struct frame *f, struct image *img);
 
 /* The symbol `png' identifying images of this type.  */
 
@@ -5405,6 +5313,12 @@ static const struct image_keyword png_format[PNG_LAST] =
   {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
+#if defined HAVE_NTGUI && defined WINDOWSNT
+static bool init_png_functions (void);
+#else
+#define init_png_functions NULL
+#endif
+
 /* Structure describing the image type `png'.  */
 
 static struct image_type png_type =
@@ -5413,12 +5327,13 @@ static struct image_type png_type =
   png_image_p,
   png_load,
   x_clear_image,
+  init_png_functions,
   NULL
 };
 
-/* Return non-zero if OBJECT is a valid PNG image specification.  */
+/* Return true if OBJECT is a valid PNG image specification.  */
 
-static int
+static bool
 png_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[PNG_LAST];
@@ -5436,7 +5351,7 @@ png_image_p (Lisp_Object object)
 
 #ifdef HAVE_PNG
 
-#ifdef HAVE_NTGUI
+#ifdef WINDOWSNT
 /* PNG library details.  */
 
 DEF_IMGLIB_FN (png_voidp, png_get_io_ptr, (png_structp));
@@ -5470,12 +5385,12 @@ DEF_IMGLIB_FN (void, png_longjmp, (png_structp, int));
 DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn, (png_structp, png_longjmp_ptr, size_t));
 #endif /* libpng version >= 1.5 */
 
-static int
-init_png_functions (Lisp_Object libraries)
+static bool
+init_png_functions (void)
 {
   HMODULE library;
 
-  if (!(library = w32_delayed_load (libraries, Qpng)))
+  if (!(library = w32_delayed_load (Qpng)))
     return 0;
 
   LOAD_IMGLIB_FN (library, png_get_io_ptr);
@@ -5536,27 +5451,35 @@ init_png_functions (Lisp_Object libraries)
 #define fn_png_set_longjmp_fn          png_set_longjmp_fn
 #endif /* libpng version >= 1.5 */
 
-#endif /* HAVE_NTGUI */
+#endif /* WINDOWSNT */
 
+/* Possibly inefficient/inexact substitutes for _setjmp and _longjmp.
+   Do not use sys_setjmp, as PNG supports only jmp_buf.  The _longjmp
+   substitute may munge the signal mask, but that should be OK here.
+   MinGW (MS-Windows) uses _setjmp and defines setjmp to _setjmp in
+   the system header setjmp.h; don't mess up that.  */
+#ifndef HAVE__SETJMP
+# define _setjmp(j) setjmp (j)
+# define _longjmp longjmp
+#endif
 
 #if (PNG_LIBPNG_VER < 10500)
-#define PNG_LONGJMP(ptr) (longjmp ((ptr)->jmpbuf, 1))
+#define PNG_LONGJMP(ptr) (_longjmp ((ptr)->jmpbuf, 1))
 #define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
 #else
 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908)  */
 #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
 #define PNG_JMPBUF(ptr) \
-  (*fn_png_set_longjmp_fn ((ptr), longjmp, sizeof (jmp_buf)))
+  (*fn_png_set_longjmp_fn ((ptr), _longjmp, sizeof (jmp_buf)))
 #endif
 
 /* 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);
@@ -5567,7 +5490,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);
 }
 
@@ -5613,28 +5536,39 @@ png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
 }
 
 
-/* Load PNG image IMG for use on frame F.  Value is non-zero if
+/* Load PNG image IMG for use on frame F.  Value is true if
    successful.  */
 
-static int
-png_load (struct frame *f, struct image *img)
+struct png_load_context
+{
+  /* These are members so that longjmp doesn't munge local variables.  */
+  png_struct *png_ptr;
+  png_info *info_ptr;
+  png_info *end_info;
+  FILE *fp;
+  png_byte *pixels;
+  png_byte **rows;
+};
+
+static bool
+png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
 {
   Lisp_Object file, specified_file;
   Lisp_Object specified_data;
   int x, y;
   ptrdiff_t i;
   XImagePtr ximg, mask_img = NULL;
-  png_struct *png_ptr = NULL;
+  png_struct *png_ptr;
   png_info *info_ptr = NULL, *end_info = NULL;
-  FILE *volatile fp = NULL;
+  FILE *fp = NULL;
   png_byte sig[8];
-  png_byte * volatile pixels = NULL;
-  png_byte ** volatile rows = NULL;
+  png_byte *pixels = NULL;
+  png_byte **rows = NULL;
   png_uint_32 width, height;
   int bit_depth, color_type, interlace_type;
   png_byte channels;
   png_uint_32 row_bytes;
-  int transparent_p;
+  bool transparent_p;
   struct png_memory_storage tbr;  /* Data to be read */
 
   /* Find out what file to load.  */
@@ -5696,41 +5630,47 @@ png_load (struct frame *f, struct image *img)
   png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING,
                                       NULL, my_png_error,
                                       my_png_warning);
-  if (!png_ptr)
+  if (png_ptr)
     {
-      if (fp) fclose (fp);
-      return 0;
+      info_ptr = fn_png_create_info_struct (png_ptr);
+      end_info = fn_png_create_info_struct (png_ptr);
     }
 
-  info_ptr = fn_png_create_info_struct (png_ptr);
-  if (!info_ptr)
+  c->png_ptr = png_ptr;
+  c->info_ptr = info_ptr;
+  c->end_info = end_info;
+  c->fp = fp;
+  c->pixels = pixels;
+  c->rows = rows;
+
+  if (! (info_ptr && end_info))
     {
-      fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
-      if (fp) fclose (fp);
-      return 0;
+      fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
+      png_ptr = 0;
     }
-
-  end_info = fn_png_create_info_struct (png_ptr);
-  if (!end_info)
+  if (! png_ptr)
     {
-      fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
       if (fp) fclose (fp);
       return 0;
     }
 
   /* Set error jump-back.  We come back here when the PNG library
      detects an error.  */
-  if (setjmp (PNG_JMPBUF (png_ptr)))
+  if (_setjmp (PNG_JMPBUF (png_ptr)))
     {
     error:
-      if (png_ptr)
-        fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
-      xfree (pixels);
-      xfree (rows);
-      if (fp) fclose (fp);
+      if (c->png_ptr)
+       fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
+      xfree (c->pixels);
+      xfree (c->rows);
+      if (c->fp)
+       fclose (c->fp);
       return 0;
     }
 
+  /* Silence a bogus diagnostic; see GCC bug 54561.  */
+  IF_LINT (fp = c->fp);
+
   /* Read image info.  */
   if (!NILP (specified_data))
     fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);
@@ -5837,7 +5777,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);
@@ -5846,8 +5786,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);
+  c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height);
+  c->rows = rows = xmalloc (height * sizeof *rows);
   for (i = 0; i < height; ++i)
     rows[i] = pixels + i * row_bytes;
 
@@ -5857,7 +5797,7 @@ png_load (struct frame *f, struct image *img)
   if (fp)
     {
       fclose (fp);
-      fp = NULL;
+      c->fp = NULL;
     }
 
   /* Create an image and pixmap serving as mask if the PNG image
@@ -5932,7 +5872,7 @@ png_load (struct frame *f, struct image *img)
 #endif /* COLOR_TABLE_SUPPORT */
 
   /* Clean up.  */
-  fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
+  fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
   xfree (rows);
   xfree (pixels);
 
@@ -5961,10 +5901,17 @@ png_load (struct frame *f, struct image *img)
   return 1;
 }
 
+static bool
+png_load (struct frame *f, struct image *img)
+{
+  struct png_load_context c;
+  return png_load_body (f, img, &c);
+}
+
 #else /* HAVE_PNG */
 
 #ifdef HAVE_NS
-static int
+static bool
 png_load (struct frame *f, struct image *img)
 {
   return ns_load_image (f, img,
@@ -5984,8 +5931,8 @@ png_load (struct frame *f, struct image *img)
 
 #if defined (HAVE_JPEG) || defined (HAVE_NS)
 
-static int jpeg_image_p (Lisp_Object object);
-static int jpeg_load (struct frame *f, struct image *img);
+static bool jpeg_image_p (Lisp_Object object);
+static bool jpeg_load (struct frame *f, struct image *img);
 
 /* The symbol `jpeg' identifying images of this type.  */
 
@@ -6025,6 +5972,12 @@ static const struct image_keyword jpeg_format[JPEG_LAST] =
   {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
+#if defined HAVE_NTGUI && defined WINDOWSNT
+static bool init_jpeg_functions (void);
+#else
+#define init_jpeg_functions NULL
+#endif
+
 /* Structure describing the image type `jpeg'.  */
 
 static struct image_type jpeg_type =
@@ -6033,12 +5986,13 @@ static struct image_type jpeg_type =
   jpeg_image_p,
   jpeg_load,
   x_clear_image,
+  init_jpeg_functions,
   NULL
 };
 
-/* Return non-zero if OBJECT is a valid JPEG image specification.  */
+/* Return true if OBJECT is a valid JPEG image specification.  */
 
-static int
+static bool
 jpeg_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[JPEG_LAST];
@@ -6068,14 +6022,27 @@ jpeg_image_p (Lisp_Object object)
 #define __WIN32__ 1
 #endif
 
+/* rpcndr.h (via windows.h) and jpeglib.h both define boolean types.
+   Some versions of jpeglib try to detect whether rpcndr.h is loaded,
+   using the Windows boolean type instead of the jpeglib boolean type
+   if so.  Cygwin jpeglib, however, doesn't try to detect whether its
+   headers are included along with windows.h, so under Cygwin, jpeglib
+   attempts to define a conflicting boolean type.  Worse, forcing
+   Cygwin jpeglib headers to use the Windows boolean type doesn't work
+   because it created an ABI incompatibility between the
+   already-compiled jpeg library and the header interface definition.
+
+   The best we can do is to define jpeglib's boolean type to a
+   different name.  This name, jpeg_boolean, remains in effect through
+   the rest of image.c.
+*/
+#if defined CYGWIN && defined HAVE_NTGUI
+#define boolean jpeg_boolean
+#endif
 #include <jpeglib.h>
 #include <jerror.h>
 
-#ifdef HAVE_STLIB_H_1
-#define HAVE_STDLIB_H 1
-#endif
-
-#ifdef HAVE_NTGUI
+#ifdef WINDOWSNT
 
 /* JPEG library details.  */
 DEF_IMGLIB_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t));
@@ -6087,12 +6054,12 @@ DEF_IMGLIB_FN (JDIMENSION, jpeg_read_scanlines, (j_decompress_ptr, JSAMPARRAY, J
 DEF_IMGLIB_FN (struct jpeg_error_mgr *, jpeg_std_error, (struct jpeg_error_mgr *));
 DEF_IMGLIB_FN (boolean, jpeg_resync_to_restart, (j_decompress_ptr, int));
 
-static int
-init_jpeg_functions (Lisp_Object libraries)
+static bool
+init_jpeg_functions (void)
 {
   HMODULE library;
 
-  if (!(library = w32_delayed_load (libraries, Qjpeg)))
+  if (!(library = w32_delayed_load (Qjpeg)))
     return 0;
 
   LOAD_IMGLIB_FN (library, jpeg_finish_decompress);
@@ -6125,21 +6092,34 @@ jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired)
 #define fn_jpeg_std_error              jpeg_std_error
 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
 
-#endif /* HAVE_NTGUI */
+#endif /* WINDOWSNT */
 
 struct my_jpeg_error_mgr
 {
   struct jpeg_error_mgr pub;
-  jmp_buf setjmp_buffer;
+  sys_jmp_buf setjmp_buffer;
+
+  /* The remaining members are so that longjmp doesn't munge local
+     variables.  */
+  struct jpeg_decompress_struct cinfo;
+  enum
+    {
+      MY_JPEG_ERROR_EXIT,
+      MY_JPEG_INVALID_IMAGE_SIZE,
+      MY_JPEG_CANNOT_CREATE_X
+    } failure_code;
+#ifdef lint
+  FILE *fp;
+#endif
 };
 
 
-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;
-  longjmp (mgr->setjmp_buffer, 1);
+  mgr->failure_code = MY_JPEG_ERROR_EXIT;
+  sys_longjmp (mgr->setjmp_buffer, 1);
 }
 
 
@@ -6207,7 +6187,7 @@ our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
    reading the image.  */
 
 static void
-jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len)
+jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len)
 {
   struct jpeg_source_mgr *src;
 
@@ -6344,18 +6324,16 @@ jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
 /* Load image IMG for use on frame F.  Patterned after example.c
    from the JPEG lib.  */
 
-static int
-jpeg_load (struct frame *f, struct image *img)
+static bool
+jpeg_load_body (struct frame *f, struct image *img,
+               struct my_jpeg_error_mgr *mgr)
 {
-  struct jpeg_decompress_struct cinfo;
-  struct my_jpeg_error_mgr mgr;
   Lisp_Object file, specified_file;
   Lisp_Object specified_data;
-  FILE * volatile fp = NULL;
+  FILE *fp = NULL;
   JSAMPARRAY buffer;
   int row_stride, x, y;
   XImagePtr ximg = NULL;
-  int rc;
   unsigned long *colors;
   int width, height;
 
@@ -6385,26 +6363,37 @@ jpeg_load (struct frame *f, struct image *img)
       return 0;
     }
 
+  IF_LINT (mgr->fp = fp);
+
   /* Customize libjpeg's error handling to call my_error_exit when an
      error is detected.  This function will perform a longjmp.  */
-  cinfo.err = fn_jpeg_std_error (&mgr.pub);
-  mgr.pub.error_exit = my_error_exit;
-
-  if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
+  mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub);
+  mgr->pub.error_exit = my_error_exit;
+  if (sys_setjmp (mgr->setjmp_buffer))
     {
-      if (rc == 1)
+      switch (mgr->failure_code)
        {
-         /* Called from my_error_exit.  Display a JPEG error.  */
-         char buf[JMSG_LENGTH_MAX];
-         cinfo.err->format_message ((j_common_ptr) &cinfo, buf);
-         image_error ("Error reading JPEG image `%s': %s", img->spec,
-                      build_string (buf));
+       case MY_JPEG_ERROR_EXIT:
+         {
+           char buf[JMSG_LENGTH_MAX];
+           mgr->cinfo.err->format_message ((j_common_ptr) &mgr->cinfo, buf);
+           image_error ("Error reading JPEG image `%s': %s", img->spec,
+                        build_string (buf));
+           break;
+         }
+
+       case MY_JPEG_INVALID_IMAGE_SIZE:
+         image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
+         break;
+
+       case MY_JPEG_CANNOT_CREATE_X:
+         break;
        }
 
       /* Close the input file and destroy the JPEG object.  */
       if (fp)
-       fclose ((FILE *) fp);
-      fn_jpeg_destroy_decompress (&cinfo);
+       fclose (fp);
+      fn_jpeg_destroy_decompress (&mgr->cinfo);
 
       /* If we already have an XImage, free that.  */
       x_destroy_x_image (ximg);
@@ -6414,46 +6403,52 @@ jpeg_load (struct frame *f, struct image *img)
       return 0;
     }
 
+  /* Silence a bogus diagnostic; see GCC bug 54561.  */
+  IF_LINT (fp = mgr->fp);
+
   /* Create the JPEG decompression object.  Let it read from fp.
         Read the JPEG image header.  */
-  fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo));
+  fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
 
   if (NILP (specified_data))
-    jpeg_file_src (&cinfo, (FILE *) fp);
+    jpeg_file_src (&mgr->cinfo, fp);
   else
-    jpeg_memory_src (&cinfo, SDATA (specified_data),
+    jpeg_memory_src (&mgr->cinfo, SDATA (specified_data),
                     SBYTES (specified_data));
 
-  fn_jpeg_read_header (&cinfo, 1);
+  fn_jpeg_read_header (&mgr->cinfo, 1);
 
   /* Customize decompression so that color quantization will be used.
         Start decompression.  */
-  cinfo.quantize_colors = 1;
-  fn_jpeg_start_decompress (&cinfo);
-  width = img->width = cinfo.output_width;
-  height = img->height = cinfo.output_height;
+  mgr->cinfo.quantize_colors = 1;
+  fn_jpeg_start_decompress (&mgr->cinfo);
+  width = img->width = mgr->cinfo.output_width;
+  height = img->height = mgr->cinfo.output_height;
 
   if (!check_image_size (f, width, height))
     {
-      image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
-      longjmp (mgr.setjmp_buffer, 2);
+      mgr->failure_code = MY_JPEG_INVALID_IMAGE_SIZE;
+      sys_longjmp (mgr->setjmp_buffer, 1);
     }
 
   /* Create X image and pixmap.  */
   if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
-    longjmp (mgr.setjmp_buffer, 2);
+    {
+      mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
+      sys_longjmp (mgr->setjmp_buffer, 1);
+    }
 
   /* Allocate colors.  When color quantization is used,
-     cinfo.actual_number_of_colors has been set with the number of
-     colors generated, and cinfo.colormap is a two-dimensional array
-     of color indices in the range 0..cinfo.actual_number_of_colors.
+     mgr->cinfo.actual_number_of_colors has been set with the number of
+     colors generated, and mgr->cinfo.colormap is a two-dimensional array
+     of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
      No more than 255 colors will be generated.  */
   {
     int i, ir, ig, ib;
 
-    if (cinfo.out_color_components > 2)
+    if (mgr->cinfo.out_color_components > 2)
       ir = 0, ig = 1, ib = 2;
-    else if (cinfo.out_color_components > 1)
+    else if (mgr->cinfo.out_color_components > 1)
       ir = 0, ig = 1, ib = 0;
     else
       ir = 0, ig = 0, ib = 0;
@@ -6463,16 +6458,15 @@ 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 (mgr->cinfo.actual_number_of_colors * sizeof *colors);
 
-    for (i = 0; i < cinfo.actual_number_of_colors; ++i)
+    for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i)
       {
        /* Multiply RGB values with 255 because X expects RGB values
           in the range 0..0xffff.  */
-       int r = cinfo.colormap[ir][i] << 8;
-       int g = cinfo.colormap[ig][i] << 8;
-       int b = cinfo.colormap[ib][i] << 8;
+       int r = mgr->cinfo.colormap[ir][i] << 8;
+       int g = mgr->cinfo.colormap[ig][i] << 8;
+       int b = mgr->cinfo.colormap[ib][i] << 8;
        colors[i] = lookup_rgb_color (f, r, g, b);
       }
 
@@ -6484,21 +6478,21 @@ jpeg_load (struct frame *f, struct image *img)
   }
 
   /* Read pixels.  */
-  row_stride = width * cinfo.output_components;
-  buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE,
-                                   row_stride, 1);
+  row_stride = width * mgr->cinfo.output_components;
+  buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo,
+                                        JPOOL_IMAGE, row_stride, 1);
   for (y = 0; y < height; ++y)
     {
-      fn_jpeg_read_scanlines (&cinfo, buffer, 1);
-      for (x = 0; x < cinfo.output_width; ++x)
+      fn_jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
+      for (x = 0; x < mgr->cinfo.output_width; ++x)
        XPutPixel (ximg, x, y, colors[buffer[0][x]]);
     }
 
   /* Clean up.  */
-  fn_jpeg_finish_decompress (&cinfo);
-  fn_jpeg_destroy_decompress (&cinfo);
+  fn_jpeg_finish_decompress (&mgr->cinfo);
+  fn_jpeg_destroy_decompress (&mgr->cinfo);
   if (fp)
-    fclose ((FILE *) fp);
+    fclose (fp);
 
   /* Maybe fill in the background field while we have ximg handy. */
   if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
@@ -6511,10 +6505,17 @@ jpeg_load (struct frame *f, struct image *img)
   return 1;
 }
 
+static bool
+jpeg_load (struct frame *f, struct image *img)
+{
+  struct my_jpeg_error_mgr mgr;
+  return jpeg_load_body (f, img, &mgr);
+}
+
 #else /* HAVE_JPEG */
 
 #ifdef HAVE_NS
-static int
+static bool
 jpeg_load (struct frame *f, struct image *img)
 {
   return ns_load_image (f, img,
@@ -6533,8 +6534,8 @@ jpeg_load (struct frame *f, struct image *img)
 
 #if defined (HAVE_TIFF) || defined (HAVE_NS)
 
-static int tiff_image_p (Lisp_Object object);
-static int tiff_load (struct frame *f, struct image *img);
+static bool tiff_image_p (Lisp_Object object);
+static bool tiff_load (struct frame *f, struct image *img);
 
 /* The symbol `tiff' identifying images of this type.  */
 
@@ -6576,6 +6577,12 @@ static const struct image_keyword tiff_format[TIFF_LAST] =
   {":index",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0}
 };
 
+#if defined HAVE_NTGUI && defined WINDOWSNT
+static bool init_tiff_functions (void);
+#else
+#define init_tiff_functions NULL
+#endif
+
 /* Structure describing the image type `tiff'.  */
 
 static struct image_type tiff_type =
@@ -6584,12 +6591,13 @@ static struct image_type tiff_type =
   tiff_image_p,
   tiff_load,
   x_clear_image,
+  init_tiff_functions,
   NULL
 };
 
-/* Return non-zero if OBJECT is a valid TIFF image specification.  */
+/* Return true if OBJECT is a valid TIFF image specification.  */
 
-static int
+static bool
 tiff_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[TIFF_LAST];
@@ -6608,7 +6616,7 @@ tiff_image_p (Lisp_Object object)
 
 #include <tiffio.h>
 
-#ifdef HAVE_NTGUI
+#ifdef WINDOWSNT
 
 /* TIFF library details.  */
 DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler));
@@ -6623,12 +6631,12 @@ DEF_IMGLIB_FN (int, TIFFReadRGBAImage, (TIFF *, uint32, uint32, uint32 *, int));
 DEF_IMGLIB_FN (void, TIFFClose, (TIFF *));
 DEF_IMGLIB_FN (int, TIFFSetDirectory, (TIFF *, tdir_t));
 
-static int
-init_tiff_functions (Lisp_Object libraries)
+static bool
+init_tiff_functions (void)
 {
   HMODULE library;
 
-  if (!(library = w32_delayed_load (libraries, Qtiff)))
+  if (!(library = w32_delayed_load (Qtiff)))
     return 0;
 
   LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
@@ -6652,7 +6660,7 @@ init_tiff_functions (Lisp_Object libraries)
 #define fn_TIFFReadRGBAImage           TIFFReadRGBAImage
 #define fn_TIFFClose                   TIFFClose
 #define fn_TIFFSetDirectory            TIFFSetDirectory
-#endif /* HAVE_NTGUI */
+#endif /* WINDOWSNT */
 
 
 /* Reading from a memory buffer for TIFF images Based on the PNG
@@ -6793,10 +6801,10 @@ tiff_warning_handler (const char *title, const char *format, va_list ap)
 }
 
 
-/* Load TIFF image IMG for use on frame F.  Value is non-zero if
+/* Load TIFF image IMG for use on frame F.  Value is true if
    successful.  */
 
-static int
+static bool
 tiff_load (struct frame *f, struct image *img)
 {
   Lisp_Object file, specified_file;
@@ -6897,7 +6905,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);
 
@@ -6961,7 +6969,7 @@ tiff_load (struct frame *f, struct image *img)
 #else /* HAVE_TIFF */
 
 #ifdef HAVE_NS
-static int
+static bool
 tiff_load (struct frame *f, struct image *img)
 {
   return ns_load_image (f, img,
@@ -6980,8 +6988,8 @@ tiff_load (struct frame *f, struct image *img)
 
 #if defined (HAVE_GIF) || defined (HAVE_NS)
 
-static int gif_image_p (Lisp_Object object);
-static int gif_load (struct frame *f, struct image *img);
+static bool gif_image_p (Lisp_Object object);
+static bool gif_load (struct frame *f, struct image *img);
 static void gif_clear_image (struct frame *f, struct image *img);
 
 /* The symbol `gif' identifying images of this type.  */
@@ -7024,6 +7032,12 @@ static const struct image_keyword gif_format[GIF_LAST] =
   {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
+#if defined HAVE_NTGUI && defined WINDOWSNT
+static bool init_gif_functions (void);
+#else
+#define init_gif_functions NULL
+#endif
+
 /* Structure describing the image type `gif'.  */
 
 static struct image_type gif_type =
@@ -7032,6 +7046,7 @@ static struct image_type gif_type =
   gif_image_p,
   gif_load,
   gif_clear_image,
+  init_gif_functions,
   NULL
 };
 
@@ -7044,9 +7059,9 @@ gif_clear_image (struct frame *f, struct image *img)
   x_clear_image (f, img);
 }
 
-/* Return non-zero if OBJECT is a valid GIF image specification.  */
+/* Return true if OBJECT is a valid GIF image specification.  */
 
-static int
+static bool
 gif_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[GIF_LAST];
@@ -7081,7 +7096,7 @@ gif_image_p (Lisp_Object object)
 #endif /* HAVE_NTGUI */
 
 
-#ifdef HAVE_NTGUI
+#ifdef WINDOWSNT
 
 /* GIF library details.  */
 DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *));
@@ -7089,12 +7104,12 @@ DEF_IMGLIB_FN (int, DGifSlurp, (GifFileType *));
 DEF_IMGLIB_FN (GifFileType *, DGifOpen, (void *, InputFunc));
 DEF_IMGLIB_FN (GifFileType *, DGifOpenFileName, (const char *));
 
-static int
-init_gif_functions (Lisp_Object libraries)
+static bool
+init_gif_functions (void)
 {
   HMODULE library;
 
-  if (!(library = w32_delayed_load (libraries, Qgif)))
+  if (!(library = w32_delayed_load (Qgif)))
     return 0;
 
   LOAD_IMGLIB_FN (library, DGifCloseFile);
@@ -7111,7 +7126,7 @@ init_gif_functions (Lisp_Object libraries)
 #define fn_DGifOpen            DGifOpen
 #define fn_DGifOpenFileName    DGifOpenFileName
 
-#endif /* HAVE_NTGUI */
+#endif /* WINDOWSNT */
 
 /* Reading a GIF image from memory
    Based on the PNG memory stuff to a certain extent. */
@@ -7143,7 +7158,7 @@ gif_read_from_memory (GifFileType *file, GifByteType *buf, int len)
 }
 
 
-/* Load GIF image IMG for use on frame F.  Value is non-zero if
+/* Load GIF image IMG for use on frame F.  Value is true if
    successful.  */
 
 static const int interlace_start[] = {0, 4, 2, 1};
@@ -7151,7 +7166,7 @@ static const int interlace_increment[] = {8, 8, 4, 2};
 
 #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
 
-static int
+static bool
 gif_load (struct frame *f, struct image *img)
 {
   Lisp_Object file;
@@ -7449,7 +7464,7 @@ gif_load (struct frame *f, struct image *img)
 #else  /* !HAVE_GIF */
 
 #ifdef HAVE_NS
-static int
+static bool
 gif_load (struct frame *f, struct image *img)
 {
   return ns_load_image (f, img,
@@ -7468,8 +7483,8 @@ gif_load (struct frame *f, struct image *img)
 
 static Lisp_Object Qimagemagick;
 
-static int imagemagick_image_p (Lisp_Object);
-static int imagemagick_load (struct frame *, struct image *);
+static bool imagemagick_image_p (Lisp_Object);
+static bool imagemagick_load (struct frame *, struct image *);
 static void imagemagick_clear_image (struct frame *, struct image *);
 
 /* Indices of image specification fields in imagemagick_format.  */
@@ -7514,6 +7529,12 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
     {":crop",          IMAGE_DONT_CHECK_VALUE_TYPE,            0}
   };
 
+#if defined HAVE_NTGUI && defined WINDOWSNT
+static bool init_imagemagick_functions (void);
+#else
+#define init_imagemagick_functions NULL
+#endif
+
 /* Structure describing the image type for any image handled via
    ImageMagick.  */
 
@@ -7523,6 +7544,7 @@ static struct image_type imagemagick_type =
     imagemagick_image_p,
     imagemagick_load,
     imagemagick_clear_image,
+    init_imagemagick_functions,
     NULL
   };
 
@@ -7535,11 +7557,11 @@ imagemagick_clear_image (struct frame *f,
   x_clear_image (f, img);
 }
 
-/* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification.  Do
+/* Return true if OBJECT is a valid IMAGEMAGICK image specification.  Do
    this by calling parse_image_spec and supplying the keywords that
    identify the IMAGEMAGICK format.   */
 
-static int
+static bool
 imagemagick_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[IMAGEMAGICK_LAST];
@@ -7576,7 +7598,7 @@ imagemagick_error (MagickWand *wand)
 
   description = MagickGetException (wand, &severity);
   image_error ("ImageMagick error: %s",
-              make_string (description, strlen (description)),
+              build_string (description),
               Qnil);
   description = (char *) MagickRelinquishMemory (description);
 }
@@ -7591,26 +7613,21 @@ imagemagick_error (MagickWand *wand)
    be parsed; SIZE is the number of bytes of data; and FILENAME is
    either the file name or the image data.
 
-   Return non-zero if successful.  */
+   Return true if successful.  */
 
-static int
+static bool
 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;
@@ -7619,10 +7636,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
   int desired_width, desired_height;
   double rotation;
   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
@@ -7636,14 +7649,9 @@ imagemagick_load_image (struct frame *f, struct image *img,
   ping_wand = NewMagickWand ();
   /* MagickSetResolution (ping_wand, 2, 2);   (Bug#10112)  */
 
-  if (filename != NULL)
-    {
-      status = MagickPingImage (ping_wand, filename);
-    }
-  else
-    {
-      status = MagickPingImageBlob (ping_wand, contents, size);
-    }
+  status = filename
+    ? MagickPingImage (ping_wand, filename)
+    : MagickPingImageBlob (ping_wand, contents, size);
 
   if (status == MagickFalse)
     {
@@ -7652,7 +7660,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
       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);
@@ -7669,39 +7677,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.  */
+     bundle, the number is one.  Load the image data.  */
 
-  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 ();
-
-      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)
-       {
-         imagemagick_error (image_wand);
-         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);
@@ -7767,13 +7782,8 @@ 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);
@@ -7787,6 +7797,22 @@ imagemagick_load_image (struct frame *f, struct image *img,
   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)))
     {
@@ -7799,7 +7825,50 @@ imagemagick_load_image (struct frame *f, struct image *img,
 
   init_color_table ();
 
-  if (imagemagick_render_type == 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;
 
@@ -7849,59 +7918,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
         }
       DestroyPixelIterator (iterator);
     }
-  else                          /* 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*/
-#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
-      MagickExportImagePixels (image_wand,
-                              0, 0,
-                              width, height,
-                              exportdepth,
-                              pixelwidth,
-                              /*&(img->pixmap));*/
-                              ximg->data);
-#else
-      image_error ("You don't have MagickExportImagePixels, upgrade ImageMagick!",
-                  Qnil, Qnil);
-#endif
-    }
-
 
 #ifdef COLOR_TABLE_SUPPORT
   /* Remember colors allocated for this image.  */
@@ -7909,7 +7925,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
   free_color_table ();
 #endif /* COLOR_TABLE_SUPPORT */
 
-
   img->width  = width;
   img->height = height;
 
@@ -7918,9 +7933,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 ();
 
@@ -7928,7 +7944,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);
@@ -7936,14 +7953,14 @@ imagemagick_load_image (struct frame *f, struct image *img,
 }
 
 
-/* Load IMAGEMAGICK image IMG for use on frame F.  Value is non-zero if
+/* Load IMAGEMAGICK image IMG for use on frame F.  Value is true if
    successful. this function will go into the imagemagick_type structure, and
    the prototype thus needs to be compatible with that structure.  */
 
-static int
+static bool
 imagemagick_load (struct frame *f, struct image *img)
 {
-  int success_p = 0;
+  bool success_p = 0;
   Lisp_Object file_name;
 
   /* If IMG->spec specifies a file name, create a non-file spec from it.  */
@@ -7987,15 +8004,21 @@ 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]);
@@ -8016,11 +8039,11 @@ recognize as images, such as C.  See `imagemagick-types-inhibit'.  */)
 
 /* Function prototypes.  */
 
-static int svg_image_p (Lisp_Object object);
-static int svg_load (struct frame *f, struct image *img);
+static bool svg_image_p (Lisp_Object object);
+static bool svg_load (struct frame *f, struct image *img);
 
-static int svg_load_image (struct frame *, struct image *,
-                           unsigned char *, ptrdiff_t);
+static bool svg_load_image (struct frame *, struct image *,
+                           unsigned char *, ptrdiff_t);
 
 /* The symbol `svg' identifying images of this type. */
 
@@ -8060,31 +8083,32 @@ static const struct image_keyword svg_format[SVG_LAST] =
   {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
+#if defined HAVE_NTGUI && defined WINDOWSNT
+static bool init_svg_functions (void);
+#else
+#define init_svg_functions NULL
+#endif
+
 /* Structure describing the image type `svg'.  Its the same type of
    structure defined for all image formats, handled by emacs image
    functions.  See struct image_type in dispextern.h.  */
 
 static struct image_type svg_type =
 {
-  /* An identifier showing that this is an image structure for the SVG format.  */
   &Qsvg,
-  /* Handle to a function that can be used to identify a SVG file.  */
   svg_image_p,
-  /* Handle to function used to load a SVG file.  */
   svg_load,
-  /* Handle to function to free sresources for SVG.  */
   x_clear_image,
-  /* An internal field to link to the next image type in a list of
-     image types, will be filled in when registering the format.  */
+  init_svg_functions,
   NULL
 };
 
 
-/* Return non-zero if OBJECT is a valid SVG image specification.  Do
+/* Return true if OBJECT is a valid SVG image specification.  Do
    this by calling parse_image_spec and supplying the keywords that
    identify the SVG format.   */
 
-static int
+static bool
 svg_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[SVG_LAST];
@@ -8099,7 +8123,7 @@ svg_image_p (Lisp_Object object)
 
 #include <librsvg/rsvg.h>
 
-#ifdef HAVE_NTGUI
+#ifdef WINDOWSNT
 
 /* SVG library functions.  */
 DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new);
@@ -8123,15 +8147,15 @@ DEF_IMGLIB_FN (void, g_error_free);
 
 Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
 
-static int
-init_svg_functions (Lisp_Object libraries)
+static bool
+init_svg_functions (void)
 {
   HMODULE library, gdklib, glib, gobject;
 
-  if (!(glib = w32_delayed_load (libraries, Qglib))
-      || !(gobject = w32_delayed_load (libraries, Qgobject))
-      || !(gdklib = w32_delayed_load (libraries, Qgdk_pixbuf))
-      || !(library = w32_delayed_load (libraries, Qsvg)))
+  if (!(glib = w32_delayed_load (Qglib))
+      || !(gobject = w32_delayed_load (Qgobject))
+      || !(gdklib = w32_delayed_load (Qgdk_pixbuf))
+      || !(library = w32_delayed_load (Qsvg)))
     return 0;
 
   LOAD_IMGLIB_FN (library, rsvg_handle_new);
@@ -8177,16 +8201,15 @@ init_svg_functions (Lisp_Object libraries)
 #define fn_g_type_init                    g_type_init
 #define fn_g_object_unref                 g_object_unref
 #define fn_g_error_free                   g_error_free
-#endif /* !HAVE_NTGUI  */
+#endif /* !WINDOWSNT  */
 
-/* Load SVG image IMG for use on frame F.  Value is non-zero if
-   successful. this function will go into the svg_type structure, and
-   the prototype thus needs to be compatible with that structure.  */
+/* Load SVG image IMG for use on frame F.  Value is true if
+   successful.  */
 
-static int
+static bool
 svg_load (struct frame *f, struct image *img)
 {
-  int success_p = 0;
+  bool success_p = 0;
   Lisp_Object file_name;
 
   /* If IMG->spec specifies a file name, create a non-file spec from it.  */
@@ -8239,8 +8262,8 @@ svg_load (struct frame *f, struct image *img)
 
    Uses librsvg to do most of the image processing.
 
-   Returns non-zero when successful.  */
-static int
+   Returns true when successful.  */
+static bool
 svg_load_image (struct frame *f,         /* Pointer to emacs frame structure.  */
                struct image *img,       /* Pointer to emacs image structure.  */
                unsigned char *contents, /* String containing the SVG XML data to be parsed.  */
@@ -8407,8 +8430,8 @@ svg_load_image (struct frame *f,         /* Pointer to emacs frame structure.  *
 
 #ifdef HAVE_GHOSTSCRIPT
 
-static int gs_image_p (Lisp_Object object);
-static int gs_load (struct frame *f, struct image *img);
+static bool gs_image_p (Lisp_Object object);
+static bool gs_load (struct frame *f, struct image *img);
 static void gs_clear_image (struct frame *f, struct image *img);
 
 /* Keyword symbols.  */
@@ -8463,6 +8486,7 @@ static struct image_type gs_type =
   gs_image_p,
   gs_load,
   gs_clear_image,
+  NULL,
   NULL
 };
 
@@ -8476,10 +8500,10 @@ gs_clear_image (struct frame *f, struct image *img)
 }
 
 
-/* Return non-zero if OBJECT is a valid Ghostscript image
+/* Return true if OBJECT is a valid Ghostscript image
    specification.  */
 
-static int
+static bool
 gs_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[GS_LAST];
@@ -8506,7 +8530,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
@@ -8516,10 +8540,10 @@ gs_image_p (Lisp_Object object)
 }
 
 
-/* Load Ghostscript image IMG for use on frame F.  Value is non-zero
+/* Load Ghostscript image IMG for use on frame F.  Value is true
    if successful.  */
 
-static int
+static bool
 gs_load (struct frame *f, struct image *img)
 {
   uprintmax_t printnum1, printnum2;
@@ -8550,16 +8574,16 @@ 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))
     {
       /* Only W32 version did BLOCK_INPUT here.  ++kfs */
-      BLOCK_INPUT;
+      block_input ();
       img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                                   img->width, img->height,
                                   DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 
   if (!img->pixmap)
@@ -8574,13 +8598,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);
@@ -8621,7 +8645,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;
 
@@ -8635,7 +8659,7 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
     {
       XImagePtr ximg;
 
-      BLOCK_INPUT;
+      block_input ();
 
       /* Try to get an XImage for img->pixmep.  */
       ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
@@ -8678,15 +8702,15 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
        image_error ("Cannot get X image of `%s'; colors will not be freed",
                     img->spec, Qnil);
 
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 #endif /* HAVE_X_WINDOWS */
 
   /* Now that we have the pixmap, compute mask and transform the
      image if requested.  */
-  BLOCK_INPUT;
+  block_input ();
   postprocess_image (f, img);
-  UNBLOCK_INPUT;
+  unblock_input ();
 }
 
 #endif /* HAVE_GHOSTSCRIPT */
@@ -8696,7 +8720,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.  */)
@@ -8718,95 +8742,99 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
   return make_number (id);
 }
 
-#endif /* GLYPH_DEBUG != 0 */
+#endif /* GLYPH_DEBUG */
 
 
 /***********************************************************************
                            Initialization
  ***********************************************************************/
 
-#ifdef HAVE_NTGUI
-/* Image types that rely on external libraries are loaded dynamically
-   if the library is available.  */
-#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
-  define_image_type (image_type, init_lib_fn (libraries))
-#else
-#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
-  define_image_type (image_type, 1)
-#endif /* HAVE_NTGUI */
-
-DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
+DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 1, 1, 0,
        doc: /* Initialize image library implementing image type TYPE.
 Return non-nil if TYPE is a supported image type.
 
-Image types pbm and xbm are prebuilt; other types are loaded here.
-Libraries to load are specified in alist LIBRARIES (usually, the value
-of `dynamic-library-alist', which see).  */)
-  (Lisp_Object type, Lisp_Object libraries)
+If image libraries are loaded dynamically (currently only the case on
+MS-Windows), load the library for TYPE if it is not yet loaded, using
+the library file(s) specified by `dynamic-library-alist'.  */)
+  (Lisp_Object type)
 {
-#ifdef HAVE_NTGUI
-  /* Don't try to reload the library.  */
-  Lisp_Object tested = Fassq (type, Vlibrary_cache);
-  if (CONSP (tested))
-    return XCDR (tested);
-#endif
+  return lookup_image_type (type) ? Qt : Qnil;
+}
 
+/* Look up image type TYPE, and return a pointer to its image_type
+   structure.  Return 0 if TYPE is not a known image type.  */
+
+static struct image_type *
+lookup_image_type (Lisp_Object type)
+{
   /* Types pbm and xbm are built-in and always available.  */
-  if (EQ (type, Qpbm) || EQ (type, Qxbm))
-    return Qt;
+  if (EQ (type, Qpbm))
+    return define_image_type (&pbm_type);
+
+  if (EQ (type, Qxbm))
+    return define_image_type (&xbm_type);
 
 #if defined (HAVE_XPM) || defined (HAVE_NS)
   if (EQ (type, Qxpm))
-    return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries);
+    return define_image_type (&xpm_type);
 #endif
 
 #if defined (HAVE_JPEG) || defined (HAVE_NS)
   if (EQ (type, Qjpeg))
-    return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries);
+    return define_image_type (&jpeg_type);
 #endif
 
 #if defined (HAVE_TIFF) || defined (HAVE_NS)
   if (EQ (type, Qtiff))
-    return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries);
+    return define_image_type (&tiff_type);
 #endif
 
 #if defined (HAVE_GIF) || defined (HAVE_NS)
   if (EQ (type, Qgif))
-    return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries);
+    return define_image_type (&gif_type);
 #endif
 
 #if defined (HAVE_PNG) || defined (HAVE_NS)
   if (EQ (type, Qpng))
-    return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries);
+    return define_image_type (&png_type);
 #endif
 
 #if defined (HAVE_RSVG)
   if (EQ (type, Qsvg))
-    return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries);
+    return define_image_type (&svg_type);
 #endif
 
 #if defined (HAVE_IMAGEMAGICK)
   if (EQ (type, Qimagemagick))
-    return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
-                                libraries);
+    return define_image_type (&imagemagick_type);
 #endif
 
 #ifdef HAVE_GHOSTSCRIPT
   if (EQ (type, Qpostscript))
-    return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
+    return define_image_type (&gs_type);
 #endif
 
-  /* If the type is not recognized, avoid testing it ever again.  */
-  CACHE_IMAGE_TYPE (type, Qnil);
-  return Qnil;
+  return NULL;
+}
+
+/* Reset image_types before dumping.
+   Called from Fdump_emacs.  */
+
+void
+reset_image_types (void)
+{
+  while (image_types)
+    {
+      struct image_type *next = image_types->next;
+      xfree (image_types);
+      image_types = next;
+    }
 }
 
 void
 syms_of_image (void)
 {
-  /* Initialize this only once, since that's what we do with Vimage_types
-     and they are supposed to be in sync.  Initializing here gives correct
-     operation on GNU/Linux of calling dump-emacs after loading some images.  */
+  /* Initialize this only once; it will be reset before dumping.  */
   image_types = NULL;
 
   /* Must be defined now because we're going to update it below, while
@@ -8829,15 +8857,6 @@ as a ratio to the frame height and width.  If the value is
 non-numeric, there is no explicit limit on the size of images.  */);
   Vmax_image_size = make_float (MAX_IMAGE_SIZE);
 
-  DEFSYM (Qpbm, "pbm");
-  ADD_IMAGE_TYPE (Qpbm);
-
-  DEFSYM (Qxbm, "xbm");
-  ADD_IMAGE_TYPE (Qxbm);
-
-  define_image_type (&xbm_type, 1);
-  define_image_type (&pbm_type, 1);
-
   DEFSYM (Qcount, "count");
   DEFSYM (Qextension_data, "extension-data");
   DEFSYM (Qdelay, "delay");
@@ -8881,6 +8900,12 @@ non-numeric, there is no explicit limit on the size of images.  */);
        );
 #endif
 
+  DEFSYM (Qpbm, "pbm");
+  ADD_IMAGE_TYPE (Qpbm);
+
+  DEFSYM (Qxbm, "xbm");
+  ADD_IMAGE_TYPE (Qxbm);
+
 #if defined (HAVE_XPM) || defined (HAVE_NS)
   DEFSYM (Qxpm, "xpm");
   ADD_IMAGE_TYPE (Qxpm);
@@ -8932,7 +8957,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
@@ -8971,8 +8996,3 @@ The options are:
 #endif
 
 }
-
-void
-init_image (void)
-{
-}