* chartab.c (ASET_RANGE, GET_SUB_CHAR_TABLE): Remove unused macros.
[bpt/emacs.git] / src / image.c
index e39c46b..c7820c3 100644 (file)
@@ -1,31 +1,26 @@
 /* Functions for image support on window system.
-   Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 1989, 1992-2011 Free Software Foundation, Inc.
 
-   This file is part of GNU Emacs.
+This file is part of GNU Emacs.
 
-   GNU Emacs is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
 
-   GNU Emacs is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
+You should have received a copy of the GNU General Public License
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
 #include <math.h>
 #include <ctype.h>
-
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 
 #ifdef HAVE_PNG
 #if defined HAVE_LIBPNG_PNG_H
@@ -94,6 +89,11 @@ typedef struct w32_bitmap_record Bitmap_Record;
    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.  */
+Lisp_Object Qlibpng_version;
 #endif /* HAVE_NTGUI */
 
 #ifdef HAVE_NS
@@ -115,17 +115,13 @@ typedef struct ns_bitmap_record Bitmap_Record;
 #define PIX_MASK_DRAW  1
 
 #define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
-#define x_defined_color(f, name, color_def, alloc)      \
+#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 */
 
 
-/* Search path for bitmap files.  */
-
-Lisp_Object Vx_bitmap_file_path;
-
 /* The symbol `postscript' identifying images of this type.  */
 
 Lisp_Object Qpostscript;
@@ -279,7 +275,7 @@ x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsi
 #ifdef HAVE_NS
   void *bitmap = ns_image_from_XBM (bits, width, height);
   if (!bitmap)
-    return -1;
+      return -1;
 #endif
 
   id = x_allocate_bitmap_record (f);
@@ -325,7 +321,7 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
   void *bitmap = ns_image_from_file (file);
 
   if (!bitmap)
-    return -1;
+      return -1;
 
 
   id = x_allocate_bitmap_record (f);
@@ -352,7 +348,7 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
     {
       if (dpyinfo->bitmaps[id].refcount
          && dpyinfo->bitmaps[id].file
-         && !strcmp (dpyinfo->bitmaps[id].file, (char *) SDATA (file)))
+         && !strcmp (dpyinfo->bitmaps[id].file, SSDATA (file)))
        {
          ++dpyinfo->bitmaps[id].refcount;
          return id + 1;
@@ -365,7 +361,7 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
     return -1;
   emacs_close (fd);
 
-  filename = (char *) SDATA (found);
+  filename = SSDATA (found);
 
   result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                            filename, &width, &height, &bitmap, &xhot, &yhot);
@@ -380,7 +376,7 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
   dpyinfo->bitmaps[id - 1].depth = 1;
   dpyinfo->bitmaps[id - 1].height = height;
   dpyinfo->bitmaps[id - 1].width = width;
-  strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
+  strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file));
 
   return id;
 #endif /* HAVE_X_WINDOWS */
@@ -552,7 +548,7 @@ x_create_bitmap_mask (struct frame *f, int id)
 
 /***********************************************************************
                            Image types
-***********************************************************************/
+ ***********************************************************************/
 
 /* Value is the number of elements of vector VECTOR.  */
 
@@ -563,14 +559,6 @@ x_create_bitmap_mask (struct frame *f, int id)
 
 static struct image_type *image_types;
 
-/* A list of symbols, one for each supported image type.  */
-
-Lisp_Object Vimage_types;
-
-/* An alist of image types and libraries that implement the type.  */
-
-Lisp_Object Vimage_library_alist;
-
 /* Cache for delayed-loading image types.  */
 
 static Lisp_Object Vimage_type_cache;
@@ -589,11 +577,6 @@ Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask, QCgeometry, QCcrop, Q
 
 Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
 
-/* Time in seconds after which images should be removed from the cache
-   if not displayed.  */
-
-Lisp_Object Vimage_cache_eviction_delay;
-
 /* Function prototypes.  */
 
 static Lisp_Object define_image_type (struct image_type *type, int loaded);
@@ -604,10 +587,10 @@ static void x_emboss (struct frame *, struct image *);
 static int x_build_heuristic_mask (struct frame *, struct image *,
                                    Lisp_Object);
 
-#define CACHE_IMAGE_TYPE(type, status)                                  \
+#define CACHE_IMAGE_TYPE(type, status) \
   do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
 
-#define ADD_IMAGE_TYPE(type)                                    \
+#define ADD_IMAGE_TYPE(type) \
   do { Vimage_types = Fcons (type, Vimage_types); } while (0)
 
 /* Define a new image type from TYPE.  This adds a copy of TYPE to
@@ -645,7 +628,7 @@ 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, Vimage_library_alist)))
+  if (NILP (Finit_image_library (symbol, Vdynamic_library_alist)))
     return 0;                  /* unimplemented */
 
   for (type = image_types; type; type = type->next)
@@ -708,23 +691,23 @@ image_error (const char *format, Lisp_Object arg1, Lisp_Object arg2)
 \f
 /***********************************************************************
                         Image specifications
-***********************************************************************/
+ ***********************************************************************/
 
 enum image_value_type
-  {
-    IMAGE_DONT_CHECK_VALUE_TYPE,
-    IMAGE_STRING_VALUE,
-    IMAGE_STRING_OR_NIL_VALUE,
-    IMAGE_SYMBOL_VALUE,
-    IMAGE_POSITIVE_INTEGER_VALUE,
-    IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
-    IMAGE_NON_NEGATIVE_INTEGER_VALUE,
-    IMAGE_ASCENT_VALUE,
-    IMAGE_INTEGER_VALUE,
-    IMAGE_FUNCTION_VALUE,
-    IMAGE_NUMBER_VALUE,
-    IMAGE_BOOL_VALUE
-  };
+{
+  IMAGE_DONT_CHECK_VALUE_TYPE,
+  IMAGE_STRING_VALUE,
+  IMAGE_STRING_OR_NIL_VALUE,
+  IMAGE_SYMBOL_VALUE,
+  IMAGE_POSITIVE_INTEGER_VALUE,
+  IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
+  IMAGE_NON_NEGATIVE_INTEGER_VALUE,
+  IMAGE_ASCENT_VALUE,
+  IMAGE_INTEGER_VALUE,
+  IMAGE_FUNCTION_VALUE,
+  IMAGE_NUMBER_VALUE,
+  IMAGE_BOOL_VALUE
+};
 
 /* Structure used when parsing image specifications.  */
 
@@ -787,7 +770,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
 
       /* Find key in KEYWORDS.  Error if not found.  */
       for (i = 0; i < nkeywords; ++i)
-       if (strcmp (keywords[i].name, SDATA (SYMBOL_NAME (key))) == 0)
+       if (strcmp (keywords[i].name, SSDATA (SYMBOL_NAME (key))) == 0)
          break;
 
       if (i == nkeywords)
@@ -998,15 +981,13 @@ or omitted means use the selected frame.  */)
 \f
 /***********************************************************************
                 Image type independent image structures
-***********************************************************************/
+ ***********************************************************************/
 
 static struct image *make_image (Lisp_Object spec, unsigned hash);
 static void free_image (struct frame *f, struct image *img);
 static int check_image_size (struct frame *f, int width, int height);
 
 #define MAX_IMAGE_SIZE 6.0
-Lisp_Object Vmax_image_size;
-
 /* Allocate and return a new image structure for image specification
    SPEC.  SPEC has a hash value of HASH.  */
 
@@ -1053,10 +1034,6 @@ free_image (struct frame *f, struct image *img)
       /* Free resources, then free IMG.  */
       img->type->free (f, img);
       xfree (img);
-
-      /* As display glyphs may still be referring to the image ID, we
-        must garbage the frame (Bug#6426).  */
-      SET_FRAME_GARBAGED (f);
     }
 }
 
@@ -1203,10 +1180,10 @@ four_corners_best (XImagePtr_or_DC ximg, int *corners,
 
 #ifdef HAVE_NTGUI
 
-#define Destroy_Image(img_dc, prev)                                     \
+#define Destroy_Image(img_dc, prev) \
   do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
 
-#define Free_Pixmap(display, pixmap)            \
+#define Free_Pixmap(display, pixmap) \
   DeleteObject (pixmap)
 
 #elif defined (HAVE_NS)
@@ -1219,10 +1196,10 @@ four_corners_best (XImagePtr_or_DC ximg, int *corners,
 
 #else
 
-#define Destroy_Image(ximg, dummy)              \
+#define Destroy_Image(ximg, dummy) \
   XDestroyImage (ximg)
 
-#define Free_Pixmap(display, pixmap)            \
+#define Free_Pixmap(display, pixmap) \
   XFreePixmap (display, pixmap)
 
 #endif /* !HAVE_NTGUI && !HAVE_NS */
@@ -1316,7 +1293,7 @@ image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_D
 \f
 /***********************************************************************
                  Helper functions for X image types
-***********************************************************************/
+ ***********************************************************************/
 
 static void x_clear_image_1 (struct frame *, struct image *, int,
                              int, int);
@@ -1389,7 +1366,7 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
 
   xassert (STRINGP (color_name));
 
-  if (x_defined_color (f, SDATA (color_name), &color, 1))
+  if (x_defined_color (f, SSDATA (color_name), &color, 1))
     {
       /* This isn't called frequently so we get away with simply
         reallocating the color vector to the needed size, here.  */
@@ -1410,7 +1387,7 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
 \f
 /***********************************************************************
                             Image Cache
-***********************************************************************/
+ ***********************************************************************/
 
 static struct image *search_image_cache (struct frame *, Lisp_Object, unsigned);
 static void cache_image (struct frame *f, struct image *img);
@@ -1475,7 +1452,12 @@ uncache_image (struct frame *f, Lisp_Object spec)
 {
   struct image *img = search_image_cache (f, spec, sxhash (spec, 0));
   if (img)
-    free_image (f, img);
+    {
+      free_image (f, img);
+      /* As display glyphs may still be referring to the image ID, we
+        must garbage the frame (Bug#6426).  */
+      SET_FRAME_GARBAGED (f);
+    }
 }
 
 
@@ -1625,9 +1607,9 @@ which is then usually a filename.  */)
 DEFUN ("image-flush", Fimage_flush, Simage_flush,
        1, 2, 0,
        doc: /* Fush the image with specification SPEC on frame FRAME.
-               This removes the image from the Emacs image cache.  If SPEC specifies
-               an image file, the next redisplay of this image will read from the
-               current contents of that file.
+This removes the image from the Emacs image cache.  If SPEC specifies
+an image file, the next redisplay of this image will read from the
+current contents of that file.
 
 FRAME nil or omitted means use the selected frame.
 FRAME t means refresh the image on all frames.  */)
@@ -1735,7 +1717,6 @@ lookup_image (struct frame *f, Lisp_Object spec)
   struct image_cache *c;
   struct image *img;
   unsigned hash;
-  struct gcpro gcpro1;
   EMACS_TIME now;
 
   /* F must be a window-system frame, and SPEC must be a valid image
@@ -1745,8 +1726,6 @@ lookup_image (struct frame *f, Lisp_Object spec)
 
   c = FRAME_IMAGE_CACHE (f);
 
-  GCPRO1 (spec);
-
   /* Look up SPEC in the hash table of the image cache.  */
   hash = sxhash (spec, 0);
   img = search_image_cache (f, spec, hash);
@@ -1838,8 +1817,6 @@ lookup_image (struct frame *f, Lisp_Object spec)
   EMACS_GET_TIME (now);
   img->timestamp = EMACS_SECS (now);
 
-  UNGCPRO;
-
   /* Value is the image id.  */
   return img->id;
 }
@@ -1914,24 +1891,25 @@ mark_image_cache (struct image_cache *c)
 \f
 /***********************************************************************
                          X / NS / W32 support code
-***********************************************************************/
+ ***********************************************************************/
 
 #ifdef HAVE_NTGUI
 
 /* Macro for defining functions that will be loaded from image DLLs.  */
-#define DEF_IMGLIB_FN(func) int (FAR CDECL *fn_##func)()
+#define DEF_IMGLIB_FN(rettype,func,args) 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;                           \
+#define LOAD_IMGLIB_FN(lib,func) {                                     \
+    fn_##func = (void *) GetProcAddress (lib, #func);                  \
+    if (!fn_##func) return 0;                                          \
   }
 
 /* Load a DLL implementing an image type.
-   The `image-library-alist' variable associates a symbol,
-   identifying an image type, to a list of possible filenames.
+   The argument LIBRARIES is usually the variable
+   `dynamic-library-alist', which associates a symbol, identifying
+   an external DLL library, to a list of possible filenames.
    The function returns NULL if no library could be loaded for
-   the given image type, or if the library was previously loaded;
+   the given symbol, or if the library was previously loaded;
    else the handle of the DLL.  */
 static HMODULE
 w32_delayed_load (Lisp_Object libraries, Lisp_Object type)
@@ -2166,7 +2144,7 @@ x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int he
 \f
 /***********************************************************************
                              File Handling
-***********************************************************************/
+ ***********************************************************************/
 
 static unsigned char *slurp_file (char *, int *);
 
@@ -2179,16 +2157,13 @@ Lisp_Object
 x_find_image_file (Lisp_Object file)
 {
   Lisp_Object file_found, search_path;
-  struct gcpro gcpro1, gcpro2;
   int fd;
 
-  file_found = Qnil;
   /* TODO I think this should use something like image-load-path
      instead.  Unfortunately, that can contain non-string elements.  */
   search_path = Fcons (Fexpand_file_name (build_string ("images"),
                                          Vdata_directory),
                       Vx_bitmap_file_path);
-  GCPRO2 (file_found, search_path);
 
   /* Try to find FILE in data-directory/images, then x-bitmap-file-path.  */
   fd = openp (search_path, file, Qnil, &file_found, Qnil);
@@ -2201,7 +2176,6 @@ x_find_image_file (Lisp_Object file)
       close (fd);
     }
 
-  UNGCPRO;
   return file_found;
 }
 
@@ -2243,7 +2217,7 @@ slurp_file (char *file, int *size)
 \f
 /***********************************************************************
                              XBM images
-***********************************************************************/
+ ***********************************************************************/
 
 static int xbm_scan (unsigned char **, unsigned char *, char *, int *);
 static int xbm_load (struct frame *f, struct image *img);
@@ -2252,68 +2226,68 @@ static int xbm_load_image (struct frame *f, struct image *img,
 static int xbm_image_p (Lisp_Object object);
 static int xbm_read_bitmap_data (struct frame *f,
                                  unsigned char *, unsigned char *,
-                                 int *, int *, unsigned char **, int);
+                                 int *, int *, char **, int);
 static int xbm_file_p (Lisp_Object);
 
 
 /* Indices of image specification fields in xbm_format, below.  */
 
 enum xbm_keyword_index
-  {
-    XBM_TYPE,
-    XBM_FILE,
-    XBM_WIDTH,
-    XBM_HEIGHT,
-    XBM_DATA,
-    XBM_FOREGROUND,
-    XBM_BACKGROUND,
-    XBM_ASCENT,
-    XBM_MARGIN,
-    XBM_RELIEF,
-    XBM_ALGORITHM,
-    XBM_HEURISTIC_MASK,
-    XBM_MASK,
-    XBM_LAST
-  };
+{
+  XBM_TYPE,
+  XBM_FILE,
+  XBM_WIDTH,
+  XBM_HEIGHT,
+  XBM_DATA,
+  XBM_FOREGROUND,
+  XBM_BACKGROUND,
+  XBM_ASCENT,
+  XBM_MARGIN,
+  XBM_RELIEF,
+  XBM_ALGORITHM,
+  XBM_HEURISTIC_MASK,
+  XBM_MASK,
+  XBM_LAST
+};
 
 /* Vector of image_keyword structures describing the format
    of valid XBM image specifications.  */
 
 static const struct image_keyword xbm_format[XBM_LAST] =
-  {
-    {":type",          IMAGE_SYMBOL_VALUE,                     1},
-    {":file",          IMAGE_STRING_VALUE,                     0},
-    {":width",         IMAGE_POSITIVE_INTEGER_VALUE,           0},
-    {":height",                IMAGE_POSITIVE_INTEGER_VALUE,           0},
-    {":data",          IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":foreground",    IMAGE_STRING_OR_NIL_VALUE,              0},
-    {":background",    IMAGE_STRING_OR_NIL_VALUE,              0},
-    {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
-    {":relief",                IMAGE_INTEGER_VALUE,                    0},
-    {":conversion",    IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":mask",          IMAGE_DONT_CHECK_VALUE_TYPE,            0}
-  };
+{
+  {":type",            IMAGE_SYMBOL_VALUE,                     1},
+  {":file",            IMAGE_STRING_VALUE,                     0},
+  {":width",           IMAGE_POSITIVE_INTEGER_VALUE,           0},
+  {":height",          IMAGE_POSITIVE_INTEGER_VALUE,           0},
+  {":data",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":foreground",      IMAGE_STRING_OR_NIL_VALUE,              0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0},
+  {":ascent",          IMAGE_ASCENT_VALUE,                     0},
+  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":relief",          IMAGE_INTEGER_VALUE,                    0},
+  {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0}
+};
 
 /* Structure describing the image type XBM.  */
 
 static struct image_type xbm_type =
-  {
-    &Qxbm,
-    xbm_image_p,
-    xbm_load,
-    x_clear_image,
-    NULL
-  };
+{
+  &Qxbm,
+  xbm_image_p,
+  xbm_load,
+  x_clear_image,
+  NULL
+};
 
 /* Tokens returned from xbm_scan.  */
 
 enum xbm_token
-  {
-    XBM_TK_IDENT = 256,
-    XBM_TK_NUMBER
-  };
+{
+  XBM_TK_IDENT = 256,
+  XBM_TK_NUMBER
+};
 
 
 /* Return non-zero if OBJECT is a valid XBM-type image specification.
@@ -2640,7 +2614,7 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
 
 static int
 xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *end,
-                     int *width, int *height, unsigned char **data,
+                     int *width, int *height, char **data,
                      int inhibit_image_error)
 {
   unsigned char *s = contents;
@@ -2648,24 +2622,24 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
   int padding_p = 0;
   int v10 = 0;
   int bytes_per_line, i, nbytes;
-  unsigned char *p;
+  char *p;
   int value;
   int LA1;
 
-#define match()                                 \
-  LA1 = xbm_scan (&s, end, buffer, &value)
+#define match() \
+     LA1 = xbm_scan (&s, end, buffer, &value)
 
-#define expect(TOKEN)                           \
-  if (LA1 != (TOKEN))                           \
-    goto failure;                               \
-  else                                          \
-    match ()
+#define expect(TOKEN)          \
+     if (LA1 != (TOKEN))       \
+       goto failure;           \
+     else                      \
+       match ()
 
 #define expect_ident(IDENT)                                    \
-  if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0)    \
-    match ();                                                   \
-  else                                                          \
-    goto failure
+     if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
+       match ();                                               \
+     else                                                      \
+       goto failure
 
   *width = *height = -1;
   if (data)
@@ -2732,7 +2706,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 = (unsigned char *) xmalloc (nbytes);
+  p = *data = (char *) xmalloc (nbytes);
 
   if (v10)
     {
@@ -2794,7 +2768,7 @@ xbm_load_image (struct frame *f, struct image *img, unsigned char *contents,
                unsigned char *end)
 {
   int rc;
-  unsigned char *data;
+  char *data;
   int success_p = 0;
 
   rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height,
@@ -2875,27 +2849,22 @@ xbm_load (struct frame *f, struct image *img)
       Lisp_Object file;
       unsigned char *contents;
       int size;
-      struct gcpro gcpro1;
 
       file = x_find_image_file (file_name);
-      GCPRO1 (file);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", file_name, Qnil);
-         UNGCPRO;
          return 0;
        }
 
-      contents = slurp_file (SDATA (file), &size);
+      contents = slurp_file (SSDATA (file), &size);
       if (contents == NULL)
        {
          image_error ("Error loading XBM image `%s'", img->spec, Qnil);
-         UNGCPRO;
          return 0;
        }
 
       success_p = xbm_load_image (f, img, contents, contents + size);
-      UNGCPRO;
     }
   else
     {
@@ -2965,9 +2934,9 @@ xbm_load (struct frame *f, struct image *img)
                }
            }
          else if (STRINGP (data))
-           bits = SDATA (data);
+           bits = SSDATA (data);
          else
-           bits = XBOOL_VECTOR (data)->data;
+           bits = (char *) XBOOL_VECTOR (data)->data;
 
 #ifdef WINDOWSNT
           {
@@ -3005,7 +2974,7 @@ xbm_load (struct frame *f, struct image *img)
 \f
 /***********************************************************************
                              XPM images
-***********************************************************************/
+ ***********************************************************************/
 
 #if defined (HAVE_XPM) || defined (HAVE_NS)
 
@@ -3044,49 +3013,49 @@ Lisp_Object Qxpm;
 /* Indices of image specification fields in xpm_format, below.  */
 
 enum xpm_keyword_index
-  {
-    XPM_TYPE,
-    XPM_FILE,
-    XPM_DATA,
-    XPM_ASCENT,
-    XPM_MARGIN,
-    XPM_RELIEF,
-    XPM_ALGORITHM,
-    XPM_HEURISTIC_MASK,
-    XPM_MASK,
-    XPM_COLOR_SYMBOLS,
-    XPM_BACKGROUND,
-    XPM_LAST
-  };
+{
+  XPM_TYPE,
+  XPM_FILE,
+  XPM_DATA,
+  XPM_ASCENT,
+  XPM_MARGIN,
+  XPM_RELIEF,
+  XPM_ALGORITHM,
+  XPM_HEURISTIC_MASK,
+  XPM_MASK,
+  XPM_COLOR_SYMBOLS,
+  XPM_BACKGROUND,
+  XPM_LAST
+};
 
 /* Vector of image_keyword structures describing the format
    of valid XPM image specifications.  */
 
 static const struct image_keyword xpm_format[XPM_LAST] =
-  {
-    {":type",          IMAGE_SYMBOL_VALUE,                     1},
-    {":file",          IMAGE_STRING_VALUE,                     0},
-    {":data",          IMAGE_STRING_VALUE,                     0},
-    {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
-    {":relief",                IMAGE_INTEGER_VALUE,                    0},
-    {":conversion",    IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":mask",          IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":background",    IMAGE_STRING_OR_NIL_VALUE,              0}
-  };
+{
+  {":type",            IMAGE_SYMBOL_VALUE,                     1},
+  {":file",            IMAGE_STRING_VALUE,                     0},
+  {":data",            IMAGE_STRING_VALUE,                     0},
+  {":ascent",          IMAGE_ASCENT_VALUE,                     0},
+  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":relief",          IMAGE_INTEGER_VALUE,                    0},
+  {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":color-symbols",   IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
+};
 
 /* Structure describing the image type XPM.  */
 
 static struct image_type xpm_type =
-  {
-    &Qxpm,
-    xpm_image_p,
-    xpm_load,
-    x_clear_image,
-    NULL
-  };
+{
+  &Qxpm,
+  xpm_image_p,
+  xpm_load,
+  x_clear_image,
+  NULL
+};
 
 #ifdef HAVE_X_WINDOWS
 
@@ -3282,10 +3251,12 @@ xpm_free_colors (Display *dpy, Colormap cmap, Pixel *pixels, int npixels, void *
 
 /* XPM library details.  */
 
-DEF_IMGLIB_FN (XpmFreeAttributes);
-DEF_IMGLIB_FN (XpmCreateImageFromBuffer);
-DEF_IMGLIB_FN (XpmReadFileToImage);
-DEF_IMGLIB_FN (XImageFree);
+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 *));
 
 static int
 init_xpm_functions (Lisp_Object libraries)
@@ -3346,7 +3317,7 @@ xpm_image_p (Lisp_Object object)
 
 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
 int
-x_create_bitmap_from_xpm_data (struct frame *f, char **bits)
+x_create_bitmap_from_xpm_data (struct frame *f, const char **bits)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   int id, rc;
@@ -3361,7 +3332,7 @@ x_create_bitmap_from_xpm_data (struct frame *f, char **bits)
   attrs.valuemask |= XpmColormap;
 
   rc = XpmCreatePixmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                               bits, &bitmap, &mask, &attrs);
+                               (char **) bits, &bitmap, &mask, &attrs);
   if (rc != XpmSuccess)
     {
       XpmFreeAttributes (&attrs);
@@ -3456,12 +3427,31 @@ xpm_load (struct frame *f, struct image *img)
           CONSP (tail);
           ++i, tail = XCDR (tail))
        {
-         Lisp_Object name = XCAR (XCAR (tail));
-         Lisp_Object color = XCDR (XCAR (tail));
-         xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
-         strcpy (xpm_syms[i].name, SDATA (name));
-         xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
-         strcpy (xpm_syms[i].value, SDATA (color));
+         Lisp_Object name;
+         Lisp_Object color;
+
+         if (!CONSP (XCAR (tail)))
+           {
+             xpm_syms[i].name = "";
+             xpm_syms[i].value = "";
+             continue;
+           }
+         name = XCAR (XCAR (tail));
+         color = XCDR (XCAR (tail));
+         if (STRINGP (name))
+           {
+             xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
+             strcpy (xpm_syms[i].name, SSDATA (name));
+           }
+         else
+           xpm_syms[i].name = "";
+         if (STRINGP (color))
+           {
+             xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
+             strcpy (xpm_syms[i].value, SSDATA (color));
+           }
+         else
+           xpm_syms[i].value = "";
        }
     }
 
@@ -3487,6 +3477,9 @@ xpm_load (struct frame *f, struct image *img)
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
+#ifdef ALLOC_XPM_COLORS
+         xpm_free_color_cache ();
+#endif
          return 0;
        }
 
@@ -3498,13 +3491,21 @@ xpm_load (struct frame *f, struct image *img)
                                  &attrs);
 #else
       rc = XpmReadFileToPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                               SDATA (file), &img->pixmap, &img->mask,
+                               SSDATA (file), &img->pixmap, &img->mask,
                                &attrs);
 #endif /* HAVE_NTGUI */
     }
   else
     {
       Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
+      if (!STRINGP (buffer))
+       {
+         image_error ("Invalid image data `%s'", buffer, Qnil);
+#ifdef ALLOC_XPM_COLORS
+         xpm_free_color_cache ();
+#endif
+         return 0;
+       }
 #ifdef HAVE_NTGUI
       /* XpmCreatePixmapFromBuffer is not available in the Windows port
         of libxpm.  But XpmCreateImageFromBuffer almost does what we want.  */
@@ -3513,7 +3514,7 @@ xpm_load (struct frame *f, struct image *img)
                                        &attrs);
 #else
       rc = XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                                     SDATA (buffer),
+                                     SSDATA (buffer),
                                      &img->pixmap, &img->mask,
                                      &attrs);
 #endif /* HAVE_NTGUI */
@@ -3645,11 +3646,11 @@ static int xpm_load_image (struct frame *, struct image *,
 /* Tokens returned from xpm_scan.  */
 
 enum xpm_token
-  {
-    XPM_TK_IDENT = 256,
-    XPM_TK_STRING,
-    XPM_TK_EOF
-  };
+{
+  XPM_TK_IDENT = 256,
+  XPM_TK_STRING,
+  XPM_TK_EOF
+};
 
 /* Scan an XPM data and return a character (< 256) or a token defined
    by enum xpm_token above.  *S and END are the start (inclusive) and
@@ -3679,7 +3680,7 @@ xpm_scan (const unsigned char **s,
          *beg = *s - 1;
          while (*s < end
                 && (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
-            ++*s;
+             ++*s;
          *len = *s - *beg;
          return XPM_TK_IDENT;
        }
@@ -3839,21 +3840,21 @@ xpm_load_image (struct frame *f,
   int best_key, have_mask = 0;
   XImagePtr ximg = NULL, mask_img = NULL;
 
-#define match()                                 \
-  LA1 = xpm_scan (&s, end, &beg, &len)
+#define match() \
+     LA1 = xpm_scan (&s, end, &beg, &len)
 
-#define expect(TOKEN)                           \
-  if (LA1 != (TOKEN))                           \
-    goto failure;                               \
-  else                                          \
-    match ()
+#define expect(TOKEN)          \
+     if (LA1 != (TOKEN))       \
+       goto failure;           \
+     else                      \
+       match ()
 
-#define expect_ident(IDENT)                                             \
-  if (LA1 == XPM_TK_IDENT                                               \
-      && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0)   \
-    match ();                                                           \
-  else                                                                  \
-    goto failure
+#define expect_ident(IDENT)                                    \
+     if (LA1 == XPM_TK_IDENT \
+         && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0)        \
+       match ();                                               \
+     else                                                      \
+       goto failure
 
   if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0))
     goto failure;
@@ -3905,7 +3906,7 @@ xpm_load_image (struct frame *f,
 
   while (num_colors-- > 0)
     {
-      unsigned char *color, *max_color;
+      char *color, *max_color;
       int key, next_key, max_key = 0;
       Lisp_Object symbol_color = Qnil, color_val;
       XColor cdef;
@@ -3957,7 +3958,7 @@ xpm_load_image (struct frame *f,
 
          if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
            {
-             if (xstrcasecmp (SDATA (XCDR (specified_color)), "None") == 0)
+             if (xstrcasecmp (SSDATA (XCDR (specified_color)), "None") == 0)
                color_val = Qt;
              else if (x_defined_color (f, SDATA (XCDR (specified_color)),
                                        &cdef, 0))
@@ -4071,14 +4072,11 @@ xpm_load (struct frame *f,
       Lisp_Object file;
       unsigned char *contents;
       int size;
-      struct gcpro gcpro1;
 
       file = x_find_image_file (file_name);
-      GCPRO1 (file);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", file_name, Qnil);
-         UNGCPRO;
          return 0;
        }
 
@@ -4086,19 +4084,22 @@ xpm_load (struct frame *f,
       if (contents == NULL)
        {
          image_error ("Error loading XPM image `%s'", img->spec, Qnil);
-         UNGCPRO;
          return 0;
        }
 
       success_p = xpm_load_image (f, img, contents, contents + size);
       xfree (contents);
-      UNGCPRO;
     }
   else
     {
       Lisp_Object data;
 
       data = image_spec_value (img->spec, QCdata, NULL);
+      if (!STRINGP (data))
+       {
+         image_error ("Invalid image data `%s'", data, Qnil);
+         return 0;
+       }
       success_p = xpm_load_image (f, img, SDATA (data),
                                  SDATA (data) + SBYTES (data));
     }
@@ -4112,7 +4113,7 @@ xpm_load (struct frame *f,
 \f
 /***********************************************************************
                             Color table
-***********************************************************************/
+ ***********************************************************************/
 
 #ifdef COLOR_TABLE_SUPPORT
 
@@ -4379,7 +4380,7 @@ init_color_table (void)
 \f
 /***********************************************************************
                              Algorithms
-***********************************************************************/
+ ***********************************************************************/
 
 static XColor *x_to_xcolors (struct frame *, struct image *, int);
 static void x_from_xcolors (struct frame *, struct image *, XColor *);
@@ -4389,26 +4390,21 @@ static void x_detect_edges (struct frame *, struct image *, int[9], int);
 static void XPutPixel (XImagePtr , int, int, COLORREF);
 #endif /* HAVE_NTGUI */
 
-/* Non-zero means draw a cross on images having `:conversion
-   disabled'.  */
-
-int cross_disabled_images;
-
 /* Edge detection matrices for different edge-detection
    strategies.  */
 
 static int emboss_matrix[9] = {
-  /* x - 1     x       x + 1  */
-  2,     -1,     0,            /* y - 1 */
-  -1,      0,        1,                /* y     */
-  0,      1,       -2          /* y + 1 */
+   /* x - 1    x       x + 1  */
+        2,     -1,       0,            /* y - 1 */
+       -1,      0,        1,           /* y     */
+        0,      1,       -2            /* y + 1 */
 };
 
 static int laplace_matrix[9] = {
-  /* x - 1     x       x + 1  */
-  1,      0,     0,            /* y - 1 */
-  0,      0,        0,         /* y     */
-  0,      0,       -1          /* y + 1 */
+   /* x - 1    x       x + 1  */
+        1,      0,       0,            /* y - 1 */
+        0,      0,        0,           /* y     */
+        0,      0,       -1            /* y + 1 */
 };
 
 /* Value is the intensity of the color whose red/green/blue values
@@ -4928,7 +4924,7 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
 \f
 /***********************************************************************
                       PBM (mono, gray, color)
-***********************************************************************/
+ ***********************************************************************/
 
 static int pbm_image_p (Lisp_Object object);
 static int pbm_load (struct frame *f, struct image *img);
@@ -4941,49 +4937,49 @@ Lisp_Object Qpbm;
 /* Indices of image specification fields in gs_format, below.  */
 
 enum pbm_keyword_index
-  {
-    PBM_TYPE,
-    PBM_FILE,
-    PBM_DATA,
-    PBM_ASCENT,
-    PBM_MARGIN,
-    PBM_RELIEF,
-    PBM_ALGORITHM,
-    PBM_HEURISTIC_MASK,
-    PBM_MASK,
-    PBM_FOREGROUND,
-    PBM_BACKGROUND,
-    PBM_LAST
-  };
+{
+  PBM_TYPE,
+  PBM_FILE,
+  PBM_DATA,
+  PBM_ASCENT,
+  PBM_MARGIN,
+  PBM_RELIEF,
+  PBM_ALGORITHM,
+  PBM_HEURISTIC_MASK,
+  PBM_MASK,
+  PBM_FOREGROUND,
+  PBM_BACKGROUND,
+  PBM_LAST
+};
 
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
 static const struct image_keyword pbm_format[PBM_LAST] =
-  {
-    {":type",          IMAGE_SYMBOL_VALUE,                     1},
-    {":file",          IMAGE_STRING_VALUE,                     0},
-    {":data",          IMAGE_STRING_VALUE,                     0},
-    {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
-    {":relief",                IMAGE_INTEGER_VALUE,                    0},
-    {":conversion",    IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":mask",          IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":foreground",    IMAGE_STRING_OR_NIL_VALUE,              0},
-    {":background",    IMAGE_STRING_OR_NIL_VALUE,              0}
-  };
+{
+  {":type",            IMAGE_SYMBOL_VALUE,                     1},
+  {":file",            IMAGE_STRING_VALUE,                     0},
+  {":data",            IMAGE_STRING_VALUE,                     0},
+  {":ascent",          IMAGE_ASCENT_VALUE,                     0},
+  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":relief",          IMAGE_INTEGER_VALUE,                    0},
+  {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":foreground",      IMAGE_STRING_OR_NIL_VALUE,              0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
+};
 
 /* Structure describing the image type `pbm'.  */
 
 static struct image_type pbm_type =
-  {
-    &Qpbm,
-    pbm_image_p,
-    pbm_load,
-    x_clear_image,
-    NULL
-  };
+{
+  &Qpbm,
+  pbm_image_p,
+  pbm_load,
+  x_clear_image,
+  NULL
+};
 
 
 /* Return non-zero if OBJECT is a valid PBM image specification.  */
@@ -5090,14 +5086,11 @@ pbm_load (struct frame *f, struct image *img)
   XImagePtr ximg;
   Lisp_Object file, specified_file;
   enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
-  struct gcpro gcpro1;
   unsigned char *contents = NULL;
   unsigned char *end, *p;
   int size;
 
   specified_file = image_spec_value (img->spec, QCfile, NULL);
-  file = Qnil;
-  GCPRO1 (file);
 
   if (STRINGP (specified_file))
     {
@@ -5105,15 +5098,13 @@ pbm_load (struct frame *f, struct image *img)
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
-         UNGCPRO;
          return 0;
        }
 
-      contents = slurp_file (SDATA (file), &size);
+      contents = slurp_file (SSDATA (file), &size);
       if (contents == NULL)
        {
          image_error ("Error reading `%s'", file, Qnil);
-         UNGCPRO;
          return 0;
        }
 
@@ -5124,6 +5115,11 @@ pbm_load (struct frame *f, struct image *img)
     {
       Lisp_Object data;
       data = image_spec_value (img->spec, QCdata, NULL);
+      if (!STRINGP (data))
+       {
+         image_error ("Invalid image data `%s'", data, Qnil);
+         return 0;
+       }
       p = SDATA (data);
       end = p + SBYTES (data);
     }
@@ -5134,7 +5130,6 @@ pbm_load (struct frame *f, struct image *img)
       image_error ("Not a PBM image: `%s'", img->spec, Qnil);
     error:
       xfree (contents);
-      UNGCPRO;
       return 0;
     }
 
@@ -5336,7 +5331,6 @@ pbm_load (struct frame *f, struct image *img)
      img->width = width;
      img->height = height; */
 
-  UNGCPRO;
   xfree (contents);
   return 1;
 }
@@ -5344,7 +5338,7 @@ pbm_load (struct frame *f, struct image *img)
 \f
 /***********************************************************************
                                 PNG
-***********************************************************************/
+ ***********************************************************************/
 
 #if defined (HAVE_PNG) || defined (HAVE_NS)
 
@@ -5360,47 +5354,47 @@ Lisp_Object Qpng;
 /* Indices of image specification fields in png_format, below.  */
 
 enum png_keyword_index
-  {
-    PNG_TYPE,
-    PNG_DATA,
-    PNG_FILE,
-    PNG_ASCENT,
-    PNG_MARGIN,
-    PNG_RELIEF,
-    PNG_ALGORITHM,
-    PNG_HEURISTIC_MASK,
-    PNG_MASK,
-    PNG_BACKGROUND,
-    PNG_LAST
-  };
+{
+  PNG_TYPE,
+  PNG_DATA,
+  PNG_FILE,
+  PNG_ASCENT,
+  PNG_MARGIN,
+  PNG_RELIEF,
+  PNG_ALGORITHM,
+  PNG_HEURISTIC_MASK,
+  PNG_MASK,
+  PNG_BACKGROUND,
+  PNG_LAST
+};
 
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
 static const struct image_keyword png_format[PNG_LAST] =
-  {
-    {":type",          IMAGE_SYMBOL_VALUE,                     1},
-    {":data",          IMAGE_STRING_VALUE,                     0},
-    {":file",          IMAGE_STRING_VALUE,                     0},
-    {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
-    {":relief",                IMAGE_INTEGER_VALUE,                    0},
-    {":conversion",    IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":mask",          IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":background",    IMAGE_STRING_OR_NIL_VALUE,              0}
-  };
+{
+  {":type",            IMAGE_SYMBOL_VALUE,                     1},
+  {":data",            IMAGE_STRING_VALUE,                     0},
+  {":file",            IMAGE_STRING_VALUE,                     0},
+  {":ascent",          IMAGE_ASCENT_VALUE,                     0},
+  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":relief",          IMAGE_INTEGER_VALUE,                    0},
+  {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
+};
 
 /* Structure describing the image type `png'.  */
 
 static struct image_type png_type =
-  {
-    &Qpng,
-    png_image_p,
-    png_load,
-    x_clear_image,
-    NULL
-  };
+{
+  &Qpng,
+  png_image_p,
+  png_load,
+  x_clear_image,
+  NULL
+};
 
 /* Return non-zero if OBJECT is a valid PNG image specification.  */
 
@@ -5425,27 +5419,36 @@ png_image_p (Lisp_Object object)
 #ifdef HAVE_NTGUI
 /* PNG library details.  */
 
-DEF_IMGLIB_FN (png_get_io_ptr);
-DEF_IMGLIB_FN (png_sig_cmp);
-DEF_IMGLIB_FN (png_create_read_struct);
-DEF_IMGLIB_FN (png_create_info_struct);
-DEF_IMGLIB_FN (png_destroy_read_struct);
-DEF_IMGLIB_FN (png_set_read_fn);
-DEF_IMGLIB_FN (png_set_sig_bytes);
-DEF_IMGLIB_FN (png_read_info);
-DEF_IMGLIB_FN (png_get_IHDR);
-DEF_IMGLIB_FN (png_get_valid);
-DEF_IMGLIB_FN (png_set_strip_16);
-DEF_IMGLIB_FN (png_set_expand);
-DEF_IMGLIB_FN (png_set_gray_to_rgb);
-DEF_IMGLIB_FN (png_set_background);
-DEF_IMGLIB_FN (png_get_bKGD);
-DEF_IMGLIB_FN (png_read_update_info);
-DEF_IMGLIB_FN (png_get_channels);
-DEF_IMGLIB_FN (png_get_rowbytes);
-DEF_IMGLIB_FN (png_read_image);
-DEF_IMGLIB_FN (png_read_end);
-DEF_IMGLIB_FN (png_error);
+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));
+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)
@@ -5477,6 +5480,12 @@ init_png_functions (Lisp_Object libraries)
   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 */
+
   return 1;
 }
 #else
@@ -5503,8 +5512,24 @@ init_png_functions (Lisp_Object libraries)
 #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 /* HAVE_NTGUI */
 
+
+#if (PNG_LIBPNG_VER < 10500)
+#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)))
+#endif
+
 /* Error and warning handlers installed when the PNG library
    is initialized.  */
 
@@ -5512,8 +5537,10 @@ static void
 my_png_error (png_struct *png_ptr, const char *msg)
 {
   xassert (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);
-  longjmp (png_ptr->jmpbuf, 1);
+  PNG_LONGJMP (png_ptr);
 }
 
 
@@ -5576,7 +5603,6 @@ png_load (struct frame *f, struct image *img)
   Lisp_Object specified_data;
   int x, y, i;
   XImagePtr ximg, mask_img = NULL;
-  struct gcpro gcpro1;
   png_struct *png_ptr = NULL;
   png_info *info_ptr = NULL, *end_info = NULL;
   FILE *volatile fp = NULL;
@@ -5593,8 +5619,6 @@ png_load (struct frame *f, struct image *img)
   /* Find out what file to load.  */
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
-  file = Qnil;
-  GCPRO1 (file);
 
   if (NILP (specified_data))
     {
@@ -5602,16 +5626,14 @@ png_load (struct frame *f, struct image *img)
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
-         UNGCPRO;
          return 0;
        }
 
       /* Open the image file.  */
-      fp = fopen (SDATA (file), "rb");
+      fp = fopen (SSDATA (file), "rb");
       if (!fp)
        {
          image_error ("Cannot open image file `%s'", file, Qnil);
-         UNGCPRO;
          return 0;
        }
 
@@ -5620,13 +5642,18 @@ png_load (struct frame *f, struct image *img)
          || fn_png_sig_cmp (sig, 0, sizeof sig))
        {
          image_error ("Not a PNG file: `%s'", file, Qnil);
-         UNGCPRO;
          fclose (fp);
          return 0;
        }
     }
   else
     {
+      if (!STRINGP (specified_data))
+       {
+         image_error ("Invalid image data `%s'", specified_data, Qnil);
+         return 0;
+       }
+
       /* Read from memory.  */
       tbr.bytes = SDATA (specified_data);
       tbr.len = SBYTES (specified_data);
@@ -5637,7 +5664,6 @@ png_load (struct frame *f, struct image *img)
          || fn_png_sig_cmp (tbr.bytes, 0, sizeof sig))
        {
          image_error ("Not a PNG image: `%s'", img->spec, Qnil);
-         UNGCPRO;
          return 0;
        }
 
@@ -5645,41 +5671,35 @@ png_load (struct frame *f, struct image *img)
       tbr.bytes += sizeof (sig);
     }
 
-  /* Initialize read and info structs for PNG lib.  Casting return
-     value avoids a GCC warning on W32.  */
-  png_ptr = (png_structp)fn_png_create_read_struct (PNG_LIBPNG_VER_STRING,
-                                                   NULL, my_png_error,
-                                                   my_png_warning);
+  /* Initialize read and info structs for PNG lib.  */
+  png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING,
+                                      NULL, my_png_error,
+                                      my_png_warning);
   if (!png_ptr)
     {
       if (fp) fclose (fp);
-      UNGCPRO;
       return 0;
     }
 
-  /* Casting return value avoids a GCC warning on W32.  */
-  info_ptr = (png_infop)fn_png_create_info_struct (png_ptr);
+  info_ptr = fn_png_create_info_struct (png_ptr);
   if (!info_ptr)
     {
       fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
       if (fp) fclose (fp);
-      UNGCPRO;
       return 0;
     }
 
-  /* Casting return value avoids a GCC warning on W32.  */
-  end_info = (png_infop)fn_png_create_info_struct (png_ptr);
+  end_info = fn_png_create_info_struct (png_ptr);
   if (!end_info)
     {
       fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
       if (fp) fclose (fp);
-      UNGCPRO;
       return 0;
     }
 
   /* Set error jump-back.  We come back here when the PNG library
      detects an error.  */
-  if (setjmp (png_ptr->jmpbuf))
+  if (setjmp (PNG_JMPBUF (png_ptr)))
     {
     error:
       if (png_ptr)
@@ -5687,7 +5707,6 @@ png_load (struct frame *f, struct image *img)
       xfree (pixels);
       xfree (rows);
       if (fp) fclose (fp);
-      UNGCPRO;
       return 0;
     }
 
@@ -5745,7 +5764,7 @@ png_load (struct frame *f, struct image *img)
        /* The user specified `:background', use that.  */
        {
          XColor color;
-         if (x_defined_color (f, SDATA (specified_bg), &color, 0))
+         if (x_defined_color (f, SSDATA (specified_bg), &color, 0))
            {
              png_color_16 user_bg;
 
@@ -5912,7 +5931,6 @@ png_load (struct frame *f, struct image *img)
       x_destroy_x_image (mask_img);
     }
 
-  UNGCPRO;
   return 1;
 }
 
@@ -5935,7 +5953,7 @@ png_load (struct frame *f, struct image *img)
 \f
 /***********************************************************************
                                 JPEG
-***********************************************************************/
+ ***********************************************************************/
 
 #if defined (HAVE_JPEG) || defined (HAVE_NS)
 
@@ -5949,47 +5967,47 @@ Lisp_Object Qjpeg;
 /* Indices of image specification fields in gs_format, below.  */
 
 enum jpeg_keyword_index
-  {
-    JPEG_TYPE,
-    JPEG_DATA,
-    JPEG_FILE,
-    JPEG_ASCENT,
-    JPEG_MARGIN,
-    JPEG_RELIEF,
-    JPEG_ALGORITHM,
-    JPEG_HEURISTIC_MASK,
-    JPEG_MASK,
-    JPEG_BACKGROUND,
-    JPEG_LAST
-  };
+{
+  JPEG_TYPE,
+  JPEG_DATA,
+  JPEG_FILE,
+  JPEG_ASCENT,
+  JPEG_MARGIN,
+  JPEG_RELIEF,
+  JPEG_ALGORITHM,
+  JPEG_HEURISTIC_MASK,
+  JPEG_MASK,
+  JPEG_BACKGROUND,
+  JPEG_LAST
+};
 
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
 static const struct image_keyword jpeg_format[JPEG_LAST] =
-  {
-    {":type",          IMAGE_SYMBOL_VALUE,                     1},
-    {":data",          IMAGE_STRING_VALUE,                     0},
-    {":file",          IMAGE_STRING_VALUE,                     0},
-    {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
-    {":relief",                IMAGE_INTEGER_VALUE,                    0},
-    {":conversions",   IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":mask",          IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":background",    IMAGE_STRING_OR_NIL_VALUE,              0}
-  };
+{
+  {":type",            IMAGE_SYMBOL_VALUE,                     1},
+  {":data",            IMAGE_STRING_VALUE,                     0},
+  {":file",            IMAGE_STRING_VALUE,                     0},
+  {":ascent",          IMAGE_ASCENT_VALUE,                     0},
+  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":relief",          IMAGE_INTEGER_VALUE,                    0},
+  {":conversions",     IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
+};
 
 /* Structure describing the image type `jpeg'.  */
 
 static struct image_type jpeg_type =
-  {
-    &Qjpeg,
-    jpeg_image_p,
-    jpeg_load,
-    x_clear_image,
-    NULL
-  };
+{
+  &Qjpeg,
+  jpeg_image_p,
+  jpeg_load,
+  x_clear_image,
+  NULL
+};
 
 /* Return non-zero if OBJECT is a valid JPEG image specification.  */
 
@@ -6034,14 +6052,14 @@ jpeg_image_p (Lisp_Object object)
 #ifdef HAVE_NTGUI
 
 /* JPEG library details.  */
-DEF_IMGLIB_FN (jpeg_CreateDecompress);
-DEF_IMGLIB_FN (jpeg_start_decompress);
-DEF_IMGLIB_FN (jpeg_finish_decompress);
-DEF_IMGLIB_FN (jpeg_destroy_decompress);
-DEF_IMGLIB_FN (jpeg_read_header);
-DEF_IMGLIB_FN (jpeg_read_scanlines);
-DEF_IMGLIB_FN (jpeg_std_error);
-DEF_IMGLIB_FN (jpeg_resync_to_restart);
+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));
 
 static int
 init_jpeg_functions (Lisp_Object libraries)
@@ -6271,7 +6289,7 @@ jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
   struct jpeg_stdio_mgr *src;
 
   if (cinfo->src != NULL)
-    src = (struct jpeg_stdio_mgr *) cinfo->src;
+      src = (struct jpeg_stdio_mgr *) cinfo->src;
   else
     {
       /* First time for this JPEG object?  */
@@ -6280,8 +6298,8 @@ jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
                                     sizeof (struct jpeg_stdio_mgr));
       src = (struct jpeg_stdio_mgr *) cinfo->src;
       src->buffer = (JOCTET *)
-        (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
-                                    JPEG_STDIO_BUFFER_SIZE);
+          (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+                                      JPEG_STDIO_BUFFER_SIZE);
     }
 
   src->file = fp;
@@ -6313,13 +6331,10 @@ jpeg_load (struct frame *f, struct image *img)
   int rc;
   unsigned long *colors;
   int width, height;
-  struct gcpro gcpro1;
 
   /* Open the JPEG file.  */
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
-  file = Qnil;
-  GCPRO1 (file);
 
   if (NILP (specified_data))
     {
@@ -6327,23 +6342,25 @@ jpeg_load (struct frame *f, struct image *img)
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
-         UNGCPRO;
          return 0;
        }
 
-      fp = fopen (SDATA (file), "rb");
+      fp = fopen (SSDATA (file), "rb");
       if (fp == NULL)
        {
          image_error ("Cannot open `%s'", file, Qnil);
-         UNGCPRO;
          return 0;
        }
     }
+  else if (!STRINGP (specified_data))
+    {
+      image_error ("Invalid image data `%s'", specified_data, Qnil);
+      return 0;
+    }
 
   /* Customize libjpeg's error handling to call my_error_exit when an
-     error is detected.  This function will perform a longjmp.
-     Casting return value avoids a GCC warning on W32.  */
-  cinfo.err = (struct jpeg_error_mgr *)fn_jpeg_std_error (&mgr.pub);
+     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)
@@ -6367,13 +6384,11 @@ jpeg_load (struct frame *f, struct image *img)
 
       /* Free pixmap and colors.  */
       x_clear_image (f, img);
-
-      UNGCPRO;
       return 0;
     }
 
   /* Create the JPEG decompression object.  Let it read from fp.
-     Read the JPEG image header.  */
+        Read the JPEG image header.  */
   fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo));
 
   if (NILP (specified_data))
@@ -6385,7 +6400,7 @@ jpeg_load (struct frame *f, struct image *img)
   fn_jpeg_read_header (&cinfo, 1);
 
   /* Customize decompression so that color quantization will be used.
-     Start decompression.  */
+        Start decompression.  */
   cinfo.quantize_colors = 1;
   fn_jpeg_start_decompress (&cinfo);
   width = img->width = cinfo.output_width;
@@ -6466,7 +6481,6 @@ jpeg_load (struct frame *f, struct image *img)
   /* Put the image into the pixmap.  */
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
-  UNGCPRO;
   return 1;
 }
 
@@ -6488,7 +6502,7 @@ jpeg_load (struct frame *f, struct image *img)
 \f
 /***********************************************************************
                                 TIFF
-***********************************************************************/
+ ***********************************************************************/
 
 #if defined (HAVE_TIFF) || defined (HAVE_NS)
 
@@ -6502,49 +6516,49 @@ Lisp_Object Qtiff;
 /* Indices of image specification fields in tiff_format, below.  */
 
 enum tiff_keyword_index
-  {
-    TIFF_TYPE,
-    TIFF_DATA,
-    TIFF_FILE,
-    TIFF_ASCENT,
-    TIFF_MARGIN,
-    TIFF_RELIEF,
-    TIFF_ALGORITHM,
-    TIFF_HEURISTIC_MASK,
-    TIFF_MASK,
-    TIFF_BACKGROUND,
-    TIFF_INDEX,
-    TIFF_LAST
-  };
+{
+  TIFF_TYPE,
+  TIFF_DATA,
+  TIFF_FILE,
+  TIFF_ASCENT,
+  TIFF_MARGIN,
+  TIFF_RELIEF,
+  TIFF_ALGORITHM,
+  TIFF_HEURISTIC_MASK,
+  TIFF_MASK,
+  TIFF_BACKGROUND,
+  TIFF_INDEX,
+  TIFF_LAST
+};
 
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
 static const struct image_keyword tiff_format[TIFF_LAST] =
-  {
-    {":type",          IMAGE_SYMBOL_VALUE,                     1},
-    {":data",          IMAGE_STRING_VALUE,                     0},
-    {":file",          IMAGE_STRING_VALUE,                     0},
-    {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
-    {":relief",                IMAGE_INTEGER_VALUE,                    0},
-    {":conversions",   IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":mask",          IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":background",    IMAGE_STRING_OR_NIL_VALUE,              0},
-    {":index",         IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0}
-  };
+{
+  {":type",            IMAGE_SYMBOL_VALUE,                     1},
+  {":data",            IMAGE_STRING_VALUE,                     0},
+  {":file",            IMAGE_STRING_VALUE,                     0},
+  {":ascent",          IMAGE_ASCENT_VALUE,                     0},
+  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":relief",          IMAGE_INTEGER_VALUE,                    0},
+  {":conversions",     IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0},
+  {":index",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0}
+};
 
 /* Structure describing the image type `tiff'.  */
 
 static struct image_type tiff_type =
-  {
-    &Qtiff,
-    tiff_image_p,
-    tiff_load,
-    x_clear_image,
-    NULL
-  };
+{
+  &Qtiff,
+  tiff_image_p,
+  tiff_load,
+  x_clear_image,
+  NULL
+};
 
 /* Return non-zero if OBJECT is a valid TIFF image specification.  */
 
@@ -6570,14 +6584,17 @@ tiff_image_p (Lisp_Object object)
 #ifdef HAVE_NTGUI
 
 /* TIFF library details.  */
-DEF_IMGLIB_FN (TIFFSetErrorHandler);
-DEF_IMGLIB_FN (TIFFSetWarningHandler);
-DEF_IMGLIB_FN (TIFFOpen);
-DEF_IMGLIB_FN (TIFFClientOpen);
-DEF_IMGLIB_FN (TIFFGetField);
-DEF_IMGLIB_FN (TIFFReadRGBAImage);
-DEF_IMGLIB_FN (TIFFClose);
-DEF_IMGLIB_FN (TIFFSetDirectory);
+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));
 
 static int
 init_tiff_functions (Lisp_Object libraries)
@@ -6626,7 +6643,7 @@ typedef struct
   size_t len;
   int index;
 }
-  tiff_memory_source;
+tiff_memory_source;
 
 static size_t
 tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size)
@@ -6741,14 +6758,11 @@ tiff_load (struct frame *f, struct image *img)
   uint32 *buf;
   int rc, rc2;
   XImagePtr ximg;
-  struct gcpro gcpro1;
   tiff_memory_source memsrc;
   Lisp_Object image;
 
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
-  file = Qnil;
-  GCPRO1 (file);
 
   fn_TIFFSetErrorHandler (tiff_error_handler);
   fn_TIFFSetWarningHandler (tiff_warning_handler);
@@ -6760,41 +6774,42 @@ tiff_load (struct frame *f, struct image *img)
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
-         UNGCPRO;
          return 0;
        }
 
-      /* Try to open the image file.  Casting return value avoids a
-        GCC warning on W32.  */
-      tiff = (TIFF *)fn_TIFFOpen (SDATA (file), "r");
+      /* Try to open the image file.  */
+      tiff = fn_TIFFOpen (SSDATA (file), "r");
       if (tiff == NULL)
        {
          image_error ("Cannot open `%s'", file, Qnil);
-         UNGCPRO;
          return 0;
        }
     }
   else
     {
+      if (!STRINGP (specified_data))
+       {
+         image_error ("Invalid image data `%s'", specified_data, Qnil);
+         return 0;
+       }
+
       /* Memory source! */
       memsrc.bytes = SDATA (specified_data);
       memsrc.len = SBYTES (specified_data);
       memsrc.index = 0;
 
-      /* Casting return value avoids a GCC warning on W32.  */
-      tiff = (TIFF *)fn_TIFFClientOpen ("memory_source", "r", &memsrc,
-                                       (TIFFReadWriteProc) tiff_read_from_memory,
-                                       (TIFFReadWriteProc) tiff_write_from_memory,
-                                       tiff_seek_in_memory,
-                                       tiff_close_memory,
-                                       tiff_size_of_memory,
-                                       tiff_mmap_memory,
-                                       tiff_unmap_memory);
+      tiff = fn_TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc,
+                               (TIFFReadWriteProc) tiff_read_from_memory,
+                               (TIFFReadWriteProc) tiff_write_from_memory,
+                               tiff_seek_in_memory,
+                               tiff_close_memory,
+                               tiff_size_of_memory,
+                               tiff_mmap_memory,
+                               tiff_unmap_memory);
 
       if (!tiff)
        {
          image_error ("Cannot open memory source for `%s'", img->spec, Qnil);
-         UNGCPRO;
          return 0;
        }
     }
@@ -6808,7 +6823,6 @@ tiff_load (struct frame *f, struct image *img)
          image_error ("Invalid image number `%s' in image `%s'",
                       image, img->spec);
          fn_TIFFClose (tiff);
-         UNGCPRO;
          return 0;
        }
     }
@@ -6822,7 +6836,6 @@ tiff_load (struct frame *f, struct image *img)
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       fn_TIFFClose (tiff);
-      UNGCPRO;
       return 0;
     }
 
@@ -6844,7 +6857,6 @@ tiff_load (struct frame *f, struct image *img)
     {
       image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
       xfree (buf);
-      UNGCPRO;
       return 0;
     }
 
@@ -6852,7 +6864,6 @@ tiff_load (struct frame *f, struct image *img)
   if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
     {
       xfree (buf);
-      UNGCPRO;
       return 0;
     }
 
@@ -6893,7 +6904,6 @@ tiff_load (struct frame *f, struct image *img)
   x_destroy_x_image (ximg);
   xfree (buf);
 
-  UNGCPRO;
   return 1;
 }
 
@@ -6915,7 +6925,7 @@ tiff_load (struct frame *f, struct image *img)
 \f
 /***********************************************************************
                                 GIF
-***********************************************************************/
+ ***********************************************************************/
 
 #if defined (HAVE_GIF) || defined (HAVE_NS)
 
@@ -6930,49 +6940,49 @@ Lisp_Object Qgif;
 /* Indices of image specification fields in gif_format, below.  */
 
 enum gif_keyword_index
-  {
-    GIF_TYPE,
-    GIF_DATA,
-    GIF_FILE,
-    GIF_ASCENT,
-    GIF_MARGIN,
-    GIF_RELIEF,
-    GIF_ALGORITHM,
-    GIF_HEURISTIC_MASK,
-    GIF_MASK,
-    GIF_IMAGE,
-    GIF_BACKGROUND,
-    GIF_LAST
-  };
+{
+  GIF_TYPE,
+  GIF_DATA,
+  GIF_FILE,
+  GIF_ASCENT,
+  GIF_MARGIN,
+  GIF_RELIEF,
+  GIF_ALGORITHM,
+  GIF_HEURISTIC_MASK,
+  GIF_MASK,
+  GIF_IMAGE,
+  GIF_BACKGROUND,
+  GIF_LAST
+};
 
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
 static const struct image_keyword gif_format[GIF_LAST] =
-  {
-    {":type",          IMAGE_SYMBOL_VALUE,                     1},
-    {":data",          IMAGE_STRING_VALUE,                     0},
-    {":file",          IMAGE_STRING_VALUE,                     0},
-    {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
-    {":relief",                IMAGE_INTEGER_VALUE,                    0},
-    {":conversion",    IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":mask",          IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":index",         IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},
-    {":background",    IMAGE_STRING_OR_NIL_VALUE,              0}
-  };
+{
+  {":type",            IMAGE_SYMBOL_VALUE,                     1},
+  {":data",            IMAGE_STRING_VALUE,                     0},
+  {":file",            IMAGE_STRING_VALUE,                     0},
+  {":ascent",          IMAGE_ASCENT_VALUE,                     0},
+  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":relief",          IMAGE_INTEGER_VALUE,                    0},
+  {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":index",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
+};
 
 /* Structure describing the image type `gif'.  */
 
 static struct image_type gif_type =
-  {
-    &Qgif,
-    gif_image_p,
-    gif_load,
-    gif_clear_image,
-    NULL
-  };
+{
+  &Qgif,
+  gif_image_p,
+  gif_load,
+  gif_clear_image,
+  NULL
+};
 
 /* Free X resources of GIF image IMG which is used on frame F.  */
 
@@ -7024,10 +7034,10 @@ gif_image_p (Lisp_Object object)
 #ifdef HAVE_NTGUI
 
 /* GIF library details.  */
-DEF_IMGLIB_FN (DGifCloseFile);
-DEF_IMGLIB_FN (DGifSlurp);
-DEF_IMGLIB_FN (DGifOpen);
-DEF_IMGLIB_FN (DGifOpenFileName);
+DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *));
+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)
@@ -7062,7 +7072,7 @@ typedef struct
   size_t len;
   int index;
 }
-  gif_memory_source;
+gif_memory_source;
 
 /* Make the current memory source available to gif_read_from_memory.
    It's done this way because not all versions of libungif support
@@ -7089,26 +7099,27 @@ gif_read_from_memory (GifFileType *file, GifByteType *buf, int len)
 static const int interlace_start[] = {0, 4, 2, 1};
 static const int interlace_increment[] = {8, 8, 4, 2};
 
+#define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
+
 static int
 gif_load (struct frame *f, struct image *img)
 {
   Lisp_Object file, specified_file;
   Lisp_Object specified_data;
   int rc, width, height, x, y, i;
+  boolean transparent_p;
   XImagePtr ximg;
   ColorMapObject *gif_color_map;
   unsigned long pixel_colors[256];
   GifFileType *gif;
-  struct gcpro gcpro1;
   Lisp_Object image;
   int ino, image_height, image_width;
   gif_memory_source memsrc;
   unsigned char *raster;
+  unsigned int transparency_color_index;
 
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
-  file = Qnil;
-  GCPRO1 (file);
 
   if (NILP (specified_data))
     {
@@ -7116,34 +7127,35 @@ gif_load (struct frame *f, struct image *img)
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
-         UNGCPRO;
          return 0;
        }
 
-      /* Open the GIF file.  Casting return value avoids a GCC warning
-        on W32.  */
-      gif = (GifFileType *)fn_DGifOpenFileName (SDATA (file));
+      /* Open the GIF file.  */
+      gif = fn_DGifOpenFileName (SDATA (file));
       if (gif == NULL)
        {
          image_error ("Cannot open `%s'", file, Qnil);
-         UNGCPRO;
          return 0;
        }
     }
   else
     {
+      if (!STRINGP (specified_data))
+       {
+         image_error ("Invalid image data `%s'", specified_data, Qnil);
+         return 0;
+       }
+
       /* Read from memory! */
       current_gif_memory_src = &memsrc;
       memsrc.bytes = SDATA (specified_data);
       memsrc.len = SBYTES (specified_data);
       memsrc.index = 0;
 
-      /* Casting return value avoids a GCC warning on W32.  */
-      gif = (GifFileType *) fn_DGifOpen (&memsrc, gif_read_from_memory);
+      gif = fn_DGifOpen (&memsrc, gif_read_from_memory);
       if (!gif)
        {
          image_error ("Cannot open memory source `%s'", img->spec, Qnil);
-         UNGCPRO;
          return 0;
        }
     }
@@ -7153,7 +7165,6 @@ gif_load (struct frame *f, struct image *img)
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       fn_DGifCloseFile (gif);
-      UNGCPRO;
       return 0;
     }
 
@@ -7163,7 +7174,6 @@ gif_load (struct frame *f, struct image *img)
     {
       image_error ("Error reading `%s'", img->spec, Qnil);
       fn_DGifCloseFile (gif);
-      UNGCPRO;
       return 0;
     }
 
@@ -7174,10 +7184,21 @@ gif_load (struct frame *f, struct image *img)
       image_error ("Invalid image number `%s' in image `%s'",
                   image, img->spec);
       fn_DGifCloseFile (gif);
-      UNGCPRO;
       return 0;
     }
 
+  for (i = 0; i < gif->SavedImages[ino].ExtensionBlockCount; i++)
+    if ((gif->SavedImages[ino].ExtensionBlocks[i].Function
+        == GIF_LOCAL_DESCRIPTOR_EXTENSION)
+       && gif->SavedImages[ino].ExtensionBlocks[i].ByteCount == 4
+       /* Transparency enabled?  */
+       && gif->SavedImages[ino].ExtensionBlocks[i].Bytes[0] & 1)
+      {
+       transparent_p = 1;
+       transparency_color_index
+         = (unsigned char) gif->SavedImages[ino].ExtensionBlocks[i].Bytes[3];
+      }
+
   img->corners[TOP_CORNER] = gif->SavedImages[ino].ImageDesc.Top;
   img->corners[LEFT_CORNER] = gif->SavedImages[ino].ImageDesc.Left;
   image_height = gif->SavedImages[ino].ImageDesc.Height;
@@ -7196,7 +7217,6 @@ gif_load (struct frame *f, struct image *img)
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       fn_DGifCloseFile (gif);
-      UNGCPRO;
       return 0;
     }
 
@@ -7204,7 +7224,6 @@ gif_load (struct frame *f, struct image *img)
   if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
     {
       fn_DGifCloseFile (gif);
-      UNGCPRO;
       return 0;
     }
 
@@ -7218,10 +7237,22 @@ gif_load (struct frame *f, struct image *img)
   if (gif_color_map)
     for (i = 0; i < gif_color_map->ColorCount; ++i)
       {
-        int r = gif_color_map->Colors[i].Red << 8;
-        int g = gif_color_map->Colors[i].Green << 8;
-        int b = gif_color_map->Colors[i].Blue << 8;
-        pixel_colors[i] = lookup_rgb_color (f, r, g, b);
+       if (transparent_p && transparency_color_index == i)
+         {
+           Lisp_Object specified_bg
+             = image_spec_value (img->spec, QCbackground, NULL);
+           pixel_colors[i] = STRINGP (specified_bg)
+             ? x_alloc_image_color (f, img, specified_bg,
+                                    FRAME_BACKGROUND_PIXEL (f))
+             : FRAME_BACKGROUND_PIXEL (f);
+         }
+       else
+         {
+           int r = gif_color_map->Colors[i].Red << 8;
+           int g = gif_color_map->Colors[i].Green << 8;
+           int b = gif_color_map->Colors[i].Blue << 8;
+           pixel_colors[i] = lookup_rgb_color (f, r, g, b);
+         }
       }
 
 #ifdef COLOR_TABLE_SUPPORT
@@ -7323,7 +7354,6 @@ gif_load (struct frame *f, struct image *img)
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
 
-  UNGCPRO;
   return 1;
 }
 
@@ -7346,13 +7376,10 @@ gif_load (struct frame *f, struct image *img)
                                 imagemagick
 ***********************************************************************/
 #if defined (HAVE_IMAGEMAGICK)
-Lisp_Object Vimagemagick_render_type;
 
 /* The symbol `imagemagick' identifying images of this type.  */
 
 Lisp_Object Qimagemagick;
-Lisp_Object Vimagemagick_render_type;
-
 /* Indices of image specification fields in imagemagick_format, below.  */
 
 enum imagemagick_keyword_index
@@ -7389,9 +7416,9 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
     {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
     {":mask",          IMAGE_DONT_CHECK_VALUE_TYPE,            0},
     {":background",    IMAGE_STRING_OR_NIL_VALUE,              0},
-    {":height",                IMAGE_INTEGER_VALUE,                    0},    
-    {":width",         IMAGE_INTEGER_VALUE,                    0},    
-    {":rotation",      IMAGE_NUMBER_VALUE,                     0},    
+    {":height",                IMAGE_INTEGER_VALUE,                    0},
+    {":width",         IMAGE_INTEGER_VALUE,                    0},
+    {":rotation",      IMAGE_NUMBER_VALUE,                     0},
     {":crop",          IMAGE_DONT_CHECK_VALUE_TYPE,            0}
   };
 /* Free X resources of imagemagick image IMG which is used on frame F.  */
@@ -7400,7 +7427,6 @@ static void
 imagemagick_clear_image (struct frame *f,
                          struct image *img)
 {
-  printf("clearing imagemagick image\n");
   x_clear_image (f, img);
 }
 
@@ -7414,7 +7440,7 @@ static int
 imagemagick_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[IMAGEMAGICK_LAST];
-  bcopy (imagemagick_format, fmt, sizeof fmt);
+  memcpy (fmt, imagemagick_format, sizeof fmt);
 
   if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
     return 0;
@@ -7441,7 +7467,7 @@ static int
 imagemagick_load_image (/* Pointer to emacs frame structure.  */
                         struct frame *f,
                         /* Pointer to emacs image structure.  */
-                        struct image *img, 
+                        struct image *img,
                         /* String containing the IMAGEMAGICK data to
                            be parsed.  */
                         unsigned char *contents,
@@ -7451,8 +7477,8 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
                            contents/size.  */
                         unsigned char *filename)
 {
-  size_t width;
-  size_t height;
+  unsigned long width;
+  unsigned long height;
 
   MagickBooleanType
     status;
@@ -7464,97 +7490,94 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
   int y;
 
   MagickWand  *image_wand;
-  MagickWand  *ping_wand;  
+  MagickWand  *ping_wand;
   PixelIterator *iterator;
   PixelWand  **pixels;
   MagickPixelPacket  pixel;
   Lisp_Object image;
-  Lisp_Object value;  
+  Lisp_Object value;
   Lisp_Object crop, geometry;
   long ino;
   int desired_width, desired_height;
   double rotation;
   int imagemagick_rendermethod;
-  int pixelwidth; 
+  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 many sub-images it contains. Pinging is faster
-     than loading the image to find out things about it.
-  */
-  printf("im ping file %s\n", filename);
+     than loading the image to find out things about it.  */
+
+  /* `MagickWandGenesis' initializes the imagemagick environment.  */
+  MagickWandGenesis ();
   image = image_spec_value (img->spec, QCindex, NULL);
   ino = INTEGERP (image) ? XFASTINT (image) : 0;
-  ping_wand=NewMagickWand();
-  MagickSetResolution(ping_wand, 2, 2);
+  ping_wand = NewMagickWand ();
+  MagickSetResolution (ping_wand, 2, 2);
   if (filename != NULL)
     {
-      status = MagickPingImage(ping_wand, filename);
+      status = MagickPingImage (ping_wand, filename);
     }
   else
     {
-      status = MagickPingImageBlob(ping_wand, contents, size);
+      status = MagickPingImageBlob (ping_wand, contents, size);
+    }
+
+  if (ino >= MagickGetNumberImages (ping_wand))
+    {
+      image_error ("Invalid image number `%s' in image `%s'",
+                  image, img->spec);
+      DestroyMagickWand (ping_wand);
+      return 0;
     }
-  
-  if (ino >= MagickGetNumberImages(ping_wand)) 
-    { 
-      image_error ("Invalid image number `%s' in image `%s'", 
-                  image, img->spec); 
-      UNGCPRO; 
-      return 0; 
-    } 
 
   if (MagickGetNumberImages(ping_wand) > 1)
     img->data.lisp_val =
       Fcons (Qcount,
-             Fcons (make_number (MagickGetNumberImages(ping_wand)),
+             Fcons (make_number (MagickGetNumberImages (ping_wand)),
                     img->data.lisp_val));
 
   DestroyMagickWand (ping_wand);
+
   /* Now, after pinging, we know how many images are inside the
-     file. If its not a bundle, just one.
-  */
+     file. If its not a bundle, just one.  */
 
   if (filename != NULL)
     {
-      printf("im read file %s\n", filename);
-      image_info=CloneImageInfo((ImageInfo *) NULL);
-      (void) strcpy(image_info->filename, filename);
-      image_info -> number_scenes = 1;
-      image_info -> scene = ino;
-      exception=AcquireExceptionInfo();
+      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); 
-      CatchException(exception);
+      im_image = ReadImage (image_info, exception);
+      DestroyExceptionInfo (exception);
 
-      printf("im wand from image\n");   
-      image_wand = NewMagickWandFromImage(im_image);
+      if (im_image != NULL)
+       {
+         image_wand = NewMagickWandFromImage (im_image);
+          DestroyImage(im_image);
+         status = MagickTrue;
+       }
+      else
+       status = MagickFalse;
     }
   else
     {
-      image_wand = NewMagickWand();  
-      status = MagickReadImageBlob(image_wand, contents, size);
+      image_wand = NewMagickWand ();
+      status = MagickReadImageBlob (image_wand, contents, size);
     }
-  image_error ("im read failed", Qnil, Qnil);
-  if (status == MagickFalse) goto imagemagick_error;
-
-
-  /* if(ino == 0) */
-  /*   MagickSetFirstIterator(image_wand); */
-  /* else */
-  /*   MagickSetIteratorIndex(image_wand, ino); */
-
-  //MagickSetFirstIterator(image_wand);
 
+  if (status == MagickFalse) goto imagemagick_error;
 
   /* 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. */
+     aspect ratio.  */
 
   value = image_spec_value (img->spec, QCwidth, NULL);
   desired_width = (INTEGERP (value)  ? XFASTINT (value) : -1);
@@ -7566,64 +7589,71 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
 
   if(desired_width != -1 && desired_height == -1)
     {
-      /* w known, calculate h*/
-      desired_height = ( (double)desired_width / width  ) * height;
+      /* w known, calculate h.  */
+      desired_height = (double) desired_width / width * height;
     }
   if(desired_width == -1 && desired_height != -1)
     {
-      /* h known, calculate w*/
-      desired_width = ( (double)desired_height / height  ) * width;
-    }  
+      /* h known, calculate w.  */
+      desired_width = (double) desired_height / height * width;
+    }
   if(desired_width != -1 && desired_height != -1)
     {
-      printf("MagickScaleImage %d %d\n", desired_width, desired_height);
-      status = MagickScaleImage(image_wand, desired_width, desired_height);
-      if (status == MagickFalse) {
-        image_error ("Imagemagick scale failed", Qnil, Qnil);
-        goto imagemagick_error;
-      }
+      status = MagickScaleImage (image_wand, desired_width, desired_height);
+      if (status == MagickFalse)
+       {
+         image_error ("Imagemagick scale failed", Qnil, Qnil);
+         goto imagemagick_error;
+       }
     }
 
 
   /* crop behaves similar to image slicing in Emacs but is more memory
-     efficient */
-  crop     = image_spec_value (img->spec, QCcrop, NULL);
-  
-  if(CONSP (crop))
-    {
-      /* 
-         after some testing, it seems MagickCropImage is the fastest
-         crop function in ImageMagick. This crop function seems to do
+     efficient.  */
+  crop = image_spec_value (img->spec, QCcrop, NULL);
+
+  if (CONSP (crop) && INTEGERP (XCAR (crop)))
+    {
+      /* After some testing, it seems MagickCropImage is the fastest
+         crop function in ImageMagick.  This crop function seems to do
          less copying than the alternatives, but it still reads the
          entire image into memory before croping, which is aparently
-         difficult to avoid when using imagemagick.
-      */
-      
-      int w,h,x,y;
-      w=XFASTINT(XCAR(crop));
-      h=XFASTINT(XCAR(XCDR(crop)));
-      x=XFASTINT(XCAR(XCDR(XCDR(crop))));
-      y=XFASTINT(XCAR(XCDR(XCDR(XCDR(crop)))));
-      printf("MagickCropImage(image_wand, %d,%d, %d,%d)\n", w, h, x, y);
-      MagickCropImage(image_wand, w,h, x,y);
-    }
-  
+         difficult to avoid when using imagemagick.  */
+
+      int w, h, x, y;
+      w = XFASTINT (XCAR (crop));
+      crop = XCDR (crop);
+      if (CONSP (crop) && INTEGERP (XCAR (crop)))
+       {
+         h = XFASTINT (XCAR (crop));
+         crop = XCDR (crop);
+         if (CONSP (crop) && INTEGERP (XCAR (crop)))
+           {
+             x = XFASTINT (XCAR (crop));
+             crop = XCDR (crop);
+             if (CONSP (crop) && INTEGERP (XCAR (crop)))
+               {
+                 y = XFASTINT (XCAR (crop));
+                 MagickCropImage (image_wand, w, h, x, y);
+               }
+           }
+       }
+    }
+
   /* Furthermore :rotation. we need background color and angle for
      rotation.  */
   /*
     TODO background handling for rotation specified_bg =
     image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
-    (specified_bg)
-  */
+    (specified_bg).  */
   value = image_spec_value (img->spec, QCrotation, NULL);
   if (FLOATP (value))
     {
-      PixelWand* background = NewPixelWand();
+      PixelWand* background = NewPixelWand ();
       PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
-        
+
       rotation = extract_float (value);
-      printf ("MagickRotateImage %f\n", rotation);
-        
+
       status = MagickRotateImage (image_wand, background, rotation);
       DestroyPixelWand (background);
       if (status == MagickFalse)
@@ -7632,27 +7662,20 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
           goto imagemagick_error;
         }
     }
-  
+
   /* Finaly we are done manipulating the image, figure out resulting
-     width, height, and then transfer ownerwship to Emacs.
-  */
+     width, height, and then transfer ownerwship to Emacs.  */
   height = MagickGetImageHeight (image_wand);
   width = MagickGetImageWidth (image_wand);
-  if (status == MagickFalse)
-    {
-      image_error ("Imagemagick image get size failed", Qnil, Qnil);  
-      goto imagemagick_error;
-    }
-    
+
   if (! check_image_size (f, width, height))
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       goto imagemagick_error;
     }
-  
+
   /* We can now get a valid pixel buffer from the imagemagick file, if all
      went ok.  */
-  
 
   init_color_table ();
   imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
@@ -7663,28 +7686,34 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
       if (!x_create_x_image_and_pixmap (f, width, height, 0,
                                         &ximg, &img->pixmap))
         {
+#ifdef COLOR_TABLE_SUPPORT
+         free_color_table ();
+#endif
           image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
           goto imagemagick_error;
         }
-    
+
       /* Copy imagegmagick image to x with primitive yet robust pixel
          pusher loop.  This has been tested a lot with many different
-         images.
-      */
-  
+         images.  */
+
       /* Copy pixels from the imagemagick image structure to the x image map. */
       iterator = NewPixelIterator (image_wand);
-      if ((iterator == (PixelIterator *) NULL))
+      if (iterator == (PixelIterator *) NULL)
         {
+#ifdef COLOR_TABLE_SUPPORT
+         free_color_table ();
+#endif
+         x_destroy_x_image (ximg);
           image_error ("Imagemagick pixel iterator creation failed",
                        Qnil, Qnil);
           goto imagemagick_error;
         }
 
-      for (y = 0; y < (long) MagickGetImageHeight(image_wand); y++)
+      for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++)
         {
           pixels = PixelGetNextIteratorRow (iterator, &width);
-          if ((pixels == (PixelWand **) NULL))
+          if (pixels == (PixelWand **) NULL)
             break;
           for (x = 0; x < (long) width; x++)
             {
@@ -7701,18 +7730,23 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
 
   if (imagemagick_rendermethod == 1)
     {
-      /* Try if magicexportimage is any faster than pixelpushing. */
+      /* Magicexportimage is normaly 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);*/
       char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
       /* Try to create a x pixmap to hold the imagemagick pixmap.  */
-      printf("imagedepth:%d exportdepth:%s\n", imagedepth, exportdepth);
       if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
-                                        &ximg, &img->pixmap)){
-        image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
-        goto imagemagick_error;
-      }
+                                        &ximg, &img->pixmap))
+       {
+#ifdef COLOR_TABLE_SUPPORT
+         free_color_table ();
+#endif
+         image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+         goto imagemagick_error;
+       }
+
 
-    
       /* Oddly, the below code doesnt seem to work:*/
       /* switch(ximg->bitmap_unit){ */
       /* case 8: */
@@ -7733,20 +7767,20 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
         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);
+#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
+      MagickExportImagePixels (image_wand,
+                              0, 0,
+                              width, height,
+                              exportdepth,
+                              pixelwidth,
+                              /*&(img->pixmap));*/
+                              ximg->data);
 #else
-      image_error("You dont have MagickExportImagePixels, upgrade ImageMagick!",
-                  Qnil, Qnil);
-#endif    
+      image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!",
+                  Qnil, Qnil);
+#endif
     }
-  
+
 
 #ifdef COLOR_TABLE_SUPPORT
   /* Remember colors allocated for this image.  */
@@ -7766,13 +7800,16 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
 
   /* Final cleanup. image_wand should be the only resource left. */
   DestroyMagickWand (image_wand);
+  /* `MagickWandTerminus' terminates the imagemagick environment.  */
+  MagickWandTerminus ();
 
   return 1;
 
  imagemagick_error:
+  DestroyMagickWand (image_wand);
+  MagickWandTerminus ();
   /* TODO more cleanup.  */
   image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
-  printf("Imagemagick error, see *Messages*\n");
   return 0;
 }
 
@@ -7793,20 +7830,14 @@ imagemagick_load (struct frame *f,
   if (STRINGP (file_name))
     {
       Lisp_Object file;
-      unsigned char *contents;
-      int size;
-      struct gcpro gcpro1;
 
       file = x_find_image_file (file_name);
-      GCPRO1 (file);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", file_name, Qnil);
-         UNGCPRO;
          return 0;
        }
-      success_p = imagemagick_load_image (f, img, 0, 0, SDATA(file_name));
-      UNGCPRO;
+      success_p = imagemagick_load_image (f, img, 0, 0, SDATA (file));
     }
   /* Else its not a file, its a lisp object.  Load the image from a
      lisp object rather than a file.  */
@@ -7815,6 +7846,11 @@ imagemagick_load (struct frame *f,
       Lisp_Object data;
 
       data = image_spec_value (img->spec, QCdata, NULL);
+      if (!STRINGP (data))
+       {
+         image_error ("Invalid image data `%s'", data, Qnil);
+         return 0;
+       }
       success_p = imagemagick_load_image (f, img, SDATA (data),
                                           SBYTES (data), NULL);
     }
@@ -7846,16 +7882,16 @@ static struct image_type imagemagick_type =
 
 
 
-DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0, 
+DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
        doc: /* Return image file types supported by ImageMagick.
-               Since ImageMagick recognizes a lot of file-types that clash with Emacs,
-               such as .c, we want to be able to alter the list at the lisp level.  */)
+Since ImageMagick recognizes a lot of file-types that clash with Emacs,
+such as .c, we want to be able to alter the list at the lisp level.  */)
   (void)
 {
   Lisp_Object typelist = Qnil;
-  size_t numf;
+  unsigned long numf;
   ExceptionInfo ex;
-  char** imtypes = GetMagickList ("*", &numf, &ex);
+  char **imtypes = GetMagickList ("*", &numf, &ex);
   int i;
   Lisp_Object Qimagemagicktype;
   for (i = 0; i < numf; i++)
@@ -7865,14 +7901,14 @@ DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
     }
   return typelist;
 }
-  
+
 #endif /* defined (HAVE_IMAGEMAGICK) */
 
 
 \f
 /***********************************************************************
                                 SVG
-***********************************************************************/
+ ***********************************************************************/
 
 #if defined (HAVE_RSVG)
 
@@ -7891,55 +7927,55 @@ Lisp_Object Qsvg;
 /* Indices of image specification fields in svg_format, below.  */
 
 enum svg_keyword_index
-  {
-    SVG_TYPE,
-    SVG_DATA,
-    SVG_FILE,
-    SVG_ASCENT,
-    SVG_MARGIN,
-    SVG_RELIEF,
-    SVG_ALGORITHM,
-    SVG_HEURISTIC_MASK,
-    SVG_MASK,
-    SVG_BACKGROUND,
-    SVG_LAST
-  };
+{
+  SVG_TYPE,
+  SVG_DATA,
+  SVG_FILE,
+  SVG_ASCENT,
+  SVG_MARGIN,
+  SVG_RELIEF,
+  SVG_ALGORITHM,
+  SVG_HEURISTIC_MASK,
+  SVG_MASK,
+  SVG_BACKGROUND,
+  SVG_LAST
+};
 
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
 static const struct image_keyword svg_format[SVG_LAST] =
-  {
-    {":type",          IMAGE_SYMBOL_VALUE,                     1},
-    {":data",          IMAGE_STRING_VALUE,                     0},
-    {":file",          IMAGE_STRING_VALUE,                     0},
-    {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
-    {":relief",                IMAGE_INTEGER_VALUE,                    0},
-    {":conversion",    IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":mask",          IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":background",    IMAGE_STRING_OR_NIL_VALUE,              0}
-  };
+{
+  {":type",            IMAGE_SYMBOL_VALUE,                     1},
+  {":data",            IMAGE_STRING_VALUE,                     0},
+  {":file",            IMAGE_STRING_VALUE,                     0},
+  {":ascent",          IMAGE_ASCENT_VALUE,                     0},
+  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":relief",          IMAGE_INTEGER_VALUE,                    0},
+  {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
+};
 
 /* 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.  */
-    NULL
-  };
+{
+  /* 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.  */
+  NULL
+};
 
 
 /* Return non-zero if OBJECT is a valid SVG image specification.  Do
@@ -7964,25 +8000,25 @@ svg_image_p (Lisp_Object object)
 #ifdef HAVE_NTGUI
 
 /* SVG library functions.  */
-DEF_IMGLIB_FN (rsvg_handle_new);
-DEF_IMGLIB_FN (rsvg_handle_get_dimensions);
-DEF_IMGLIB_FN (rsvg_handle_write);
-DEF_IMGLIB_FN (rsvg_handle_close);
-DEF_IMGLIB_FN (rsvg_handle_get_pixbuf);
-DEF_IMGLIB_FN (rsvg_handle_free);
-
-DEF_IMGLIB_FN (gdk_pixbuf_get_width);
-DEF_IMGLIB_FN (gdk_pixbuf_get_height);
-DEF_IMGLIB_FN (gdk_pixbuf_get_pixels);
-DEF_IMGLIB_FN (gdk_pixbuf_get_rowstride);
-DEF_IMGLIB_FN (gdk_pixbuf_get_colorspace);
-DEF_IMGLIB_FN (gdk_pixbuf_get_n_channels);
-DEF_IMGLIB_FN (gdk_pixbuf_get_has_alpha);
-DEF_IMGLIB_FN (gdk_pixbuf_get_bits_per_sample);
-
-DEF_IMGLIB_FN (g_type_init);
-DEF_IMGLIB_FN (g_object_unref);
-DEF_IMGLIB_FN (g_error_free);
+DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new);
+DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions);
+DEF_IMGLIB_FN (gboolean, rsvg_handle_write);
+DEF_IMGLIB_FN (gboolean, rsvg_handle_close);
+DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf);
+DEF_IMGLIB_FN (void, rsvg_handle_free);
+
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_width);
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_height);
+DEF_IMGLIB_FN (guchar *, gdk_pixbuf_get_pixels);
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride);
+DEF_IMGLIB_FN (GdkColorspace, gdk_pixbuf_get_colorspace);
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels);
+DEF_IMGLIB_FN (gboolean, gdk_pixbuf_get_has_alpha);
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample);
+
+DEF_IMGLIB_FN (void, g_type_init);
+DEF_IMGLIB_FN (void, g_object_unref);
+DEF_IMGLIB_FN (void, g_error_free);
 
 Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
 
@@ -8061,14 +8097,11 @@ svg_load (struct frame *f, struct image *img)
       Lisp_Object file;
       unsigned char *contents;
       int size;
-      struct gcpro gcpro1;
 
       file = x_find_image_file (file_name);
-      GCPRO1 (file);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", file_name, Qnil);
-         UNGCPRO;
          return 0;
        }
 
@@ -8077,13 +8110,11 @@ svg_load (struct frame *f, struct image *img)
       if (contents == NULL)
        {
          image_error ("Error loading SVG image `%s'", img->spec, Qnil);
-         UNGCPRO;
          return 0;
        }
       /* If the file was slurped into memory properly, parse it.  */
       success_p = svg_load_image (f, img, contents, size);
       xfree (contents);
-      UNGCPRO;
     }
   /* Else its not a file, its a lisp object.  Load the image from a
      lisp object rather than a file.  */
@@ -8092,6 +8123,11 @@ svg_load (struct frame *f, struct image *img)
       Lisp_Object data;
 
       data = image_spec_value (img->spec, QCdata, NULL);
+      if (!STRINGP (data))
+       {
+         image_error ("Invalid image data `%s'", data, Qnil);
+         return 0;
+       }
       success_p = svg_load_image (f, img, SDATA (data), SBYTES (data));
     }
 
@@ -8129,7 +8165,7 @@ svg_load_image (struct frame *f,         /* Pointer to emacs frame structure.  *
      gnome type library functions.  */
   fn_g_type_init ();
   /* Make a handle to a new rsvg object.  */
-  rsvg_handle = (RsvgHandle *) fn_rsvg_handle_new ();
+  rsvg_handle = fn_rsvg_handle_new ();
 
   /* Parse the contents argument and fill in the rsvg_handle.  */
   fn_rsvg_handle_write (rsvg_handle, contents, size, &error);
@@ -8149,14 +8185,14 @@ 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 = (GdkPixbuf *) fn_rsvg_handle_get_pixbuf (rsvg_handle);
+  pixbuf = fn_rsvg_handle_get_pixbuf (rsvg_handle);
   if (!pixbuf) goto rsvg_error;
   fn_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    = (const guint8 *) fn_gdk_pixbuf_get_pixels (pixbuf);
+  pixels    = fn_gdk_pixbuf_get_pixels (pixbuf);
   rowstride = fn_gdk_pixbuf_get_rowstride (pixbuf);
 
   /* Validate the svg meta data.  */
@@ -8264,7 +8300,7 @@ svg_load_image (struct frame *f,         /* Pointer to emacs frame structure.  *
 \f
 /***********************************************************************
                                Ghostscript
-***********************************************************************/
+ ***********************************************************************/
 
 #ifdef HAVE_X_WINDOWS
 #define HAVE_GHOSTSCRIPT 1
@@ -8283,53 +8319,53 @@ Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height;
 /* Indices of image specification fields in gs_format, below.  */
 
 enum gs_keyword_index
-  {
-    GS_TYPE,
-    GS_PT_WIDTH,
-    GS_PT_HEIGHT,
-    GS_FILE,
-    GS_LOADER,
-    GS_BOUNDING_BOX,
-    GS_ASCENT,
-    GS_MARGIN,
-    GS_RELIEF,
-    GS_ALGORITHM,
-    GS_HEURISTIC_MASK,
-    GS_MASK,
-    GS_BACKGROUND,
-    GS_LAST
-  };
+{
+  GS_TYPE,
+  GS_PT_WIDTH,
+  GS_PT_HEIGHT,
+  GS_FILE,
+  GS_LOADER,
+  GS_BOUNDING_BOX,
+  GS_ASCENT,
+  GS_MARGIN,
+  GS_RELIEF,
+  GS_ALGORITHM,
+  GS_HEURISTIC_MASK,
+  GS_MASK,
+  GS_BACKGROUND,
+  GS_LAST
+};
 
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
 static const struct image_keyword gs_format[GS_LAST] =
-  {
-    {":type",          IMAGE_SYMBOL_VALUE,                     1},
-    {":pt-width",              IMAGE_POSITIVE_INTEGER_VALUE,           1},
-    {":pt-height",     IMAGE_POSITIVE_INTEGER_VALUE,           1},
-    {":file",          IMAGE_STRING_VALUE,                     1},
-    {":loader",                IMAGE_FUNCTION_VALUE,                   0},
-    {":bounding-box",  IMAGE_DONT_CHECK_VALUE_TYPE,            1},
-    {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
-    {":relief",                IMAGE_INTEGER_VALUE,                    0},
-    {":conversion",    IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":mask",          IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-    {":background",    IMAGE_STRING_OR_NIL_VALUE,              0}
-  };
+{
+  {":type",            IMAGE_SYMBOL_VALUE,                     1},
+  {":pt-width",                IMAGE_POSITIVE_INTEGER_VALUE,           1},
+  {":pt-height",       IMAGE_POSITIVE_INTEGER_VALUE,           1},
+  {":file",            IMAGE_STRING_VALUE,                     1},
+  {":loader",          IMAGE_FUNCTION_VALUE,                   0},
+  {":bounding-box",    IMAGE_DONT_CHECK_VALUE_TYPE,            1},
+  {":ascent",          IMAGE_ASCENT_VALUE,                     0},
+  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":relief",          IMAGE_INTEGER_VALUE,                    0},
+  {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
+};
 
 /* Structure describing the image type `ghostscript'.  */
 
 static struct image_type gs_type =
-  {
-    &Qpostscript,
-    gs_image_p,
-    gs_load,
-    gs_clear_image,
-    NULL
-  };
+{
+  &Qpostscript,
+  gs_image_p,
+  gs_load,
+  gs_clear_image,
+  NULL
+};
 
 
 /* Free X resources of Ghostscript image IMG which is used on frame F.  */
@@ -8391,7 +8427,6 @@ gs_load (struct frame *f, struct image *img)
 {
   char buffer[100];
   Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
-  struct gcpro gcpro1, gcpro2;
   Lisp_Object frame;
   double in_width, in_height;
   Lisp_Object pixel_colors = Qnil;
@@ -8401,10 +8436,10 @@ gs_load (struct frame *f, struct image *img)
      = 1/72 in, xdpi and ydpi are stored in the frame's X display
      info.  */
   pt_width = image_spec_value (img->spec, QCpt_width, NULL);
-  in_width = XFASTINT (pt_width) / 72.0;
+  in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
   img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx;
   pt_height = image_spec_value (img->spec, QCpt_height, NULL);
-  in_height = XFASTINT (pt_height) / 72.0;
+  in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
   img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy;
 
   if (!check_image_size (f, img->width, img->height))
@@ -8433,8 +8468,6 @@ gs_load (struct frame *f, struct image *img)
      if successful.  We do not record_unwind_protect here because
      other places in redisplay like calling window scroll functions
      don't either.  Let the Lisp loader use `unwind-protect' instead.  */
-  GCPRO2 (window_and_pixmap_id, pixel_colors);
-
   sprintf (buffer, "%lu %lu",
           (unsigned long) FRAME_X_WINDOW (f),
           (unsigned long) img->pixmap);
@@ -8455,7 +8488,6 @@ gs_load (struct frame *f, struct image *img)
                              make_number (img->height),
                              window_and_pixmap_id,
                              pixel_colors);
-  UNGCPRO;
   return PROCESSP (img->data.lisp_val);
 }
 
@@ -8557,7 +8589,7 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
 \f
 /***********************************************************************
                                Tests
-***********************************************************************/
+ ***********************************************************************/
 
 #if GLYPH_DEBUG
 
@@ -8586,7 +8618,7 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
 
 /***********************************************************************
                            Initialization
-***********************************************************************/
+ ***********************************************************************/
 
 #ifdef HAVE_NTGUI
 /* Image types that rely on external libraries are loaded dynamically
@@ -8600,11 +8632,11 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
 
 DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
        doc: /* Initialize image library implementing image type TYPE.
-               Return non-nil if TYPE is a supported image 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 `image-library-alist', which see).  */)
+of `dynamic-library-alist', which see).  */)
   (Lisp_Object type, Lisp_Object libraries)
 {
   Lisp_Object tested;
@@ -8645,12 +8677,11 @@ of `image-library-alist', which see).  */)
 #endif
 
 #if defined (HAVE_IMAGEMAGICK)
-  if (EQ (type, Qimagemagick)){
-    /* MagickWandGenesis() initalizes the imagemagick library.  */
-    MagickWandGenesis(); 
-    return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
-                                libraries);
-  }
+  if (EQ (type, Qimagemagick))
+    {
+      return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
+                                 libraries);
+    }
 #endif
 
 #ifdef HAVE_GHOSTSCRIPT
@@ -8663,7 +8694,6 @@ of `image-library-alist', which see).  */)
   return Qnil;
 }
 
-
 void
 syms_of_image (void)
 {
@@ -8674,36 +8704,22 @@ syms_of_image (void)
 
   /* Must be defined now becase we're going to update it below, while
      defining the supported image types.  */
-  DEFVAR_LISP ("image-types", &Vimage_types,
-               doc: /* List of potentially supported image types.
-                       Each element of the list is a symbol for an image type, like 'jpeg or 'png.
-                       To check whether it is really supported, use `image-type-available-p'.  */);
+  DEFVAR_LISP ("image-types", Vimage_types,
+    doc: /* List of potentially supported image types.
+Each element of the list is a symbol for an image type, like 'jpeg or 'png.
+To check whether it is really supported, use `image-type-available-p'.  */);
   Vimage_types = Qnil;
 
-  DEFVAR_LISP ("image-library-alist", &Vimage_library_alist,
-               doc: /* Alist of image types vs external libraries needed to display them.
-
-Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol
-representing a supported image type, and the rest are strings giving
-alternate filenames for the corresponding external libraries.
-
-Emacs tries to load the libraries in the order they appear on the
-list; if none is loaded, the running session of Emacs won't
-support the image type.  Types 'pbm and 'xbm don't need to be
-listed; they are always supported.  */);
-  Vimage_library_alist = Qnil;
-  Fput (intern_c_string ("image-library-alist"), Qrisky_local_variable, Qt);
-
-  DEFVAR_LISP ("max-image-size", &Vmax_image_size,
-               doc: /* Maximum size of images.
-                       Emacs will not load an image into memory if its pixel width or
-                       pixel height exceeds this limit.
-
-                       If the value is an integer, it directly specifies the maximum
-                       image height and width, measured in pixels.  If it is a floating
-                       point number, it specifies the maximum image height and width
-                       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.  */);
+  DEFVAR_LISP ("max-image-size", Vmax_image_size,
+    doc: /* Maximum size of images.
+Emacs will not load an image into memory if its pixel width or
+pixel height exceeds this limit.
+
+If the value is an integer, it directly specifies the maximum
+image height and width, measured in pixels.  If it is a floating
+point number, it specifies the maximum image height and width
+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);
 
   Vimage_type_cache = Qnil;
@@ -8739,14 +8755,13 @@ listed; they are always supported.  */);
   staticpro (&QCheuristic_mask);
   QCindex = intern_c_string (":index");
   staticpro (&QCindex);
-  QCgeometry = intern (":geometry");
+  QCgeometry = intern_c_string (":geometry");
   staticpro (&QCgeometry);
-  QCcrop = intern (":crop");
+  QCcrop = intern_c_string (":crop");
   staticpro (&QCcrop);
-  QCrotation = intern (":rotation");
+  QCrotation = intern_c_string (":rotation");
   staticpro (&QCrotation);
   QCmatrix = intern_c_string (":matrix");
-
   staticpro (&QCmatrix);
   QCcolor_adjustment = intern_c_string (":color-adjustment");
   staticpro (&QCcolor_adjustment);
@@ -8776,6 +8791,18 @@ listed; they are always supported.  */);
   staticpro (&QCpt_height);
 #endif /* HAVE_GHOSTSCRIPT */
 
+#ifdef HAVE_NTGUI
+  Qlibpng_version = intern_c_string ("libpng-version");
+  staticpro (&Qlibpng_version);
+  Fset (Qlibpng_version,
+#if HAVE_PNG
+       make_number (PNG_LIBPNG_VER)
+#else
+       make_number (-1)
+#endif
+       );
+#endif
+
 #if defined (HAVE_XPM) || defined (HAVE_NS)
   Qxpm = intern_c_string ("xpm");
   staticpro (&Qxpm);
@@ -8807,11 +8834,11 @@ listed; they are always supported.  */);
 #endif
 
 #if defined (HAVE_IMAGEMAGICK)
-  Qimagemagick = intern ("imagemagick");
+  Qimagemagick = intern_c_string ("imagemagick");
   staticpro (&Qimagemagick);
   ADD_IMAGE_TYPE (Qimagemagick);
 #endif
-  
+
 #if defined (HAVE_RSVG)
   Qsvg = intern_c_string ("svg");
   staticpro (&Qsvg);
@@ -8828,9 +8855,9 @@ listed; they are always supported.  */);
 #endif /* HAVE_RSVG  */
 
   defsubr (&Sinit_image_library);
-#ifdef HAVE_IMAGEMAGICK  
+#ifdef HAVE_IMAGEMAGICK
   defsubr (&Simagemagick_types);
-#endif  
+#endif
   defsubr (&Sclear_image_cache);
   defsubr (&Simage_flush);
   defsubr (&Simage_size);
@@ -8842,39 +8869,33 @@ listed; they are always supported.  */);
   defsubr (&Slookup_image);
 #endif
 
-  DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images,
-               doc: /* Non-nil means always draw a cross over disabled images.
-                       Disabled images are those having a `:conversion disabled' property.
-                       A cross is always drawn on black & white displays.  */);
+  DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images,
+    doc: /* Non-nil means always draw a cross over disabled images.
+Disabled images are those having a `:conversion disabled' property.
+A cross is always drawn on black & white displays.  */);
   cross_disabled_images = 0;
 
-  DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
-               doc: /* List of directories to search for window system bitmap files.  */);
+  DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path,
+    doc: /* List of directories to search for window system bitmap files.  */);
   Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
 
-  DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
-               doc: /* Maximum time after which images are removed from the cache.
-                       When an image has not been displayed this many seconds, Emacs
-                       automatically removes it from the image cache.  If the cache contains
-                       a large number of images, the actual eviction time may be shorter.
-                       The value can also be nil, meaning the cache is never cleared.
-                       The function `clear-image-cache' disregards this variable.  */);
+  DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
+    doc: /* Maximum time after which images are removed from the cache.
+When an image has not been displayed this many seconds, Emacs
+automatically removes it from the image cache.  If the cache contains
+a large number of images, the actual eviction time may be shorter.
+The value can also be nil, meaning the cache is never cleared.
+
+The function `clear-image-cache' disregards this variable.  */);
   Vimage_cache_eviction_delay = make_number (300);
-#ifdef HAVE_IMAGEMAGICK  
-  DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type,
+#ifdef HAVE_IMAGEMAGICK
+  DEFVAR_LISP ("imagemagick-render-type", Vimagemagick_render_type,
                doc: /* Choose between ImageMagick render methods.  */);
-#endif    
+#endif
 
 }
 
-
 void
 init_image (void)
 {
-
 }
-
-
-
-/* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
-   (do not change this comment) */