]> code.delx.au - gnu-emacs/blobdiff - src/image.c
Merge from origin/emacs-24
[gnu-emacs] / src / image.c
index 57f9b7735b6f9ed730955bf5e2bb3b595c4c2af4..4cba8863b888fb7a7b870cdf9ddf1c6aeb31ca3c 100644 (file)
@@ -33,6 +33,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "lisp.h"
 #include "frame.h"
 #include "window.h"
+#include "buffer.h"
 #include "dispextern.h"
 #include "blockinput.h"
 #include "systime.h"
@@ -1858,19 +1859,6 @@ mark_image_cache (struct image_cache *c)
                          X / NS / W32 support code
  ***********************************************************************/
 
-#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
-
-/* Macro for loading those image functions from the library.  */
-#define LOAD_IMGLIB_FN(lib,func) {                                     \
-    fn_##func = (void *) GetProcAddress (lib, #func);                  \
-    if (!fn_##func) return 0;                                          \
-  }
-
-#endif /* WINDOWSNT */
-
 /* Return true if XIMG's size WIDTH x HEIGHT doesn't break the
    windowing system.
    WIDTH and HEIGHT must both be positive.
@@ -3376,12 +3364,14 @@ xpm_free_colors (Display *dpy, Colormap cmap, Pixel *pixels, int npixels, void *
 
 /* XPM library details.  */
 
-DEF_IMGLIB_FN (void, XpmFreeAttributes, (XpmAttributes *));
-DEF_IMGLIB_FN (int, XpmCreateImageFromBuffer, (Display *, char *, xpm_XImage **,
-                                         xpm_XImage **, XpmAttributes *));
-DEF_IMGLIB_FN (int, XpmReadFileToImage, (Display *, char *, xpm_XImage **,
-                                   xpm_XImage **, XpmAttributes *));
-DEF_IMGLIB_FN (void, XImageFree, (xpm_XImage *));
+DEF_DLL_FN (void, XpmFreeAttributes, (XpmAttributes *));
+DEF_DLL_FN (int, XpmCreateImageFromBuffer,
+           (Display *, char *, xpm_XImage **,
+            xpm_XImage **, XpmAttributes *));
+DEF_DLL_FN (int, XpmReadFileToImage,
+           (Display *, char *, xpm_XImage **,
+            xpm_XImage **, XpmAttributes *));
+DEF_DLL_FN (void, XImageFree, (xpm_XImage *));
 
 static bool
 init_xpm_functions (void)
@@ -3391,22 +3381,24 @@ init_xpm_functions (void)
   if (!(library = w32_delayed_load (Qxpm)))
     return 0;
 
-  LOAD_IMGLIB_FN (library, XpmFreeAttributes);
-  LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
-  LOAD_IMGLIB_FN (library, XpmReadFileToImage);
-  LOAD_IMGLIB_FN (library, XImageFree);
+  LOAD_DLL_FN (library, XpmFreeAttributes);
+  LOAD_DLL_FN (library, XpmCreateImageFromBuffer);
+  LOAD_DLL_FN (library, XpmReadFileToImage);
+  LOAD_DLL_FN (library, XImageFree);
   return 1;
 }
 
-#endif /* WINDOWSNT */
+# undef XImageFree
+# undef XpmCreateImageFromBuffer
+# undef XpmFreeAttributes
+# undef XpmReadFileToImage
+
+# define XImageFree fn_XImageFree
+# define XpmCreateImageFromBuffer fn_XpmCreateImageFromBuffer
+# define XpmFreeAttributes fn_XpmFreeAttributes
+# define XpmReadFileToImage fn_XpmReadFileToImage
 
-#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 */
+#endif /* WINDOWSNT */
 
 /* 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
@@ -3623,9 +3615,9 @@ xpm_load (struct frame *f, struct image *img)
 #endif
       /* XpmReadFileToPixmap is not available in the Windows port of
         libxpm.  But XpmReadFileToImage almost does what we want.  */
-      rc = fn_XpmReadFileToImage (&hdc, SDATA (file),
-                                 &xpm_image, &xpm_mask,
-                                 &attrs);
+      rc = XpmReadFileToImage (&hdc, SDATA (file),
+                              &xpm_image, &xpm_mask,
+                              &attrs);
 #else
       rc = XpmReadFileToImage (FRAME_X_DISPLAY (f), SSDATA (file),
                               &img->ximg, &img->mask_img,
@@ -3647,9 +3639,9 @@ xpm_load (struct frame *f, struct image *img)
 #ifdef HAVE_NTGUI
       /* XpmCreatePixmapFromBuffer is not available in the Windows port
         of libxpm.  But XpmCreateImageFromBuffer almost does what we want.  */
-      rc = fn_XpmCreateImageFromBuffer (&hdc, SDATA (buffer),
-                                       &xpm_image, &xpm_mask,
-                                       &attrs);
+      rc = XpmCreateImageFromBuffer (&hdc, SDATA (buffer),
+                                    &xpm_image, &xpm_mask,
+                                    &attrs);
 #else
       rc = XpmCreateImageFromBuffer (FRAME_X_DISPLAY (f), SSDATA (buffer),
                                     &img->ximg, &img->mask_img,
@@ -3698,7 +3690,7 @@ xpm_load (struct frame *f, struct image *img)
          img->pixmap = xpm_image->bitmap;
          /* XImageFree in libXpm frees XImage struct without destroying
             the bitmap, which is what we want.  */
-         fn_XImageFree (xpm_image);
+         XImageFree (xpm_image);
        }
       if (xpm_mask && xpm_mask->bitmap)
        {
@@ -3712,7 +3704,7 @@ xpm_load (struct frame *f, struct image *img)
          SelectObject (hdc, old_obj);
 
          img->mask = xpm_mask->bitmap;
-         fn_XImageFree (xpm_mask);
+         XImageFree (xpm_mask);
          DeleteDC (hdc);
        }
 
@@ -3736,11 +3728,7 @@ xpm_load (struct frame *f, struct image *img)
       eassert (img->width > 0 && img->height > 0);
 
       /* The call to XpmFreeAttributes below frees attrs.alloc_pixels.  */
-#ifdef HAVE_NTGUI
-      fn_XpmFreeAttributes (&attrs);
-#else
       XpmFreeAttributes (&attrs);
-#endif /* HAVE_NTGUI */
 
 #ifdef HAVE_X_WINDOWS
       /* Maybe fill in the background field while we have ximg handy.  */
@@ -4294,7 +4282,11 @@ struct ct_color
 
 /* Value is a hash of the RGB color given by R, G, and B.  */
 
-#define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
+static unsigned
+ct_hash_rgb (unsigned r, unsigned g, unsigned b)
+{
+  return (r << 16) ^ (g << 8) ^ b;
+}
 
 /* The color hash table.  */
 
@@ -4349,7 +4341,7 @@ free_color_table (void)
 static unsigned long
 lookup_rgb_color (struct frame *f, int r, int g, int b)
 {
-  unsigned hash = CT_HASH_RGB (r, g, b);
+  unsigned hash = ct_hash_rgb (r, g, b);
   int i = hash % CT_SIZE;
   struct ct_color *p;
   Display_Info *dpyinfo;
@@ -5530,39 +5522,42 @@ png_image_p (Lisp_Object object)
 
 #if defined HAVE_PNG && !defined HAVE_NS
 
-#ifdef WINDOWSNT
+# ifdef WINDOWSNT
 /* PNG library details.  */
 
-DEF_IMGLIB_FN (png_voidp, png_get_io_ptr, (png_structp));
-DEF_IMGLIB_FN (int, png_sig_cmp, (png_bytep, png_size_t, png_size_t));
-DEF_IMGLIB_FN (png_structp, png_create_read_struct, (png_const_charp, png_voidp,
-                                                    png_error_ptr, png_error_ptr));
-DEF_IMGLIB_FN (png_infop, png_create_info_struct, (png_structp));
-DEF_IMGLIB_FN (void, png_destroy_read_struct, (png_structpp, png_infopp, png_infopp));
-DEF_IMGLIB_FN (void, png_set_read_fn, (png_structp, png_voidp, png_rw_ptr));
-DEF_IMGLIB_FN (void, png_set_sig_bytes, (png_structp, int));
-DEF_IMGLIB_FN (void, png_read_info, (png_structp, png_infop));
-DEF_IMGLIB_FN (png_uint_32, png_get_IHDR, (png_structp, png_infop,
-                             png_uint_32 *, png_uint_32 *,
-                             int *, int *, int *, int *, int *));
-DEF_IMGLIB_FN (png_uint_32, png_get_valid, (png_structp, png_infop, png_uint_32));
-DEF_IMGLIB_FN (void, png_set_strip_16, (png_structp));
-DEF_IMGLIB_FN (void, png_set_expand, (png_structp));
-DEF_IMGLIB_FN (void, png_set_gray_to_rgb, (png_structp));
-DEF_IMGLIB_FN (void, png_set_background, (png_structp, png_color_16p,
-                                   int, int, double));
-DEF_IMGLIB_FN (png_uint_32, png_get_bKGD, (png_structp, png_infop, png_color_16p *));
-DEF_IMGLIB_FN (void, png_read_update_info, (png_structp, png_infop));
-DEF_IMGLIB_FN (png_byte, png_get_channels, (png_structp, png_infop));
-DEF_IMGLIB_FN (png_size_t, png_get_rowbytes, (png_structp, png_infop));
-DEF_IMGLIB_FN (void, png_read_image, (png_structp, png_bytepp));
-DEF_IMGLIB_FN (void, png_read_end, (png_structp, png_infop));
-DEF_IMGLIB_FN (void, png_error, (png_structp, png_const_charp));
-
-#if (PNG_LIBPNG_VER >= 10500)
-DEF_IMGLIB_FN (void, png_longjmp, (png_structp, int)) PNG_NORETURN;
-DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn, (png_structp, png_longjmp_ptr, size_t));
-#endif /* libpng version >= 1.5 */
+DEF_DLL_FN (png_voidp, png_get_io_ptr, (png_structp));
+DEF_DLL_FN (int, png_sig_cmp, (png_bytep, png_size_t, png_size_t));
+DEF_DLL_FN (png_structp, png_create_read_struct,
+           (png_const_charp, png_voidp, png_error_ptr, png_error_ptr));
+DEF_DLL_FN (png_infop, png_create_info_struct, (png_structp));
+DEF_DLL_FN (void, png_destroy_read_struct,
+           (png_structpp, png_infopp, png_infopp));
+DEF_DLL_FN (void, png_set_read_fn, (png_structp, png_voidp, png_rw_ptr));
+DEF_DLL_FN (void, png_set_sig_bytes, (png_structp, int));
+DEF_DLL_FN (void, png_read_info, (png_structp, png_infop));
+DEF_DLL_FN (png_uint_32, png_get_IHDR,
+           (png_structp, png_infop, png_uint_32 *, png_uint_32 *,
+            int *, int *, int *, int *, int *));
+DEF_DLL_FN (png_uint_32, png_get_valid, (png_structp, png_infop, png_uint_32));
+DEF_DLL_FN (void, png_set_strip_16, (png_structp));
+DEF_DLL_FN (void, png_set_expand, (png_structp));
+DEF_DLL_FN (void, png_set_gray_to_rgb, (png_structp));
+DEF_DLL_FN (void, png_set_background,
+           (png_structp, png_color_16p, int, int, double));
+DEF_DLL_FN (png_uint_32, png_get_bKGD,
+           (png_structp, png_infop, png_color_16p *));
+DEF_DLL_FN (void, png_read_update_info, (png_structp, png_infop));
+DEF_DLL_FN (png_byte, png_get_channels, (png_structp, png_infop));
+DEF_DLL_FN (png_size_t, png_get_rowbytes, (png_structp, png_infop));
+DEF_DLL_FN (void, png_read_image, (png_structp, png_bytepp));
+DEF_DLL_FN (void, png_read_end, (png_structp, png_infop));
+DEF_DLL_FN (void, png_error, (png_structp, png_const_charp));
+
+#  if (PNG_LIBPNG_VER >= 10500)
+DEF_DLL_FN (void, png_longjmp, (png_structp, int)) PNG_NORETURN;
+DEF_DLL_FN (jmp_buf *, png_set_longjmp_fn,
+           (png_structp, png_longjmp_ptr, size_t));
+#  endif /* libpng version >= 1.5 */
 
 static bool
 init_png_functions (void)
@@ -5572,87 +5567,107 @@ init_png_functions (void)
   if (!(library = w32_delayed_load (Qpng)))
     return 0;
 
-  LOAD_IMGLIB_FN (library, png_get_io_ptr);
-  LOAD_IMGLIB_FN (library, png_sig_cmp);
-  LOAD_IMGLIB_FN (library, png_create_read_struct);
-  LOAD_IMGLIB_FN (library, png_create_info_struct);
-  LOAD_IMGLIB_FN (library, png_destroy_read_struct);
-  LOAD_IMGLIB_FN (library, png_set_read_fn);
-  LOAD_IMGLIB_FN (library, png_set_sig_bytes);
-  LOAD_IMGLIB_FN (library, png_read_info);
-  LOAD_IMGLIB_FN (library, png_get_IHDR);
-  LOAD_IMGLIB_FN (library, png_get_valid);
-  LOAD_IMGLIB_FN (library, png_set_strip_16);
-  LOAD_IMGLIB_FN (library, png_set_expand);
-  LOAD_IMGLIB_FN (library, png_set_gray_to_rgb);
-  LOAD_IMGLIB_FN (library, png_set_background);
-  LOAD_IMGLIB_FN (library, png_get_bKGD);
-  LOAD_IMGLIB_FN (library, png_read_update_info);
-  LOAD_IMGLIB_FN (library, png_get_channels);
-  LOAD_IMGLIB_FN (library, png_get_rowbytes);
-  LOAD_IMGLIB_FN (library, png_read_image);
-  LOAD_IMGLIB_FN (library, png_read_end);
-  LOAD_IMGLIB_FN (library, png_error);
-
-#if (PNG_LIBPNG_VER >= 10500)
-  LOAD_IMGLIB_FN (library, png_longjmp);
-  LOAD_IMGLIB_FN (library, png_set_longjmp_fn);
-#endif /* libpng version >= 1.5 */
+  LOAD_DLL_FN (library, png_get_io_ptr);
+  LOAD_DLL_FN (library, png_sig_cmp);
+  LOAD_DLL_FN (library, png_create_read_struct);
+  LOAD_DLL_FN (library, png_create_info_struct);
+  LOAD_DLL_FN (library, png_destroy_read_struct);
+  LOAD_DLL_FN (library, png_set_read_fn);
+  LOAD_DLL_FN (library, png_set_sig_bytes);
+  LOAD_DLL_FN (library, png_read_info);
+  LOAD_DLL_FN (library, png_get_IHDR);
+  LOAD_DLL_FN (library, png_get_valid);
+  LOAD_DLL_FN (library, png_set_strip_16);
+  LOAD_DLL_FN (library, png_set_expand);
+  LOAD_DLL_FN (library, png_set_gray_to_rgb);
+  LOAD_DLL_FN (library, png_set_background);
+  LOAD_DLL_FN (library, png_get_bKGD);
+  LOAD_DLL_FN (library, png_read_update_info);
+  LOAD_DLL_FN (library, png_get_channels);
+  LOAD_DLL_FN (library, png_get_rowbytes);
+  LOAD_DLL_FN (library, png_read_image);
+  LOAD_DLL_FN (library, png_read_end);
+  LOAD_DLL_FN (library, png_error);
+
+#  if (PNG_LIBPNG_VER >= 10500)
+  LOAD_DLL_FN (library, png_longjmp);
+  LOAD_DLL_FN (library, png_set_longjmp_fn);
+#  endif /* libpng version >= 1.5 */
 
   return 1;
 }
-#else
-
-#define fn_png_get_io_ptr              png_get_io_ptr
-#define fn_png_sig_cmp                 png_sig_cmp
-#define fn_png_create_read_struct      png_create_read_struct
-#define fn_png_create_info_struct      png_create_info_struct
-#define fn_png_destroy_read_struct     png_destroy_read_struct
-#define fn_png_set_read_fn             png_set_read_fn
-#define fn_png_set_sig_bytes           png_set_sig_bytes
-#define fn_png_read_info               png_read_info
-#define fn_png_get_IHDR                        png_get_IHDR
-#define fn_png_get_valid               png_get_valid
-#define fn_png_set_strip_16            png_set_strip_16
-#define fn_png_set_expand              png_set_expand
-#define fn_png_set_gray_to_rgb         png_set_gray_to_rgb
-#define fn_png_set_background          png_set_background
-#define fn_png_get_bKGD                        png_get_bKGD
-#define fn_png_read_update_info                png_read_update_info
-#define fn_png_get_channels            png_get_channels
-#define fn_png_get_rowbytes            png_get_rowbytes
-#define fn_png_read_image              png_read_image
-#define fn_png_read_end                        png_read_end
-#define fn_png_error                   png_error
-
-#if (PNG_LIBPNG_VER >= 10500)
-#define fn_png_longjmp                 png_longjmp
-#define fn_png_set_longjmp_fn          png_set_longjmp_fn
-#endif /* libpng version >= 1.5 */
 
-#endif /* WINDOWSNT */
+#  undef png_create_info_struct
+#  undef png_create_read_struct
+#  undef png_destroy_read_struct
+#  undef png_error
+#  undef png_get_bKGD
+#  undef png_get_channels
+#  undef png_get_IHDR
+#  undef png_get_io_ptr
+#  undef png_get_rowbytes
+#  undef png_get_valid
+#  undef png_longjmp
+#  undef png_read_end
+#  undef png_read_image
+#  undef png_read_info
+#  undef png_read_update_info
+#  undef png_set_background
+#  undef png_set_expand
+#  undef png_set_gray_to_rgb
+#  undef png_set_longjmp_fn
+#  undef png_set_read_fn
+#  undef png_set_sig_bytes
+#  undef png_set_strip_16
+#  undef png_sig_cmp
+
+#  define png_create_info_struct fn_png_create_info_struct
+#  define png_create_read_struct fn_png_create_read_struct
+#  define png_destroy_read_struct fn_png_destroy_read_struct
+#  define png_error fn_png_error
+#  define png_get_bKGD fn_png_get_bKGD
+#  define png_get_channels fn_png_get_channels
+#  define png_get_IHDR fn_png_get_IHDR
+#  define png_get_io_ptr fn_png_get_io_ptr
+#  define png_get_rowbytes fn_png_get_rowbytes
+#  define png_get_valid fn_png_get_valid
+#  define png_longjmp fn_png_longjmp
+#  define png_read_end fn_png_read_end
+#  define png_read_image fn_png_read_image
+#  define png_read_info fn_png_read_info
+#  define png_read_update_info fn_png_read_update_info
+#  define png_set_background fn_png_set_background
+#  define png_set_expand fn_png_set_expand
+#  define png_set_gray_to_rgb fn_png_set_gray_to_rgb
+#  define png_set_longjmp_fn fn_png_set_longjmp_fn
+#  define png_set_read_fn fn_png_set_read_fn
+#  define png_set_sig_bytes fn_png_set_sig_bytes
+#  define png_set_strip_16 fn_png_set_strip_16
+#  define png_sig_cmp fn_png_sig_cmp
+
+# endif /* WINDOWSNT */
 
 /* Fast implementations of setjmp and longjmp.  Although setjmp and longjmp
    will do, POSIX _setjmp and _longjmp (if available) are often faster.
    Do not use sys_setjmp, as PNG supports only jmp_buf.
    It's OK if the longjmp substitute restores the signal mask.  */
-#ifdef HAVE__SETJMP
-# define FAST_SETJMP(j) _setjmp (j)
-# define FAST_LONGJMP _longjmp
-#else
-# define FAST_SETJMP(j) setjmp (j)
-# define FAST_LONGJMP longjmp
-#endif
-
-#if PNG_LIBPNG_VER < 10500
-#define PNG_LONGJMP(ptr) FAST_LONGJMP ((ptr)->jmpbuf, 1)
-#define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
-#else
+# ifdef HAVE__SETJMP
+#  define FAST_SETJMP(j) _setjmp (j)
+#  define FAST_LONGJMP _longjmp
+# else
+#  define FAST_SETJMP(j) setjmp (j)
+#  define FAST_LONGJMP longjmp
+# endif
+
+# if PNG_LIBPNG_VER < 10500
+#  define PNG_LONGJMP(ptr) FAST_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, FAST_LONGJMP, sizeof (jmp_buf)))
-#endif
+#  define PNG_LONGJMP(ptr) png_longjmp (ptr, 1)
+#  define PNG_JMPBUF(ptr) \
+     (*png_set_longjmp_fn (ptr, FAST_LONGJMP, sizeof (jmp_buf)))
+# endif
 
 /* Error and warning handlers installed when the PNG library
    is initialized.  */
@@ -5692,10 +5707,10 @@ struct png_memory_storage
 static void
 png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
 {
-  struct png_memory_storage *tbr = fn_png_get_io_ptr (png_ptr);
+  struct png_memory_storage *tbr = png_get_io_ptr (png_ptr);
 
   if (length > tbr->len - tbr->index)
-    fn_png_error (png_ptr, "Read error");
+    png_error (png_ptr, "Read error");
 
   memcpy (data, tbr->bytes + tbr->index, length);
   tbr->index = tbr->index + length;
@@ -5709,10 +5724,10 @@ png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
 static void
 png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
 {
-  FILE *fp = fn_png_get_io_ptr (png_ptr);
+  FILE *fp = png_get_io_ptr (png_ptr);
 
   if (fread (data, 1, length, fp) < length)
-    fn_png_error (png_ptr, "Read error");
+    png_error (png_ptr, "Read error");
 }
 
 
@@ -5774,7 +5789,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
 
       /* Check PNG signature.  */
       if (fread (sig, 1, sizeof sig, fp) != sizeof sig
-         || fn_png_sig_cmp (sig, 0, sizeof sig))
+         || png_sig_cmp (sig, 0, sizeof sig))
        {
          fclose (fp);
          image_error ("Not a PNG file: `%s'", file, Qnil);
@@ -5796,7 +5811,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
 
       /* Check PNG signature.  */
       if (tbr.len < sizeof sig
-         || fn_png_sig_cmp (tbr.bytes, 0, sizeof sig))
+         || png_sig_cmp (tbr.bytes, 0, sizeof sig))
        {
          image_error ("Not a PNG image: `%s'", img->spec, Qnil);
          return 0;
@@ -5807,13 +5822,13 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
     }
 
   /* Initialize read and info structs for PNG lib.  */
-  png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING,
+  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
                                       NULL, my_png_error,
                                       my_png_warning);
   if (png_ptr)
     {
-      info_ptr = fn_png_create_info_struct (png_ptr);
-      end_info = fn_png_create_info_struct (png_ptr);
+      info_ptr = png_create_info_struct (png_ptr);
+      end_info = png_create_info_struct (png_ptr);
     }
 
   c->png_ptr = png_ptr;
@@ -5825,7 +5840,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
 
   if (! (info_ptr && end_info))
     {
-      fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
+      png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
       png_ptr = 0;
     }
   if (! png_ptr)
@@ -5840,7 +5855,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
     {
     error:
       if (c->png_ptr)
-       fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
+       png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
       xfree (c->pixels);
       xfree (c->rows);
       if (c->fp)
@@ -5853,14 +5868,14 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
 
   /* Read image info.  */
   if (!NILP (specified_data))
-    fn_png_set_read_fn (png_ptr, &tbr, png_read_from_memory);
+    png_set_read_fn (png_ptr, &tbr, png_read_from_memory);
   else
-    fn_png_set_read_fn (png_ptr, fp, png_read_from_file);
+    png_set_read_fn (png_ptr, fp, png_read_from_file);
 
-  fn_png_set_sig_bytes (png_ptr, sizeof sig);
-  fn_png_read_info (png_ptr, info_ptr);
-  fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
-                  &interlace_type, NULL, NULL);
+  png_set_sig_bytes (png_ptr, sizeof sig);
+  png_read_info (png_ptr, info_ptr);
+  png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+               &interlace_type, NULL, NULL);
 
   if (! (width <= INT_MAX && height <= INT_MAX
         && check_image_size (f, width, height)))
@@ -5876,7 +5891,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
 
   /* If image contains simply transparency data, we prefer to
      construct a clipping mask.  */
-  if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
+  if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
     transparent_p = 1;
   else
     transparent_p = 0;
@@ -5887,16 +5902,16 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
 
   /* Strip more than 8 bits per channel.  */
   if (bit_depth == 16)
-    fn_png_set_strip_16 (png_ptr);
+    png_set_strip_16 (png_ptr);
 
   /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
      if available.  */
-  fn_png_set_expand (png_ptr);
+  png_set_expand (png_ptr);
 
   /* Convert grayscale images to RGB.  */
   if (color_type == PNG_COLOR_TYPE_GRAY
       || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-    fn_png_set_gray_to_rgb (png_ptr);
+    png_set_gray_to_rgb (png_ptr);
 
   /* Handle alpha channel by combining the image with a background
      color.  Do this only if a real alpha channel is supplied.  For
@@ -5922,24 +5937,24 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
          bg.green = color.green >> shift;
          bg.blue = color.blue >> shift;
 
-         fn_png_set_background (png_ptr, &bg,
-                                PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+         png_set_background (png_ptr, &bg,
+                             PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
        }
     }
 
   /* Update info structure.  */
-  fn_png_read_update_info (png_ptr, info_ptr);
+  png_read_update_info (png_ptr, info_ptr);
 
   /* Get number of channels.  Valid values are 1 for grayscale images
      and images with a palette, 2 for grayscale images with transparency
      information (alpha channel), 3 for RGB images, and 4 for RGB
      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);
+  channels = png_get_channels (png_ptr, info_ptr);
   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);
+  row_bytes = png_get_rowbytes (png_ptr, info_ptr);
 
   /* Allocate memory for the image.  */
   if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
@@ -5951,8 +5966,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
     rows[i] = pixels + i * row_bytes;
 
   /* Read the entire image.  */
-  fn_png_read_image (png_ptr, rows);
-  fn_png_read_end (png_ptr, info_ptr);
+  png_read_image (png_ptr, rows);
+  png_read_end (png_ptr, info_ptr);
   if (fp)
     {
       fclose (fp);
@@ -6016,21 +6031,21 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
        overrode it.  */
     {
       png_color_16 *bg;
-      if (fn_png_get_bKGD (png_ptr, info_ptr, &bg))
+      if (png_get_bKGD (png_ptr, info_ptr, &bg))
        {
          img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
          img->background_valid = 1;
        }
     }
 
-#ifdef COLOR_TABLE_SUPPORT
+# ifdef COLOR_TABLE_SUPPORT
   /* Remember colors allocated for this image.  */
   img->colors = colors_in_color_table (&img->ncolors);
   free_color_table ();
-#endif /* COLOR_TABLE_SUPPORT */
+# endif /* COLOR_TABLE_SUPPORT */
 
   /* Clean up.  */
-  fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
+  png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
   xfree (rows);
   xfree (pixels);
 
@@ -6165,15 +6180,15 @@ jpeg_image_p (Lisp_Object object)
 
 /* Work around a warning about HAVE_STDLIB_H being redefined in
    jconfig.h.  */
-#ifdef HAVE_STDLIB_H
-#undef HAVE_STDLIB_H
-#endif /* HAVE_STLIB_H */
+# ifdef HAVE_STDLIB_H
+#  undef HAVE_STDLIB_H
+# endif
 
-#if defined (HAVE_NTGUI) && !defined (__WIN32__)
+# if defined (HAVE_NTGUI) && !defined (__WIN32__)
 /* In older releases of the jpeg library, jpeglib.h will define boolean
    differently depending on __WIN32__, so make sure it is defined.  */
-#define __WIN32__ 1
-#endif
+#  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,
@@ -6189,23 +6204,25 @@ jpeg_image_p (Lisp_Object object)
    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>
+# if defined CYGWIN && defined HAVE_NTGUI
+#  define boolean jpeg_boolean
+# endif
+# include <jpeglib.h>
+# include <jerror.h>
 
-#ifdef WINDOWSNT
+# ifdef WINDOWSNT
 
 /* JPEG library details.  */
-DEF_IMGLIB_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t));
-DEF_IMGLIB_FN (boolean, jpeg_start_decompress, (j_decompress_ptr));
-DEF_IMGLIB_FN (boolean, jpeg_finish_decompress, (j_decompress_ptr));
-DEF_IMGLIB_FN (void, jpeg_destroy_decompress, (j_decompress_ptr));
-DEF_IMGLIB_FN (int, jpeg_read_header, (j_decompress_ptr, boolean));
-DEF_IMGLIB_FN (JDIMENSION, jpeg_read_scanlines, (j_decompress_ptr, JSAMPARRAY, JDIMENSION));
-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));
+DEF_DLL_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t));
+DEF_DLL_FN (boolean, jpeg_start_decompress, (j_decompress_ptr));
+DEF_DLL_FN (boolean, jpeg_finish_decompress, (j_decompress_ptr));
+DEF_DLL_FN (void, jpeg_destroy_decompress, (j_decompress_ptr));
+DEF_DLL_FN (int, jpeg_read_header, (j_decompress_ptr, boolean));
+DEF_DLL_FN (JDIMENSION, jpeg_read_scanlines,
+           (j_decompress_ptr, JSAMPARRAY, JDIMENSION));
+DEF_DLL_FN (struct jpeg_error_mgr *, jpeg_std_error,
+           (struct jpeg_error_mgr *));
+DEF_DLL_FN (boolean, jpeg_resync_to_restart, (j_decompress_ptr, int));
 
 static bool
 init_jpeg_functions (void)
@@ -6215,37 +6232,46 @@ init_jpeg_functions (void)
   if (!(library = w32_delayed_load (Qjpeg)))
     return 0;
 
-  LOAD_IMGLIB_FN (library, jpeg_finish_decompress);
-  LOAD_IMGLIB_FN (library, jpeg_read_scanlines);
-  LOAD_IMGLIB_FN (library, jpeg_start_decompress);
-  LOAD_IMGLIB_FN (library, jpeg_read_header);
-  LOAD_IMGLIB_FN (library, jpeg_CreateDecompress);
-  LOAD_IMGLIB_FN (library, jpeg_destroy_decompress);
-  LOAD_IMGLIB_FN (library, jpeg_std_error);
-  LOAD_IMGLIB_FN (library, jpeg_resync_to_restart);
+  LOAD_DLL_FN (library, jpeg_finish_decompress);
+  LOAD_DLL_FN (library, jpeg_read_scanlines);
+  LOAD_DLL_FN (library, jpeg_start_decompress);
+  LOAD_DLL_FN (library, jpeg_read_header);
+  LOAD_DLL_FN (library, jpeg_CreateDecompress);
+  LOAD_DLL_FN (library, jpeg_destroy_decompress);
+  LOAD_DLL_FN (library, jpeg_std_error);
+  LOAD_DLL_FN (library, jpeg_resync_to_restart);
   return 1;
 }
 
+#  undef jpeg_CreateDecompress
+#  undef jpeg_destroy_decompress
+#  undef jpeg_finish_decompress
+#  undef jpeg_read_header
+#  undef jpeg_read_scanlines
+#  undef jpeg_resync_to_restart
+#  undef jpeg_start_decompress
+#  undef jpeg_std_error
+
+#  define jpeg_CreateDecompress fn_jpeg_CreateDecompress
+#  define jpeg_destroy_decompress fn_jpeg_destroy_decompress
+#  define jpeg_finish_decompress fn_jpeg_finish_decompress
+#  define jpeg_read_header fn_jpeg_read_header
+#  define jpeg_read_scanlines fn_jpeg_read_scanlines
+#  define jpeg_resync_to_restart fn_jpeg_resync_to_restart
+#  define jpeg_start_decompress fn_jpeg_start_decompress
+#  define jpeg_std_error fn_jpeg_std_error
+
 /* Wrapper since we can't directly assign the function pointer
    to another function pointer that was declared more completely easily.  */
 static boolean
 jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired)
 {
-  return fn_jpeg_resync_to_restart (cinfo, desired);
+  return jpeg_resync_to_restart (cinfo, desired);
 }
+#  undef jpeg_resync_to_restart
+#  define jpeg_resync_to_restart jpeg_resync_to_restart_wrapper
 
-#else
-
-#define fn_jpeg_CreateDecompress(a,b,c)        jpeg_create_decompress (a)
-#define fn_jpeg_start_decompress       jpeg_start_decompress
-#define fn_jpeg_finish_decompress      jpeg_finish_decompress
-#define fn_jpeg_destroy_decompress     jpeg_destroy_decompress
-#define fn_jpeg_read_header            jpeg_read_header
-#define fn_jpeg_read_scanlines         jpeg_read_scanlines
-#define fn_jpeg_std_error              jpeg_std_error
-#define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
-
-#endif /* WINDOWSNT */
+# endif /* WINDOWSNT */
 
 struct my_jpeg_error_mgr
 {
@@ -6353,7 +6379,7 @@ jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len)
   src->init_source = our_common_init_source;
   src->fill_input_buffer = our_memory_fill_input_buffer;
   src->skip_input_data = our_memory_skip_input_data;
-  src->resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method.  */
+  src->resync_to_restart = jpeg_resync_to_restart; /* Use default method.  */
   src->term_source = our_common_term_source;
   src->bytes_in_buffer = len;
   src->next_input_byte = data;
@@ -6459,7 +6485,7 @@ jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
   src->mgr.init_source = our_common_init_source;
   src->mgr.fill_input_buffer = our_stdio_fill_input_buffer;
   src->mgr.skip_input_data = our_stdio_skip_input_data;
-  src->mgr.resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method.  */
+  src->mgr.resync_to_restart = jpeg_resync_to_restart; /* Use default.  */
   src->mgr.term_source = our_common_term_source;
   src->mgr.bytes_in_buffer = 0;
   src->mgr.next_input_byte = NULL;
@@ -6510,7 +6536,7 @@ jpeg_load_body (struct frame *f, struct image *img,
 
   /* Customize libjpeg's error handling to call my_error_exit when an
      error is detected.  This function will perform a longjmp.  */
-  mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub);
+  mgr->cinfo.err = jpeg_std_error (&mgr->pub);
   mgr->pub.error_exit = my_error_exit;
   if (sys_setjmp (mgr->setjmp_buffer))
     {
@@ -6536,7 +6562,7 @@ jpeg_load_body (struct frame *f, struct image *img,
       /* Close the input file and destroy the JPEG object.  */
       if (fp)
        fclose (fp);
-      fn_jpeg_destroy_decompress (&mgr->cinfo);
+      jpeg_destroy_decompress (&mgr->cinfo);
 
       /* If we already have an XImage, free that.  */
       x_destroy_x_image (ximg);
@@ -6548,7 +6574,7 @@ jpeg_load_body (struct frame *f, struct image *img,
 
   /* Create the JPEG decompression object.  Let it read from fp.
         Read the JPEG image header.  */
-  fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
+  jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
 
   if (NILP (specified_data))
     jpeg_file_src (&mgr->cinfo, fp);
@@ -6556,12 +6582,12 @@ jpeg_load_body (struct frame *f, struct image *img,
     jpeg_memory_src (&mgr->cinfo, SDATA (specified_data),
                     SBYTES (specified_data));
 
-  fn_jpeg_read_header (&mgr->cinfo, 1);
+  jpeg_read_header (&mgr->cinfo, 1);
 
   /* Customize decompression so that color quantization will be used.
         Start decompression.  */
   mgr->cinfo.quantize_colors = 1;
-  fn_jpeg_start_decompress (&mgr->cinfo);
+  jpeg_start_decompress (&mgr->cinfo);
   width = img->width = mgr->cinfo.output_width;
   height = img->height = mgr->cinfo.output_height;
 
@@ -6624,14 +6650,14 @@ jpeg_load_body (struct frame *f, struct image *img,
                                         JPOOL_IMAGE, row_stride, 1);
   for (y = 0; y < height; ++y)
     {
-      fn_jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
+      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 (&mgr->cinfo);
-  fn_jpeg_destroy_decompress (&mgr->cinfo);
+  jpeg_finish_decompress (&mgr->cinfo);
+  jpeg_destroy_decompress (&mgr->cinfo);
   if (fp)
     fclose (fp);
 
@@ -6755,22 +6781,22 @@ tiff_image_p (Lisp_Object object)
 
 #ifdef HAVE_TIFF
 
-#include <tiffio.h>
+# include <tiffio.h>
 
-#ifdef WINDOWSNT
+# ifdef WINDOWSNT
 
 /* TIFF library details.  */
-DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler));
-DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetWarningHandler, (TIFFErrorHandler));
-DEF_IMGLIB_FN (TIFF *, TIFFOpen, (const char *, const char *));
-DEF_IMGLIB_FN (TIFF *, TIFFClientOpen, (const char *, const char *, thandle_t,
-                               TIFFReadWriteProc, TIFFReadWriteProc,
-                               TIFFSeekProc, TIFFCloseProc, TIFFSizeProc,
-                               TIFFMapFileProc, TIFFUnmapFileProc));
-DEF_IMGLIB_FN (int, TIFFGetField, (TIFF *, ttag_t, ...));
-DEF_IMGLIB_FN (int, TIFFReadRGBAImage, (TIFF *, uint32, uint32, uint32 *, int));
-DEF_IMGLIB_FN (void, TIFFClose, (TIFF *));
-DEF_IMGLIB_FN (int, TIFFSetDirectory, (TIFF *, tdir_t));
+DEF_DLL_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler));
+DEF_DLL_FN (TIFFErrorHandler, TIFFSetWarningHandler, (TIFFErrorHandler));
+DEF_DLL_FN (TIFF *, TIFFOpen, (const char *, const char *));
+DEF_DLL_FN (TIFF *, TIFFClientOpen,
+           (const char *, const char *, thandle_t, TIFFReadWriteProc,
+            TIFFReadWriteProc, TIFFSeekProc, TIFFCloseProc, TIFFSizeProc,
+            TIFFMapFileProc, TIFFUnmapFileProc));
+DEF_DLL_FN (int, TIFFGetField, (TIFF *, ttag_t, ...));
+DEF_DLL_FN (int, TIFFReadRGBAImage, (TIFF *, uint32, uint32, uint32 *, int));
+DEF_DLL_FN (void, TIFFClose, (TIFF *));
+DEF_DLL_FN (int, TIFFSetDirectory, (TIFF *, tdir_t));
 
 static bool
 init_tiff_functions (void)
@@ -6780,28 +6806,36 @@ init_tiff_functions (void)
   if (!(library = w32_delayed_load (Qtiff)))
     return 0;
 
-  LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
-  LOAD_IMGLIB_FN (library, TIFFSetWarningHandler);
-  LOAD_IMGLIB_FN (library, TIFFOpen);
-  LOAD_IMGLIB_FN (library, TIFFClientOpen);
-  LOAD_IMGLIB_FN (library, TIFFGetField);
-  LOAD_IMGLIB_FN (library, TIFFReadRGBAImage);
-  LOAD_IMGLIB_FN (library, TIFFClose);
-  LOAD_IMGLIB_FN (library, TIFFSetDirectory);
+  LOAD_DLL_FN (library, TIFFSetErrorHandler);
+  LOAD_DLL_FN (library, TIFFSetWarningHandler);
+  LOAD_DLL_FN (library, TIFFOpen);
+  LOAD_DLL_FN (library, TIFFClientOpen);
+  LOAD_DLL_FN (library, TIFFGetField);
+  LOAD_DLL_FN (library, TIFFReadRGBAImage);
+  LOAD_DLL_FN (library, TIFFClose);
+  LOAD_DLL_FN (library, TIFFSetDirectory);
   return 1;
 }
 
-#else
+#  undef TIFFClientOpen
+#  undef TIFFClose
+#  undef TIFFGetField
+#  undef TIFFOpen
+#  undef TIFFReadRGBAImage
+#  undef TIFFSetDirectory
+#  undef TIFFSetErrorHandler
+#  undef TIFFSetWarningHandler
 
-#define fn_TIFFSetErrorHandler         TIFFSetErrorHandler
-#define fn_TIFFSetWarningHandler       TIFFSetWarningHandler
-#define fn_TIFFOpen                    TIFFOpen
-#define fn_TIFFClientOpen              TIFFClientOpen
-#define fn_TIFFGetField                        TIFFGetField
-#define fn_TIFFReadRGBAImage           TIFFReadRGBAImage
-#define fn_TIFFClose                   TIFFClose
-#define fn_TIFFSetDirectory            TIFFSetDirectory
-#endif /* WINDOWSNT */
+#  define TIFFClientOpen fn_TIFFClientOpen
+#  define TIFFClose fn_TIFFClose
+#  define TIFFGetField fn_TIFFGetField
+#  define TIFFOpen fn_TIFFOpen
+#  define TIFFReadRGBAImage fn_TIFFReadRGBAImage
+#  define TIFFSetDirectory fn_TIFFSetDirectory
+#  define TIFFSetErrorHandler fn_TIFFSetErrorHandler
+#  define TIFFSetWarningHandler fn_TIFFSetWarningHandler
+
+# endif /* WINDOWSNT */
 
 
 /* Reading from a memory buffer for TIFF images Based on the PNG
@@ -6899,11 +6933,11 @@ tiff_size_of_memory (thandle_t data)
    compiler error compiling tiff_handler, see Bugzilla bug #17406
    (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17406).  Declaring
    this function as external works around that problem.  */
-#if defined (__MINGW32__) && __GNUC__ == 3
-# define MINGW_STATIC
-#else
-# define MINGW_STATIC static
-#endif
+# if defined (__MINGW32__) && __GNUC__ == 3
+#  define MINGW_STATIC
+# else
+#  define MINGW_STATIC static
+# endif
 
 MINGW_STATIC void
 tiff_handler (const char *, const char *, const char *, va_list)
@@ -6922,7 +6956,7 @@ tiff_handler (const char *log_format, const char *title,
   add_to_log (log_format, build_string (title),
              make_string (buf, max (0, min (len, sizeof buf - 1))));
 }
-#undef MINGW_STATIC
+# undef MINGW_STATIC
 
 static void tiff_error_handler (const char *, const char *, va_list)
   ATTRIBUTE_FORMAT_PRINTF (2, 0);
@@ -6961,8 +6995,8 @@ tiff_load (struct frame *f, struct image *img)
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
 
-  fn_TIFFSetErrorHandler ((TIFFErrorHandler) tiff_error_handler);
-  fn_TIFFSetWarningHandler ((TIFFErrorHandler) tiff_warning_handler);
+  TIFFSetErrorHandler ((TIFFErrorHandler) tiff_error_handler);
+  TIFFSetWarningHandler ((TIFFErrorHandler) tiff_warning_handler);
 
   if (NILP (specified_data))
     {
@@ -6973,12 +7007,12 @@ tiff_load (struct frame *f, struct image *img)
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
          return 0;
        }
-#ifdef WINDOWSNT
+# ifdef WINDOWSNT
       file = ansi_encode_filename (file);
-#endif
+# endif
 
       /* Try to open the image file.  */
-      tiff = fn_TIFFOpen (SSDATA (file), "r");
+      tiff = TIFFOpen (SSDATA (file), "r");
       if (tiff == NULL)
        {
          image_error ("Cannot open `%s'", file, Qnil);
@@ -6998,14 +7032,14 @@ tiff_load (struct frame *f, struct image *img)
       memsrc.len = SBYTES (specified_data);
       memsrc.index = 0;
 
-      tiff = fn_TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc,
-                               tiff_read_from_memory,
-                               tiff_write_from_memory,
-                               tiff_seek_in_memory,
-                               tiff_close_memory,
-                               tiff_size_of_memory,
-                               tiff_mmap_memory,
-                               tiff_unmap_memory);
+      tiff = TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc,
+                            tiff_read_from_memory,
+                            tiff_write_from_memory,
+                            tiff_seek_in_memory,
+                            tiff_close_memory,
+                            tiff_size_of_memory,
+                            tiff_mmap_memory,
+                            tiff_unmap_memory);
 
       if (!tiff)
        {
@@ -7019,24 +7053,24 @@ tiff_load (struct frame *f, struct image *img)
     {
       EMACS_INT ino = XFASTINT (image);
       if (! (TYPE_MINIMUM (tdir_t) <= ino && ino <= TYPE_MAXIMUM (tdir_t)
-            && fn_TIFFSetDirectory (tiff, ino)))
+            && TIFFSetDirectory (tiff, ino)))
        {
          image_error ("Invalid image number `%s' in image `%s'",
                       image, img->spec);
-         fn_TIFFClose (tiff);
+         TIFFClose (tiff);
          return 0;
        }
     }
 
   /* Get width and height of the image, and allocate a raster buffer
      of width x height 32-bit values.  */
-  fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
-  fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
+  TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
+  TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
 
   if (!check_image_size (f, width, height))
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
-      fn_TIFFClose (tiff);
+      TIFFClose (tiff);
       return 0;
     }
 
@@ -7045,16 +7079,16 @@ tiff_load (struct frame *f, struct image *img)
         && image_create_x_image_and_pixmap (f, img, width, height, 0,
                                             &ximg, 0)))
     {
-      fn_TIFFClose (tiff);
+      TIFFClose (tiff);
       return 0;
     }
 
   buf = xmalloc (sizeof *buf * width * height);
 
-  rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
+  rc = TIFFReadRGBAImage (tiff, width, height, buf, 0);
 
   /* Count the number of images in the file.  */
-  for (count = 1; fn_TIFFSetDirectory (tiff, count); count++)
+  for (count = 1; TIFFSetDirectory (tiff, count); count++)
     continue;
 
   if (count > 1)
@@ -7062,7 +7096,7 @@ tiff_load (struct frame *f, struct image *img)
                            Fcons (make_number (count),
                                   img->lisp_data));
 
-  fn_TIFFClose (tiff);
+  TIFFClose (tiff);
   if (!rc)
     {
       image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
@@ -7088,11 +7122,11 @@ tiff_load (struct frame *f, struct image *img)
        }
     }
 
-#ifdef COLOR_TABLE_SUPPORT
+# ifdef COLOR_TABLE_SUPPORT
   /* Remember the colors allocated for the image.  Free the color table.  */
   img->colors = colors_in_color_table (&img->ncolors);
   free_color_table ();
-#endif /* COLOR_TABLE_SUPPORT */
+# endif /* COLOR_TABLE_SUPPORT */
 
   img->width = width;
   img->height = height;
@@ -7109,9 +7143,8 @@ tiff_load (struct frame *f, struct image *img)
   return 1;
 }
 
-#else /* HAVE_TIFF */
+#elif defined HAVE_NS
 
-#ifdef HAVE_NS
 static bool
 tiff_load (struct frame *f, struct image *img)
 {
@@ -7119,9 +7152,8 @@ tiff_load (struct frame *f, struct image *img)
                         image_spec_value (img->spec, QCfile, NULL),
                         image_spec_value (img->spec, QCdata, NULL));
 }
-#endif  /* HAVE_NS */
 
-#endif /* !HAVE_TIFF */
+#endif
 
 
 \f
@@ -7221,54 +7253,54 @@ gif_image_p (Lisp_Object object)
 
 #ifdef HAVE_GIF
 
-#if defined (HAVE_NTGUI)
+# ifdef HAVE_NTGUI
 
 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
    Undefine before redefining to avoid a preprocessor warning.  */
-#ifdef DrawText
-#undef DrawText
-#endif
+#  ifdef DrawText
+#   undef DrawText
+#  endif
 /* avoid conflict with QuickdrawText.h */
-#define DrawText gif_DrawText
-#include <gif_lib.h>
-#undef DrawText
+#  define DrawText gif_DrawText
+#  include <gif_lib.h>
+#  undef DrawText
 
 /* Giflib before 5.0 didn't define these macros (used only if HAVE_NTGUI).  */
-#ifndef GIFLIB_MINOR
-#define GIFLIB_MINOR 0
-#endif
-#ifndef GIFLIB_RELEASE
-#define GIFLIB_RELEASE 0
-#endif
+#  ifndef GIFLIB_MINOR
+#   define GIFLIB_MINOR 0
+#  endif
+#  ifndef GIFLIB_RELEASE
+#   define GIFLIB_RELEASE 0
+#  endif
 
-#else /* HAVE_NTGUI */
+# else /* HAVE_NTGUI */
 
-#include <gif_lib.h>
+#  include <gif_lib.h>
 
-#endif /* HAVE_NTGUI */
+# endif /* HAVE_NTGUI */
 
 /* Giflib before 5.0 didn't define these macros.  */
-#ifndef GIFLIB_MAJOR
-#define GIFLIB_MAJOR 4
-#endif
+# ifndef GIFLIB_MAJOR
+#  define GIFLIB_MAJOR 4
+# endif
 
-#ifdef WINDOWSNT
+# ifdef WINDOWSNT
 
 /* GIF library details.  */
-#if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
-DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *, int *));
-#else
-DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *));
-#endif
-DEF_IMGLIB_FN (int, DGifSlurp, (GifFileType *));
-#if GIFLIB_MAJOR < 5
-DEF_IMGLIB_FN (GifFileType *, DGifOpen, (void *, InputFunc));
-DEF_IMGLIB_FN (GifFileType *, DGifOpenFileName, (const char *));
-#else
-DEF_IMGLIB_FN (GifFileType *, DGifOpen, (void *, InputFunc, int *));
-DEF_IMGLIB_FN (GifFileType *, DGifOpenFileName, (const char *, int *));
-DEF_IMGLIB_FN (char *, GifErrorString, (int));
-#endif
+#  if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
+DEF_DLL_FN (int, DGifCloseFile, (GifFileType *, int *));
+#   else
+DEF_DLL_FN (int, DGifCloseFile, (GifFileType *));
+#  endif
+DEF_DLL_FN (int, DGifSlurp, (GifFileType *));
+#  if GIFLIB_MAJOR < 5
+DEF_DLL_FN (GifFileType *, DGifOpen, (void *, InputFunc));
+DEF_DLL_FN (GifFileType *, DGifOpenFileName, (const char *));
+#  else
+DEF_DLL_FN (GifFileType *, DGifOpen, (void *, InputFunc, int *));
+DEF_DLL_FN (GifFileType *, DGifOpenFileName, (const char *, int *));
+DEF_DLL_FN (char *, GifErrorString, (int));
+#  endif
 
 static bool
 init_gif_functions (void)
@@ -7278,27 +7310,29 @@ init_gif_functions (void)
   if (!(library = w32_delayed_load (Qgif)))
     return 0;
 
-  LOAD_IMGLIB_FN (library, DGifCloseFile);
-  LOAD_IMGLIB_FN (library, DGifSlurp);
-  LOAD_IMGLIB_FN (library, DGifOpen);
-  LOAD_IMGLIB_FN (library, DGifOpenFileName);
-#if GIFLIB_MAJOR >= 5
-  LOAD_IMGLIB_FN (library, GifErrorString);
-#endif
+  LOAD_DLL_FN (library, DGifCloseFile);
+  LOAD_DLL_FN (library, DGifSlurp);
+  LOAD_DLL_FN (library, DGifOpen);
+  LOAD_DLL_FN (library, DGifOpenFileName);
+#  if GIFLIB_MAJOR >= 5
+  LOAD_DLL_FN (library, GifErrorString);
+#  endif
   return 1;
 }
 
-#else
+#  undef DGifCloseFile
+#  undef DGifOpen
+#  undef DGifOpenFileName
+#  undef DGifSlurp
+#  undef GifErrorString
 
-#define fn_DGifCloseFile       DGifCloseFile
-#define fn_DGifSlurp           DGifSlurp
-#define fn_DGifOpen            DGifOpen
-#define fn_DGifOpenFileName    DGifOpenFileName
-#if 5 <= GIFLIB_MAJOR
-# define fn_GifErrorString     GifErrorString
-#endif
+#  define DGifCloseFile fn_DGifCloseFile
+#  define DGifOpen fn_DGifOpen
+#  define DGifOpenFileName fn_DGifOpenFileName
+#  define DGifSlurp fn_DGifSlurp
+#  define GifErrorString fn_GifErrorString
 
-#endif /* WINDOWSNT */
+# endif /* WINDOWSNT */
 
 /* Reading a GIF image from memory
    Based on the PNG memory stuff to a certain extent. */
@@ -7335,9 +7369,9 @@ gif_close (GifFileType *gif, int *err)
   int retval;
 
 #if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
-  retval = fn_DGifCloseFile (gif, err);
+  retval = DGifCloseFile (gif, err);
 #else
-  retval = fn_DGifCloseFile (gif);
+  retval = DGifCloseFile (gif);
 #if GIFLIB_MAJOR >= 5
   if (err)
     *err = gif->Error;
@@ -7385,18 +7419,18 @@ gif_load (struct frame *f, struct image *img)
 
       /* Open the GIF file.  */
 #if GIFLIB_MAJOR < 5
-      gif = fn_DGifOpenFileName (SSDATA (file));
+      gif = DGifOpenFileName (SSDATA (file));
       if (gif == NULL)
        {
          image_error ("Cannot open `%s'", file, Qnil);
          return 0;
        }
 #else
-      gif = fn_DGifOpenFileName (SSDATA (file), &gif_err);
+      gif = DGifOpenFileName (SSDATA (file), &gif_err);
       if (gif == NULL)
        {
          image_error ("Cannot open `%s': %s",
-                      file, build_string (fn_GifErrorString (gif_err)));
+                      file, build_string (GifErrorString (gif_err)));
          return 0;
        }
 #endif
@@ -7416,18 +7450,18 @@ gif_load (struct frame *f, struct image *img)
       memsrc.index = 0;
 
 #if GIFLIB_MAJOR < 5
-      gif = fn_DGifOpen (&memsrc, gif_read_from_memory);
+      gif = DGifOpen (&memsrc, gif_read_from_memory);
       if (!gif)
        {
          image_error ("Cannot open memory source `%s'", img->spec, Qnil);
          return 0;
        }
 #else
-      gif = fn_DGifOpen (&memsrc, gif_read_from_memory, &gif_err);
+      gif = DGifOpen (&memsrc, gif_read_from_memory, &gif_err);
       if (!gif)
        {
          image_error ("Cannot open memory source `%s': %s",
-                      img->spec, build_string (fn_GifErrorString (gif_err)));
+                      img->spec, build_string (GifErrorString (gif_err)));
          return 0;
        }
 #endif
@@ -7442,7 +7476,7 @@ gif_load (struct frame *f, struct image *img)
     }
 
   /* Read entire contents.  */
-  rc = fn_DGifSlurp (gif);
+  rc = DGifSlurp (gif);
   if (rc == GIF_ERROR || gif->ImageCount <= 0)
     {
       image_error ("Error reading `%s'", img->spec, Qnil);
@@ -7676,7 +7710,7 @@ gif_load (struct frame *f, struct image *img)
   if (gif_close (gif, &gif_err) == GIF_ERROR)
     {
 #if 5 <= GIFLIB_MAJOR
-      char *error_text = fn_GifErrorString (gif_err);
+      char *error_text = GifErrorString (gif_err);
 
       if (error_text)
        image_error ("Error closing `%s': %s",
@@ -8231,6 +8265,12 @@ imagemagick_load_image (struct frame *f, struct image *img,
       return 0;
     }
 
+  if (MagickGetImageDelay (image_wand) > 0)
+    img->lisp_data =
+      Fcons (Qdelay,
+             Fcons (make_float (MagickGetImageDelay (image_wand) / 100.0),
+                    img->lisp_data));
+
   if (MagickGetNumberImages (image_wand) > 1)
     img->lisp_data =
       Fcons (Qcount,
@@ -8582,7 +8622,7 @@ and `imagemagick-types-inhibit'.  */)
                                 SVG
  ***********************************************************************/
 
-#if defined (HAVE_RSVG)
+#ifdef HAVE_RSVG
 
 /* Function prototypes.  */
 
@@ -8590,7 +8630,7 @@ static bool svg_image_p (Lisp_Object object);
 static bool svg_load (struct frame *f, struct image *img);
 
 static bool svg_load_image (struct frame *, struct image *,
-                           unsigned char *, ptrdiff_t);
+                           unsigned char *, ptrdiff_t, char *);
 
 /* The symbol `svg' identifying images of this type. */
 
@@ -8630,11 +8670,11 @@ static const struct image_keyword svg_format[SVG_LAST] =
   {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
-#if defined HAVE_NTGUI && defined WINDOWSNT
+# if defined HAVE_NTGUI && defined WINDOWSNT
 static bool init_svg_functions (void);
-#else
+# else
 #define init_svg_functions NULL
-#endif
+# endif
 
 /* Structure describing the image type `svg'.  Its the same type of
    structure defined for all image formats, handled by emacs image
@@ -8668,31 +8708,34 @@ svg_image_p (Lisp_Object object)
   return fmt[SVG_FILE].count + fmt[SVG_DATA].count == 1;
 }
 
-#include <librsvg/rsvg.h>
+# include <librsvg/rsvg.h>
 
-#ifdef WINDOWSNT
+# ifdef WINDOWSNT
 
 /* SVG library functions.  */
-DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new, (void));
-DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions, (RsvgHandle *, RsvgDimensionData *));
-DEF_IMGLIB_FN (gboolean, rsvg_handle_write, (RsvgHandle *, const guchar *, gsize, GError **));
-DEF_IMGLIB_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
-DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
-
-DEF_IMGLIB_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
-DEF_IMGLIB_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
-DEF_IMGLIB_FN (guchar *, gdk_pixbuf_get_pixels, (const GdkPixbuf *));
-DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride, (const GdkPixbuf *));
-DEF_IMGLIB_FN (GdkColorspace, gdk_pixbuf_get_colorspace, (const GdkPixbuf *));
-DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels, (const GdkPixbuf *));
-DEF_IMGLIB_FN (gboolean, gdk_pixbuf_get_has_alpha, (const GdkPixbuf *));
-DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample, (const GdkPixbuf *));
-
-#if ! GLIB_CHECK_VERSION (2, 36, 0)
-DEF_IMGLIB_FN (void, g_type_init, (void));
-#endif
-DEF_IMGLIB_FN (void, g_object_unref, (gpointer));
-DEF_IMGLIB_FN (void, g_error_free, (GError *));
+DEF_DLL_FN (RsvgHandle *, rsvg_handle_new, (void));
+DEF_DLL_FN (void, rsvg_handle_get_dimensions,
+           (RsvgHandle *, RsvgDimensionData *));
+DEF_DLL_FN (gboolean, rsvg_handle_write,
+           (RsvgHandle *, const guchar *, gsize, GError **));
+DEF_DLL_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
+DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
+DEF_DLL_FN (void, rsvg_handle_set_base_uri, (RsvgHandle *, const char *));
+
+DEF_DLL_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
+DEF_DLL_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
+DEF_DLL_FN (guchar *, gdk_pixbuf_get_pixels, (const GdkPixbuf *));
+DEF_DLL_FN (int, gdk_pixbuf_get_rowstride, (const GdkPixbuf *));
+DEF_DLL_FN (GdkColorspace, gdk_pixbuf_get_colorspace, (const GdkPixbuf *));
+DEF_DLL_FN (int, gdk_pixbuf_get_n_channels, (const GdkPixbuf *));
+DEF_DLL_FN (gboolean, gdk_pixbuf_get_has_alpha, (const GdkPixbuf *));
+DEF_DLL_FN (int, gdk_pixbuf_get_bits_per_sample, (const GdkPixbuf *));
+
+#  if ! GLIB_CHECK_VERSION (2, 36, 0)
+DEF_DLL_FN (void, g_type_init, (void));
+#  endif
+DEF_DLL_FN (void, g_object_unref, (gpointer));
+DEF_DLL_FN (void, g_error_free, (GError *));
 
 Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
 
@@ -8712,54 +8755,71 @@ init_svg_functions (void)
       return 0;
     }
 
-  LOAD_IMGLIB_FN (library, rsvg_handle_new);
-  LOAD_IMGLIB_FN (library, rsvg_handle_get_dimensions);
-  LOAD_IMGLIB_FN (library, rsvg_handle_write);
-  LOAD_IMGLIB_FN (library, rsvg_handle_close);
-  LOAD_IMGLIB_FN (library, rsvg_handle_get_pixbuf);
-
-  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_width);
-  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_height);
-  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_pixels);
-  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_rowstride);
-  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_colorspace);
-  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_n_channels);
-  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_has_alpha);
-  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_bits_per_sample);
-
-#if ! GLIB_CHECK_VERSION (2, 36, 0)
-  LOAD_IMGLIB_FN (gobject, g_type_init);
-#endif
-  LOAD_IMGLIB_FN (gobject, g_object_unref);
-  LOAD_IMGLIB_FN (glib, g_error_free);
+  LOAD_DLL_FN (library, rsvg_handle_new);
+  LOAD_DLL_FN (library, rsvg_handle_get_dimensions);
+  LOAD_DLL_FN (library, rsvg_handle_write);
+  LOAD_DLL_FN (library, rsvg_handle_close);
+  LOAD_DLL_FN (library, rsvg_handle_get_pixbuf);
+  LOAD_DLL_FN (library, rsvg_handle_set_base_uri);
+
+  LOAD_DLL_FN (gdklib, gdk_pixbuf_get_width);
+  LOAD_DLL_FN (gdklib, gdk_pixbuf_get_height);
+  LOAD_DLL_FN (gdklib, gdk_pixbuf_get_pixels);
+  LOAD_DLL_FN (gdklib, gdk_pixbuf_get_rowstride);
+  LOAD_DLL_FN (gdklib, gdk_pixbuf_get_colorspace);
+  LOAD_DLL_FN (gdklib, gdk_pixbuf_get_n_channels);
+  LOAD_DLL_FN (gdklib, gdk_pixbuf_get_has_alpha);
+  LOAD_DLL_FN (gdklib, gdk_pixbuf_get_bits_per_sample);
+
+#  if ! GLIB_CHECK_VERSION (2, 36, 0)
+  LOAD_DLL_FN (gobject, g_type_init);
+#  endif
+  LOAD_DLL_FN (gobject, g_object_unref);
+  LOAD_DLL_FN (glib, g_error_free);
 
   return 1;
 }
 
-#else
 /* The following aliases for library functions allow dynamic loading
    to be used on some platforms.  */
-#define fn_rsvg_handle_new             rsvg_handle_new
-#define fn_rsvg_handle_get_dimensions   rsvg_handle_get_dimensions
-#define fn_rsvg_handle_write           rsvg_handle_write
-#define fn_rsvg_handle_close           rsvg_handle_close
-#define fn_rsvg_handle_get_pixbuf      rsvg_handle_get_pixbuf
-
-#define fn_gdk_pixbuf_get_width                  gdk_pixbuf_get_width
-#define fn_gdk_pixbuf_get_height         gdk_pixbuf_get_height
-#define fn_gdk_pixbuf_get_pixels         gdk_pixbuf_get_pixels
-#define fn_gdk_pixbuf_get_rowstride      gdk_pixbuf_get_rowstride
-#define fn_gdk_pixbuf_get_colorspace     gdk_pixbuf_get_colorspace
-#define fn_gdk_pixbuf_get_n_channels     gdk_pixbuf_get_n_channels
-#define fn_gdk_pixbuf_get_has_alpha      gdk_pixbuf_get_has_alpha
-#define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
 
-#if ! GLIB_CHECK_VERSION (2, 36, 0)
-#define fn_g_type_init                    g_type_init
-#endif
-#define fn_g_object_unref                 g_object_unref
-#define fn_g_error_free                   g_error_free
-#endif /* !WINDOWSNT  */
+#  undef gdk_pixbuf_get_bits_per_sample
+#  undef gdk_pixbuf_get_colorspace
+#  undef gdk_pixbuf_get_has_alpha
+#  undef gdk_pixbuf_get_height
+#  undef gdk_pixbuf_get_n_channels
+#  undef gdk_pixbuf_get_pixels
+#  undef gdk_pixbuf_get_rowstride
+#  undef gdk_pixbuf_get_width
+#  undef g_error_free
+#  undef g_object_unref
+#  undef g_type_init
+#  undef rsvg_handle_close
+#  undef rsvg_handle_get_dimensions
+#  undef rsvg_handle_get_pixbuf
+#  undef rsvg_handle_new
+#  undef rsvg_handle_set_base_uri
+#  undef rsvg_handle_write
+
+#  define gdk_pixbuf_get_bits_per_sample fn_gdk_pixbuf_get_bits_per_sample
+#  define gdk_pixbuf_get_colorspace fn_gdk_pixbuf_get_colorspace
+#  define gdk_pixbuf_get_has_alpha fn_gdk_pixbuf_get_has_alpha
+#  define gdk_pixbuf_get_height fn_gdk_pixbuf_get_height
+#  define gdk_pixbuf_get_n_channels fn_gdk_pixbuf_get_n_channels
+#  define gdk_pixbuf_get_pixels fn_gdk_pixbuf_get_pixels
+#  define gdk_pixbuf_get_rowstride fn_gdk_pixbuf_get_rowstride
+#  define gdk_pixbuf_get_width fn_gdk_pixbuf_get_width
+#  define g_error_free fn_g_error_free
+#  define g_object_unref fn_g_object_unref
+#  define g_type_init fn_g_type_init
+#  define rsvg_handle_close fn_rsvg_handle_close
+#  define rsvg_handle_get_dimensions fn_rsvg_handle_get_dimensions
+#  define rsvg_handle_get_pixbuf fn_rsvg_handle_get_pixbuf
+#  define rsvg_handle_new fn_rsvg_handle_new
+#  define rsvg_handle_set_base_uri fn_rsvg_handle_set_base_uri
+#  define rsvg_handle_write fn_rsvg_handle_write
+
+# endif /* !WINDOWSNT  */
 
 /* Load SVG image IMG for use on frame F.  Value is true if
    successful.  */
@@ -8793,14 +8853,14 @@ svg_load (struct frame *f, struct image *img)
          return 0;
        }
       /* If the file was slurped into memory properly, parse it.  */
-      success_p = svg_load_image (f, img, contents, size);
+      success_p = svg_load_image (f, img, contents, size, SSDATA (file));
       xfree (contents);
     }
   /* Else its not a file, its a lisp object.  Load the image from a
      lisp object rather than a file.  */
   else
     {
-      Lisp_Object data;
+      Lisp_Object data, original_filename;
 
       data = image_spec_value (img->spec, QCdata, NULL);
       if (!STRINGP (data))
@@ -8808,7 +8868,10 @@ svg_load (struct frame *f, struct image *img)
          image_error ("Invalid image data `%s'", data, Qnil);
          return 0;
        }
-      success_p = svg_load_image (f, img, SDATA (data), SBYTES (data));
+      original_filename = BVAR (current_buffer, filename);
+      success_p = svg_load_image (f, img, SDATA (data), SBYTES (data),
+                                  (NILP (original_filename) ? NULL
+                                  : SSDATA (original_filename)));
     }
 
   return success_p;
@@ -8825,7 +8888,8 @@ 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.  */
-               ptrdiff_t size)          /* Size of data in bytes.  */
+               ptrdiff_t size,          /* Size of data in bytes.  */
+               char *filename)          /* Name of SVG file being loaded.  */
 {
   RsvgHandle *rsvg_handle;
   RsvgDimensionData dimension_data;
@@ -8844,22 +8908,28 @@ svg_load_image (struct frame *f,         /* Pointer to emacs frame structure.  *
 #if ! GLIB_CHECK_VERSION (2, 36, 0)
   /* g_type_init is a glib function that must be called prior to
      using gnome type library functions (obsolete since 2.36.0).  */
-  fn_g_type_init ();
+  g_type_init ();
 #endif
 
   /* Make a handle to a new rsvg object.  */
-  rsvg_handle = fn_rsvg_handle_new ();
+  rsvg_handle = rsvg_handle_new ();
+
+  /* Set base_uri for properly handling referenced images (via 'href').
+     See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
+     (https://bugzilla.gnome.org/show_bug.cgi?id=596114). */
+  if (filename)
+    rsvg_handle_set_base_uri(rsvg_handle, filename);
 
   /* Parse the contents argument and fill in the rsvg_handle.  */
-  fn_rsvg_handle_write (rsvg_handle, contents, size, &err);
+  rsvg_handle_write (rsvg_handle, contents, size, &err);
   if (err) goto rsvg_error;
 
   /* The parsing is complete, rsvg_handle is ready to used, close it
      for further writes.  */
-  fn_rsvg_handle_close (rsvg_handle, &err);
+  rsvg_handle_close (rsvg_handle, &err);
   if (err) goto rsvg_error;
 
-  fn_rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
+  rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
   if (! check_image_size (f, dimension_data.width, dimension_data.height))
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
@@ -8868,26 +8938,26 @@ svg_load_image (struct frame *f,         /* Pointer to emacs frame structure.  *
 
   /* We can now get a valid pixel buffer from the svg file, if all
      went ok.  */
-  pixbuf = fn_rsvg_handle_get_pixbuf (rsvg_handle);
+  pixbuf = rsvg_handle_get_pixbuf (rsvg_handle);
   if (!pixbuf) goto rsvg_error;
-  fn_g_object_unref (rsvg_handle);
+  g_object_unref (rsvg_handle);
 
   /* Extract some meta data from the svg handle.  */
-  width     = fn_gdk_pixbuf_get_width (pixbuf);
-  height    = fn_gdk_pixbuf_get_height (pixbuf);
-  pixels    = fn_gdk_pixbuf_get_pixels (pixbuf);
-  rowstride = fn_gdk_pixbuf_get_rowstride (pixbuf);
+  width     = gdk_pixbuf_get_width (pixbuf);
+  height    = gdk_pixbuf_get_height (pixbuf);
+  pixels    = gdk_pixbuf_get_pixels (pixbuf);
+  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 
   /* Validate the svg meta data.  */
-  eassert (fn_gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
-  eassert (fn_gdk_pixbuf_get_n_channels (pixbuf) == 4);
-  eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf));
-  eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
+  eassert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
+  eassert (gdk_pixbuf_get_n_channels (pixbuf) == 4);
+  eassert (gdk_pixbuf_get_has_alpha (pixbuf));
+  eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
 
   /* Try to create a x pixmap to hold the svg pixmap.  */
   if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
     {
-      fn_g_object_unref (pixbuf);
+      g_object_unref (pixbuf);
       return 0;
     }
 
@@ -8944,7 +9014,7 @@ svg_load_image (struct frame *f,         /* Pointer to emacs frame structure.  *
   free_color_table ();
 #endif /* COLOR_TABLE_SUPPORT */
 
-  fn_g_object_unref (pixbuf);
+  g_object_unref (pixbuf);
 
   img->width  = width;
   img->height = height;
@@ -8959,11 +9029,11 @@ svg_load_image (struct frame *f,         /* Pointer to emacs frame structure.  *
   return 1;
 
  rsvg_error:
-  fn_g_object_unref (rsvg_handle);
+  g_object_unref (rsvg_handle);
   /* FIXME: Use error->message so the user knows what is the actual
      problem with the image.  */
   image_error ("Error parsing SVG image `%s'", img->spec, Qnil);
-  fn_g_error_free (err);
+  g_error_free (err);
   return 0;
 }