]> code.delx.au - gnu-emacs/blobdiff - src/image.c
Convert most remaining function definitions to standard C.
[gnu-emacs] / src / image.c
index cce0024e8356a84785db38d1beef874463190065..adc28ba8d38563aec6bf39ed6ef071e7f90514dd 100644 (file)
@@ -1,14 +1,14 @@
 /* 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
+                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+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, or (at your option)
-any later version.
+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
@@ -16,9 +16,7 @@ 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; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
@@ -29,6 +27,16 @@ Boston, MA 02110-1301, USA.  */
 #include <unistd.h>
 #endif
 
+#ifdef HAVE_PNG
+#if defined HAVE_LIBPNG_PNG_H
+# include <libpng/png.h>
+#else
+# include <png.h>
+#endif
+#endif
+
+#include <setjmp.h>
+
 /* This makes the fields of a Display accessible, in Xlib header files.  */
 
 #define XLIB_ILLEGAL_ACCESS
@@ -40,9 +48,10 @@ Boston, MA 02110-1301, USA.  */
 #include "blockinput.h"
 #include "systime.h"
 #include <epaths.h>
-#include "charset.h"
+#include "character.h"
 #include "coding.h"
 #include "termhooks.h"
+#include "font.h"
 
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
@@ -80,51 +89,37 @@ typedef struct w32_bitmap_record Bitmap_Record;
 #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
 #define x_defined_color w32_defined_color
 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
-#endif /* HAVE_NTGUI */
 
+/* Functions from w32term.c that depend on XColor (so can't go in w32term.h
+   without modifying lots of files).  */
+extern void x_query_colors (struct frame *f, XColor *colors, int ncolors);
+extern void x_query_color (struct frame *f, XColor *color);
+#endif /* HAVE_NTGUI */
 
-#ifdef MAC_OS
-#include "macterm.h"
+#ifdef HAVE_NS
+#include "nsterm.h"
+#include <sys/types.h>
 #include <sys/stat.h>
-#ifndef MAC_OSX
-#include <alloca.h>
-#include <sys/param.h>
-#endif
-#if TARGET_API_MAC_CARBON
-#ifdef MAC_OSX
-#include <QuickTime/QuickTime.h>
-#else  /* not MAC_OSX */
-#include <QuickTime.h>
-#endif /* not MAC_OSX */
-#else  /* not TARGET_API_MAC_CARBON */
-#include <Windows.h>
-#include <Gestalt.h>
-#include <TextUtils.h>
-#include <ImageCompression.h>
-#include <QuickTimeComponents.h>
-#endif /* not TARGET_API_MAC_CARBON */
-
-/* MAC_TODO : Color tables on Mac.  */
+
 #undef COLOR_TABLE_SUPPORT
 
-#define ZPixmap 0              /* arbitrary */
-typedef struct mac_bitmap_record Bitmap_Record;
+typedef struct ns_bitmap_record Bitmap_Record;
 
 #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
 #define NO_PIXMAP 0
 
 #define RGB_PIXEL_COLOR unsigned long
+#define ZPixmap 0
 
-/* A black pixel in a mask bitmap/pixmap means ``draw a source
-   pixel''.  A white pixel means ``retain the current pixel''. */
-#define PIX_MASK_DRAW  RGB_TO_ULONG(0,0,0)
-#define PIX_MASK_RETAIN        RGB_TO_ULONG(255,255,255)
-
-#define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
-#define x_defined_color mac_defined_color
-#define DefaultDepthOfScreen(screen) (one_mac_display_info.n_planes)
+#define PIX_MASK_RETAIN        0
+#define PIX_MASK_DRAW  1
 
-#endif /* MAC_OS */
+#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
+#define x_defined_color(f, name, color_def, alloc) \
+  ns_defined_color (f, name, color_def, alloc, 0)
+#define FRAME_X_SCREEN(f) 0
+#define DefaultDepthOfScreen(screen) x_display_list->n_planes
+#endif /* HAVE_NS */
 
 
 /* Search path for bitmap files.  */
@@ -132,16 +127,16 @@ typedef struct mac_bitmap_record Bitmap_Record;
 Lisp_Object Vx_bitmap_file_path;
 
 
-static void x_disable_image P_ ((struct frame *, struct image *));
-static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
-                                 Lisp_Object));
+static void x_disable_image (struct frame *, struct image *);
+static void x_edge_detection (struct frame *, struct image *, Lisp_Object,
+                              Lisp_Object);
 
-static void init_color_table P_ ((void));
-static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b));
+static void init_color_table (void);
+static unsigned long lookup_rgb_color (struct frame *f, int r, int g, int b);
 #ifdef COLOR_TABLE_SUPPORT
-static void free_color_table P_ ((void));
-static unsigned long *colors_in_color_table P_ ((int *n));
-static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
+static void free_color_table (void);
+static unsigned long *colors_in_color_table (int *n);
+static unsigned long lookup_pixel_color (struct frame *f, unsigned long p);
 #endif
 
 /* Code to deal with bitmaps.  Bitmaps are referenced by their bitmap
@@ -155,199 +150,51 @@ static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
    the bitmaps yourself.  That is, creating a bitmap from the same
    data more than once will not be caught.  */
 
-#ifdef MAC_OS
-
-static XImagePtr
-XGetImage (display, pixmap, x, y, width, height, plane_mask, format)
-     Display *display;         /* not used */
-     Pixmap pixmap;
-     int x, y;                 /* not used */
-     unsigned int width, height; /* not used */
-     unsigned long plane_mask;         /* not used */
-     int format;               /* not used */
+#ifdef HAVE_NS
+XImagePtr
+XGetImage (Display *display, Pixmap pixmap, int x, int y,
+           unsigned int width, unsigned int height,
+           unsigned long plane_mask, int format)
 {
-#if GLYPH_DEBUG
-  xassert (x == 0 && y == 0);
-  {
-    Rect ri, rp;
-    SetRect (&ri, 0, 0, width, height);
-    xassert (EqualRect (&ri, GetPixBounds (GetGWorldPixMap (pixmap), &rp)));
-  }
-  xassert (! (pixelsLocked & GetPixelsState (GetGWorldPixMap (pixmap))));
-#endif
-
-  LockPixels (GetGWorldPixMap (pixmap));
-
+  /* TODO: not sure what this function is supposed to do.. */
+  ns_retain_object(pixmap);
   return pixmap;
 }
 
-static void
-XPutPixel (ximage, x, y, pixel)
-     XImagePtr ximage;
-     int x, y;
-     unsigned long pixel;
-{
-  PixMapHandle pixmap = GetGWorldPixMap (ximage);
-  short depth = GetPixDepth (pixmap);
-
-#if defined (WORDS_BIG_ENDIAN) || !USE_CG_DRAWING
-  if (depth == 32)
-    {
-      char *base_addr = GetPixBaseAddr (pixmap);
-      short row_bytes = GetPixRowBytes (pixmap);
-
-      ((unsigned long *) (base_addr + y * row_bytes))[x] = 0xff000000 | pixel;
-    }
-  else
-#endif
-  if (depth == 1)
-    {
-      char *base_addr = GetPixBaseAddr (pixmap);
-      short row_bytes = GetPixRowBytes (pixmap);
-
-      if (pixel == PIX_MASK_DRAW)
-       base_addr[y * row_bytes + x / 8] |= (1 << 7) >> (x & 7);
-      else
-       base_addr[y * row_bytes + x / 8] &= ~((1 << 7) >> (x & 7));
-    }
-  else
-    {
-      CGrafPtr old_port;
-      GDHandle old_gdh;
-      RGBColor color;
-
-      GetGWorld (&old_port, &old_gdh);
-      SetGWorld (ximage, NULL);
-
-      color.red = RED16_FROM_ULONG (pixel);
-      color.green = GREEN16_FROM_ULONG (pixel);
-      color.blue = BLUE16_FROM_ULONG (pixel);
-
-      SetCPixel (x, y, &color);
-
-      SetGWorld (old_port, old_gdh);
-    }
-}
-
-static unsigned long
-XGetPixel (ximage, x, y)
-     XImagePtr ximage;
-     int x, y;
-{
-  PixMapHandle pixmap = GetGWorldPixMap (ximage);
-  short depth = GetPixDepth (pixmap);
-
-#if defined (WORDS_BIG_ENDIAN) || !USE_CG_DRAWING
-  if (depth == 32)
-    {
-      char *base_addr = GetPixBaseAddr (pixmap);
-      short row_bytes = GetPixRowBytes (pixmap);
-
-      return ((unsigned long *) (base_addr + y * row_bytes))[x] & 0x00ffffff;
-    }
-  else
-#endif
-  if (depth == 1)
-    {
-      char *base_addr = GetPixBaseAddr (pixmap);
-      short row_bytes = GetPixRowBytes (pixmap);
-
-      if (base_addr[y * row_bytes + x / 8] & (1 << (~x & 7)))
-       return PIX_MASK_DRAW;
-      else
-       return PIX_MASK_RETAIN;
-    }
-  else
-    {
-      CGrafPtr old_port;
-      GDHandle old_gdh;
-      RGBColor color;
-
-      GetGWorld (&old_port, &old_gdh);
-      SetGWorld (ximage, NULL);
-
-      GetCPixel (x, y, &color);
-
-      SetGWorld (old_port, old_gdh);
-      return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8);
-    }
-}
-
-static void
-XDestroyImage (ximg)
-     XImagePtr ximg;
+/* use with imgs created by ns_image_for_XPM */
+unsigned long
+XGetPixel (XImagePtr ximage, int x, int y)
 {
-  UnlockPixels (GetGWorldPixMap (ximg));
+  return ns_get_pixel(ximage, x, y);
 }
 
-#if USE_CG_DRAWING
-static CGImageRef
-mac_create_cg_image_from_image (f, img)
-     struct frame *f;
-     struct image *img;
+/* use with imgs created by ns_image_for_XPM; alpha set to 1;
+   pixel is assumed to be in form RGB */
+void
+XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
 {
-  Pixmap mask;
-  CGImageRef result = NULL;
-
-  BLOCK_INPUT;
-  if (img->mask)
-    mask = img->mask;
-  else
-    {
-      mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                           img->width, img->height, 1);
-      if (mask)
-       {
-         CGrafPtr old_port;
-         GDHandle old_gdh;
-         Rect r;
-
-         GetGWorld (&old_port, &old_gdh);
-         SetGWorld (mask, NULL);
-         BackColor (blackColor); /* Don't mask.  */
-         SetRect (&r, 0, 0, img->width, img->height);
-         EraseRect (&r);
-         SetGWorld (old_port, old_gdh);
-       }
-    }
-  if (mask)
-    {
-      CreateCGImageFromPixMaps (GetGWorldPixMap (img->pixmap),
-                               GetGWorldPixMap (mask), &result);
-      if (mask != img->mask)
-       XFreePixmap (FRAME_X_DISPLAY (f), mask);
-    }
-  UNBLOCK_INPUT;
-
-  return result;
+  ns_put_pixel(ximage, x, y, pixel);
 }
-#endif /* USE_CG_DRAWING */
-#endif /* MAC_OS */
+#endif /* HAVE_NS */
 
 
 /* Functions to access the contents of a bitmap, given an id.  */
 
 int
-x_bitmap_height (f, id)
-     FRAME_PTR f;
-     int id;
+x_bitmap_height (FRAME_PTR f, int id)
 {
   return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].height;
 }
 
 int
-x_bitmap_width (f, id)
-     FRAME_PTR f;
-     int id;
+x_bitmap_width (FRAME_PTR f, int id)
 {
   return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].width;
 }
 
 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
 int
-x_bitmap_pixmap (f, id)
-     FRAME_PTR f;
-     int id;
+x_bitmap_pixmap (FRAME_PTR f, int id)
 {
   return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
 }
@@ -355,9 +202,7 @@ x_bitmap_pixmap (f, id)
 
 #ifdef HAVE_X_WINDOWS
 int
-x_bitmap_mask (f, id)
-     FRAME_PTR f;
-     int id;
+x_bitmap_mask (FRAME_PTR f, int id)
 {
   return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].mask;
 }
@@ -366,8 +211,7 @@ x_bitmap_mask (f, id)
 /* Allocate a new bitmap record.  Returns index of new record.  */
 
 static int
-x_allocate_bitmap_record (f)
-     FRAME_PTR f;
+x_allocate_bitmap_record (FRAME_PTR f)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   int i;
@@ -398,9 +242,7 @@ x_allocate_bitmap_record (f)
 /* Add one reference to the reference count of the bitmap with id ID.  */
 
 void
-x_reference_bitmap (f, id)
-     FRAME_PTR f;
-     int id;
+x_reference_bitmap (FRAME_PTR f, int id)
 {
   ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
 }
@@ -408,10 +250,7 @@ x_reference_bitmap (f, id)
 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS.  */
 
 int
-x_create_bitmap_from_data (f, bits, width, height)
-     struct frame *f;
-     char *bits;
-     unsigned int width, height;
+x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsigned int height)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   int id;
@@ -434,17 +273,18 @@ x_create_bitmap_from_data (f, bits, width, height)
     return -1;
 #endif /* HAVE_NTGUI */
 
-#ifdef MAC_OS
-  /* MAC_TODO: for now fail if width is not mod 16 (toolbox requires it) */
-  if (width % 16 != 0)
-    return -1;
+#ifdef HAVE_NS
+  void *bitmap = ns_image_from_XBM(bits, width, height);
+  if (!bitmap)
+      return -1;
 #endif
 
   id = x_allocate_bitmap_record (f);
-#ifdef MAC_OS
-  dpyinfo->bitmaps[id - 1].bitmap_data = (char *) xmalloc (height * width);
-  bcopy (bits, dpyinfo->bitmaps[id - 1].bitmap_data, height * width);
-#endif  /* MAC_OS */
+
+#ifdef HAVE_NS
+  dpyinfo->bitmaps[id - 1].img = bitmap;
+  dpyinfo->bitmaps[id - 1].depth = 1;
+#endif
 
   dpyinfo->bitmaps[id - 1].file = NULL;
   dpyinfo->bitmaps[id - 1].height = height;
@@ -469,20 +309,34 @@ x_create_bitmap_from_data (f, bits, width, height)
 /* Create bitmap from file FILE for frame F.  */
 
 int
-x_create_bitmap_from_file (f, file)
-     struct frame *f;
-     Lisp_Object file;
+x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
 {
-#ifdef MAC_OS
-  return -1;  /* MAC_TODO : bitmap support */
-#endif  /* MAC_OS */
+  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
 
 #ifdef HAVE_NTGUI
   return -1;  /* W32_TODO : bitmap support */
 #endif /* HAVE_NTGUI */
 
+#ifdef HAVE_NS
+  int id;
+  void *bitmap = ns_image_from_file(file);
+
+  if (!bitmap)
+      return -1;
+
+
+  id = x_allocate_bitmap_record (f);
+  dpyinfo->bitmaps[id - 1].img = bitmap;
+  dpyinfo->bitmaps[id - 1].refcount = 1;
+  dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (SBYTES (file) + 1);
+  dpyinfo->bitmaps[id - 1].depth = 1;
+  dpyinfo->bitmaps[id - 1].height = ns_image_width(bitmap);
+  dpyinfo->bitmaps[id - 1].width = ns_image_height(bitmap);
+  strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
+  return id;
+#endif
+
 #ifdef HAVE_X_WINDOWS
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   unsigned int width, height;
   Pixmap bitmap;
   int xhot, yhot, result, id;
@@ -532,9 +386,7 @@ x_create_bitmap_from_file (f, file)
 /* Free bitmap B.  */
 
 static void
-free_bitmap_record (dpyinfo, bm)
-     Display_Info *dpyinfo;
-     Bitmap_Record *bm;
+free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
 {
 #ifdef HAVE_X_WINDOWS
   XFreePixmap (dpyinfo->display, bm->pixmap);
@@ -546,10 +398,9 @@ free_bitmap_record (dpyinfo, bm)
   DeleteObject (bm->pixmap);
 #endif /* HAVE_NTGUI */
 
-#ifdef MAC_OS
-  xfree (bm->bitmap_data);  /* Added ++kfs */
-  bm->bitmap_data = NULL;
-#endif  /* MAC_OS */
+#ifdef HAVE_NS
+  ns_release_object(bm->img);
+#endif
 
   if (bm->file)
     {
@@ -561,9 +412,7 @@ free_bitmap_record (dpyinfo, bm)
 /* Remove reference to bitmap with id number ID.  */
 
 void
-x_destroy_bitmap (f, id)
-     FRAME_PTR f;
-     int id;
+x_destroy_bitmap (FRAME_PTR f, int id)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
 
@@ -583,8 +432,7 @@ x_destroy_bitmap (f, id)
 /* Free all the bitmaps for the display specified by DPYINFO.  */
 
 void
-x_destroy_all_bitmaps (dpyinfo)
-     Display_Info *dpyinfo;
+x_destroy_all_bitmaps (Display_Info *dpyinfo)
 {
   int i;
   Bitmap_Record *bm = dpyinfo->bitmaps;
@@ -602,25 +450,23 @@ x_destroy_all_bitmaps (dpyinfo)
 /* Useful functions defined in the section
    `Image type independent image structures' below. */
 
-static unsigned long four_corners_best P_ ((XImagePtr ximg,
-                                           int *corners,
-                                           unsigned long width,
-                                           unsigned long height));
+static unsigned long four_corners_best (XImagePtr ximg,
+                                        int *corners,
+                                        unsigned long width,
+                                        unsigned long height);
 
-static int x_create_x_image_and_pixmap P_ ((struct frame *f, int width, int height,
-                                           int depth, XImagePtr *ximg,
-                                           Pixmap *pixmap));
+static int x_create_x_image_and_pixmap (struct frame *f, int width, int height,
+                                        int depth, XImagePtr *ximg,
+                                        Pixmap *pixmap);
 
-static void x_destroy_x_image P_ ((XImagePtr ximg));
+static void x_destroy_x_image (XImagePtr ximg);
 
 
 /* Create a mask of a bitmap. Note is this not a perfect mask.
    It's nicer with some borders in this context */
 
 int
-x_create_bitmap_mask (f, id)
-     struct frame *f;
-     int id;
+x_create_bitmap_mask (struct frame *f, int id)
 {
   Pixmap pixmap, mask;
   XImagePtr ximg, mask_img;
@@ -735,7 +581,7 @@ Lisp_Object Qxbm;
 extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
 extern Lisp_Object QCdata, QCtype;
 extern Lisp_Object Qcenter;
-Lisp_Object QCascent, QCmargin, QCrelief, Qcount;
+Lisp_Object QCascent, QCmargin, QCrelief, Qcount, Qextension_data;
 Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
 Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
 
@@ -750,13 +596,13 @@ Lisp_Object Vimage_cache_eviction_delay;
 
 /* Function prototypes.  */
 
-static Lisp_Object define_image_type P_ ((struct image_type *type, int loaded));
-static struct image_type *lookup_image_type P_ ((Lisp_Object symbol));
-static void image_error P_ ((char *format, Lisp_Object, Lisp_Object));
-static void x_laplace P_ ((struct frame *, struct image *));
-static void x_emboss P_ ((struct frame *, struct image *));
-static int x_build_heuristic_mask P_ ((struct frame *, struct image *,
-                                      Lisp_Object));
+static Lisp_Object define_image_type (struct image_type *type, int loaded);
+static struct image_type *lookup_image_type (Lisp_Object symbol);
+static void image_error (char *format, Lisp_Object, Lisp_Object);
+static void x_laplace (struct frame *, struct image *);
+static void x_emboss (struct frame *, struct image *);
+static int x_build_heuristic_mask (struct frame *, struct image *,
+                                   Lisp_Object);
 
 #define CACHE_IMAGE_TYPE(type, status) \
   do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
@@ -768,9 +614,7 @@ static int x_build_heuristic_mask P_ ((struct frame *, struct image *,
    image_types and caches the loading status of TYPE.  */
 
 static Lisp_Object
-define_image_type (type, loaded)
-     struct image_type *type;
-     int loaded;
+define_image_type (struct image_type *type, int loaded)
 {
   Lisp_Object success;
 
@@ -796,8 +640,7 @@ define_image_type (type, loaded)
    structure.  Value is null if SYMBOL is not a known image type.  */
 
 static INLINE struct image_type *
-lookup_image_type (symbol)
-     Lisp_Object symbol;
+lookup_image_type (Lisp_Object symbol)
 {
   struct image_type *type;
 
@@ -821,8 +664,7 @@ lookup_image_type (symbol)
    image type.  */
 
 int
-valid_image_p (object)
-     Lisp_Object object;
+valid_image_p (Lisp_Object object)
 {
   int valid_p = 0;
 
@@ -857,9 +699,7 @@ valid_image_p (object)
    therefore simply displays a message.  */
 
 static void
-image_error (format, arg1, arg2)
-     char *format;
-     Lisp_Object arg1, arg2;
+image_error (char *format, Lisp_Object arg1, Lisp_Object arg2)
 {
   add_to_log (format, arg1, arg2);
 }
@@ -907,9 +747,9 @@ struct image_keyword
 };
 
 
-static int parse_image_spec P_ ((Lisp_Object, struct image_keyword *,
-                                int, Lisp_Object));
-static Lisp_Object image_spec_value P_ ((Lisp_Object, Lisp_Object, int *));
+static int parse_image_spec (Lisp_Object, struct image_keyword *,
+                             int, Lisp_Object);
+static Lisp_Object image_spec_value (Lisp_Object, Lisp_Object, int *);
 
 
 /* Parse image spec SPEC according to KEYWORDS.  A valid image spec
@@ -919,11 +759,8 @@ static Lisp_Object image_spec_value P_ ((Lisp_Object, Lisp_Object, int *));
    allowed keyword/value pairs.  Value is non-zero if SPEC is valid.  */
 
 static int
-parse_image_spec (spec, keywords, nkeywords, type)
-     Lisp_Object spec;
-     struct image_keyword *keywords;
-     int nkeywords;
-     Lisp_Object type;
+parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
+                 int nkeywords, Lisp_Object type)
 {
   int i;
   Lisp_Object plist;
@@ -1059,9 +896,7 @@ parse_image_spec (spec, keywords, nkeywords, type)
    to 1 if KEY was found in SPEC, set it to 0 otherwise.  */
 
 static Lisp_Object
-image_spec_value (spec, key, found)
-     Lisp_Object spec, key;
-     int *found;
+image_spec_value (Lisp_Object spec, Lisp_Object key, int *found)
 {
   Lisp_Object tail;
 
@@ -1142,8 +977,8 @@ or omitted means use the selected frame.  */)
   return mask;
 }
 
-DEFUN ("image-extension-data", Fimage_extension_data, Simage_extension_data, 1, 2, 0,
-       doc: /* Return extension data for image SPEC.
+DEFUN ("image-metadata", Fimage_metadata, Simage_metadata, 1, 2, 0,
+       doc: /* Return metadata for image SPEC.
 FRAME is the frame on which the image will be displayed.  FRAME nil
 or omitted means use the selected frame.  */)
      (spec, frame)
@@ -1168,9 +1003,9 @@ or omitted means use the selected frame.  */)
                 Image type independent image structures
  ***********************************************************************/
 
-static struct image *make_image P_ ((Lisp_Object spec, unsigned hash));
-static void free_image P_ ((struct frame *f, struct image *img));
-static int check_image_size P_ ((struct frame *f, int width, int height));
+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;
@@ -1179,14 +1014,14 @@ Lisp_Object Vmax_image_size;
    SPEC.  SPEC has a hash value of HASH.  */
 
 static struct image *
-make_image (spec, hash)
-     Lisp_Object spec;
-     unsigned hash;
+make_image (Lisp_Object spec, unsigned int hash)
 {
   struct image *img = (struct image *) xmalloc (sizeof *img);
+  Lisp_Object file = image_spec_value (spec, QCfile, NULL);
 
   xassert (valid_image_p (spec));
   bzero (img, sizeof *img);
+  img->dependencies = NILP (file) ? Qnil : list1 (file);
   img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
   xassert (img->type != NULL);
   img->spec = spec;
@@ -1201,9 +1036,7 @@ make_image (spec, hash)
 /* Free image IMG which was used on frame F, including its resources.  */
 
 static void
-free_image (f, img)
-     struct frame *f;
-     struct image *img;
+free_image (struct frame *f, struct image *img)
 {
   if (img)
     {
@@ -1230,10 +1063,7 @@ free_image (f, img)
    otherwise, return 0. */
 
 int
-check_image_size (f, width, height)
-     struct frame *f;
-     int width;
-     int height;
+check_image_size (struct frame *f, int width, int height)
 {
   int w, h;
 
@@ -1264,9 +1094,7 @@ check_image_size (f, width, height)
    drawing an image.  */
 
 void
-prepare_image_for_display (f, img)
-     struct frame *f;
-     struct image *img;
+prepare_image_for_display (struct frame *f, struct image *img)
 {
   EMACS_TIME t;
 
@@ -1279,17 +1107,6 @@ prepare_image_for_display (f, img)
   if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
     img->load_failed_p = img->type->load (f, img) == 0;
 
-#if defined (MAC_OS) && USE_CG_DRAWING
-  if (!img->load_failed_p && img->data.ptr_val == NULL)
-    {
-      img->data.ptr_val = mac_create_cg_image_from_image (f, img);
-      if (img->data.ptr_val == NULL)
-       {
-         img->load_failed_p = 1;
-         img->type->free (f, img);
-       }
-    }
-#endif
 }
 
 
@@ -1297,10 +1114,7 @@ prepare_image_for_display (f, img)
    drawn in face FACE.  */
 
 int
-image_ascent (img, face, slice)
-     struct image *img;
-     struct face *face;
-     struct glyph_slice *slice;
+image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
 {
   int height;
   int ascent;
@@ -1326,7 +1140,8 @@ image_ascent (img, face, slice)
             because a typical font is `top-heavy' (due to the presence
             uppercase letters), so the image placement should err towards
             being top-heavy too.  It also just generally looks better.  */
-         ascent = (height + face->font->ascent - face->font->descent + 1) / 2;
+         ascent = (height + FONT_BASE(face->font)
+                    - FONT_DESCENT(face->font) + 1) / 2;
 #endif /* HAVE_NTGUI */
        }
       else
@@ -1345,10 +1160,8 @@ image_ascent (img, face, slice)
    On W32, XIMG is assumed to a device context with the bitmap selected.  */
 
 static RGB_PIXEL_COLOR
-four_corners_best (ximg, corners, width, height)
-     XImagePtr_or_DC ximg;
-     int *corners;
-     unsigned long width, height;
+four_corners_best (XImagePtr_or_DC ximg, int *corners,
+                  unsigned long width, unsigned long height)
 {
   RGB_PIXEL_COLOR corner_pixels[4], best;
   int i, best_count;
@@ -1395,6 +1208,14 @@ four_corners_best (ximg, corners, width, height)
 #define Free_Pixmap(display, pixmap) \
   DeleteObject (pixmap)
 
+#elif defined (HAVE_NS)
+
+#define Destroy_Image(ximg, dummy) \
+  ns_release_object(ximg)
+
+#define Free_Pixmap(display, pixmap) \
+  ns_release_object(pixmap)
+
 #else
 
 #define Destroy_Image(ximg, dummy) \
@@ -1403,7 +1224,7 @@ four_corners_best (ximg, corners, width, height)
 #define Free_Pixmap(display, pixmap) \
   XFreePixmap (display, pixmap)
 
-#endif /* HAVE_NTGUI */
+#endif /* !HAVE_NTGUI && !HAVE_NS */
 
 
 /* Return the `background' field of IMG.  If IMG doesn't have one yet,
@@ -1412,10 +1233,7 @@ four_corners_best (ximg, corners, width, height)
    use for the heuristic.  */
 
 RGB_PIXEL_COLOR
-image_background (img, f, ximg)
-     struct image *img;
-     struct frame *f;
-     XImagePtr_or_DC ximg;
+image_background (struct image *img, struct frame *f, XImagePtr_or_DC ximg)
 {
   if (! img->background_valid)
     /* IMG doesn't have a background yet, try to guess a reasonable value.  */
@@ -1454,10 +1272,7 @@ image_background (img, f, ximg)
    existing XImage object to use for the heuristic.  */
 
 int
-image_background_transparent (img, f, mask)
-     struct image *img;
-     struct frame *f;
-     XImagePtr_or_DC mask;
+image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_DC mask)
 {
   if (! img->background_transparent_valid)
     /* IMG doesn't have a background yet, try to guess a reasonable value.  */
@@ -1502,13 +1317,13 @@ image_background_transparent (img, f, mask)
                  Helper functions for X image types
  ***********************************************************************/
 
-static void x_clear_image_1 P_ ((struct frame *, struct image *, int,
-                                int, int));
-static void x_clear_image P_ ((struct frame *f, struct image *img));
-static unsigned long x_alloc_image_color P_ ((struct frame *f,
-                                             struct image *img,
-                                             Lisp_Object color_name,
-                                             unsigned long dflt));
+static void x_clear_image_1 (struct frame *, struct image *, int,
+                             int, int);
+static void x_clear_image (struct frame *f, struct image *img);
+static unsigned long x_alloc_image_color (struct frame *f,
+                                          struct image *img,
+                                          Lisp_Object color_name,
+                                          unsigned long dflt);
 
 
 /* Clear X resources of image IMG on frame F.  PIXMAP_P non-zero means
@@ -1517,15 +1332,14 @@ static unsigned long x_alloc_image_color P_ ((struct frame *f,
    the image, if any.  */
 
 static void
-x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
-     struct frame *f;
-     struct image *img;
-     int pixmap_p, mask_p, colors_p;
+x_clear_image_1 (struct frame *f, struct image *img, int pixmap_p, int mask_p,
+                int colors_p)
 {
   if (pixmap_p && img->pixmap)
     {
       Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
       img->pixmap = NO_PIXMAP;
+      /* NOTE (HAVE_NS): background color is NOT an indexed color! */
       img->background_valid = 0;
     }
 
@@ -1538,7 +1352,6 @@ x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
 
   if (colors_p && img->ncolors)
     {
-      /* MAC_TODO: color table support.  */
       /* W32_TODO: color table support.  */
 #ifdef HAVE_X_WINDOWS
       x_free_colors (f, img->colors, img->ncolors);
@@ -1548,21 +1361,12 @@ x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
       img->ncolors = 0;
     }
 
-#if defined (MAC_OS) && USE_CG_DRAWING
-  if (img->data.ptr_val)
-    {
-      CGImageRelease (img->data.ptr_val);
-      img->data.ptr_val = NULL;
-    }
-#endif
 }
 
 /* Free X resources of image IMG which is used on frame F.  */
 
 static void
-x_clear_image (f, img)
-     struct frame *f;
-     struct image *img;
+x_clear_image (struct frame *f, struct image *img)
 {
   BLOCK_INPUT;
   x_clear_image_1 (f, img, 1, 1, 1);
@@ -1576,11 +1380,8 @@ x_clear_image (f, img)
    color.  */
 
 static unsigned long
-x_alloc_image_color (f, img, color_name, dflt)
-     struct frame *f;
-     struct image *img;
-     Lisp_Object color_name;
-     unsigned long dflt;
+x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
+                    unsigned long dflt)
 {
   XColor color;
   unsigned long result;
@@ -1610,15 +1411,15 @@ x_alloc_image_color (f, img, color_name, dflt)
                             Image Cache
  ***********************************************************************/
 
-static struct image *search_image_cache P_ ((struct frame *, Lisp_Object, unsigned));
-static void cache_image P_ ((struct frame *f, struct image *img));
-static void postprocess_image P_ ((struct frame *, struct image *));
+static struct image *search_image_cache (struct frame *, Lisp_Object, unsigned);
+static void cache_image (struct frame *f, struct image *img);
+static void postprocess_image (struct frame *, struct image *);
 
 /* Return a new, initialized image cache that is allocated from the
    heap.  Call free_image_cache to free an image cache.  */
 
 struct image_cache *
-make_image_cache ()
+make_image_cache (void)
 {
   struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c);
   int size;
@@ -1636,10 +1437,7 @@ make_image_cache ()
 /* Find an image matching SPEC in the cache, and return it.  If no
    image is found, return NULL.  */
 static struct image *
-search_image_cache (f, spec, hash)
-     struct frame *f;
-     Lisp_Object spec;
-     unsigned hash;
+search_image_cache (struct frame *f, Lisp_Object spec, unsigned int hash)
 {
   struct image *img;
   struct image_cache *c = FRAME_IMAGE_CACHE (f);
@@ -1672,9 +1470,7 @@ search_image_cache (f, spec, hash)
 /* Search frame F for an image with spec SPEC, and free it.  */
 
 static void
-uncache_image (f, spec)
-     struct frame *f;
-     Lisp_Object spec;
+uncache_image (struct frame *f, Lisp_Object spec)
 {
   struct image *img = search_image_cache (f, spec, sxhash (spec, 0));
   if (img)
@@ -1686,8 +1482,7 @@ uncache_image (f, spec)
    caches.  */
 
 void
-free_image_cache (f)
-     struct frame *f;
+free_image_cache (struct frame *f)
 {
   struct image_cache *c = FRAME_IMAGE_CACHE (f);
   if (c)
@@ -1707,41 +1502,69 @@ free_image_cache (f)
 }
 
 
-/* Clear image cache of frame F.  FORCE_P non-zero means free all
-   images.  FORCE_P zero means clear only images that haven't been
-   displayed for some time.  Should be called from time to time to
-   reduce the number of loaded images.  If image-cache-eviction-delay
-   is non-nil, this frees images in the cache which weren't displayed
-   for at least that many seconds.  */
+/* Clear image cache of frame F.  FILTER=t means free all images.
+   FILTER=nil means clear only images that haven't been
+   displayed for some time.
+   Else, only free the images which have FILTER in their `dependencies'.
+   Should be called from time to time to reduce the number of loaded images.
+   If image-cache-eviction-delay is non-nil, this frees images in the cache
+   which weren't displayed for at least that many seconds.  */
 
 void
-clear_image_cache (f, force_p)
-     struct frame *f;
-     int force_p;
+clear_image_cache (struct frame *f, Lisp_Object filter)
 {
   struct image_cache *c = FRAME_IMAGE_CACHE (f);
 
-  if (c && INTEGERP (Vimage_cache_eviction_delay))
+  if (c)
     {
-      EMACS_TIME t;
-      unsigned long old;
-      int i, nfreed;
-
-      EMACS_GET_TIME (t);
-      old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay);
+      int i, nfreed = 0;
 
       /* Block input so that we won't be interrupted by a SIGIO
         while being in an inconsistent state.  */
       BLOCK_INPUT;
 
-      for (i = nfreed = 0; i < c->used; ++i)
+      if (!NILP (filter))
+       {
+         /* Filter image cache.  */
+         for (i = 0; i < c->used; ++i)
+           {
+             struct image *img = c->images[i];
+             if (img && (EQ (Qt, filter)
+                         || !NILP (Fmember (filter, img->dependencies))))
+               {
+                 free_image (f, img);
+                 ++nfreed;
+               }
+           }
+       }
+      else if (INTEGERP (Vimage_cache_eviction_delay))
        {
-         struct image *img = c->images[i];
-         if (img != NULL
-             && (force_p || img->timestamp < old))
+         /* Free cache based on timestamp.  */
+         EMACS_TIME t;
+         unsigned long old;
+         int delay, nimages = 0;
+
+         for (i = 0; i < c->used; ++i)
+           if (c->images[i])
+             nimages++;
+
+         /* If the number of cached images has grown unusually large,
+            decrease the cache eviction delay (Bug#6230).  */
+         delay = XFASTINT (Vimage_cache_eviction_delay);
+         if (nimages > 40)
+           delay = max (1, 1600 * delay / (nimages*nimages));
+
+         EMACS_GET_TIME (t);
+         old = EMACS_SECS (t) - delay;
+
+         for (i = 0; i < c->used; ++i)
            {
-             free_image (f, img);
-             ++nfreed;
+             struct image *img = c->images[i];
+             if (img && img->timestamp < old)
+               {
+                 free_image (f, img);
+                 ++nfreed;
+               }
            }
        }
 
@@ -1768,7 +1591,7 @@ clear_image_cache (f, force_p)
 }
 
 void
-clear_image_caches (int force_p)
+clear_image_caches (Lisp_Object filter)
 {
   /* FIXME: We want to do
    * struct terminal *t;
@@ -1777,31 +1600,35 @@ clear_image_caches (int force_p)
   Lisp_Object tail, frame;
   FOR_EACH_FRAME (tail, frame)
     if (FRAME_WINDOW_P (XFRAME (frame)))
-      clear_image_cache (XFRAME (frame), force_p);
+      clear_image_cache (XFRAME (frame), filter);
 }
 
 DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
        0, 1, 0,
-       doc: /* Clear the image cache of FRAME.
-FRAME nil or omitted means use the selected frame.
-FRAME t means clear the image caches of all frames.  */)
-     (frame)
-     Lisp_Object frame;
-{
-  if (EQ (frame, Qt))
-    clear_image_caches (1);
+       doc: /* Clear the image cache.
+FILTER nil or a frame means clear all images in the selected frame.
+FILTER t means clear the image caches of all frames.
+Anything else, means only clear those images which refer to FILTER,
+which is then usually a filename.  */)
+     (filter)
+     Lisp_Object filter;
+{
+  if (!(EQ (filter, Qnil) || FRAMEP (filter)))
+    clear_image_caches (filter);
   else
-    clear_image_cache (check_x_frame (frame), 1);
+    clear_image_cache (check_x_frame (filter), Qt);
 
   return Qnil;
 }
 
 
-DEFUN ("image-refresh", Fimage_refresh, Simage_refresh,
+DEFUN ("image-flush", Fimage_flush, Simage_flush,
        1, 2, 0,
-       doc: /* Refresh the image with specification SPEC on frame FRAME.
-If SPEC specifies an image file, the displayed image is updated with
-the current contents of that file.
+       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.
+
 FRAME nil or omitted means use the selected frame.
 FRAME t means refresh the image on all frames.  */)
      (spec, frame)
@@ -1831,9 +1658,7 @@ FRAME t means refresh the image on all frames.  */)
    by the image's specification,  */
 
 static void
-postprocess_image (f, img)
-     struct frame *f;
-     struct image *img;
+postprocess_image (struct frame *f, struct image *img)
 {
   /* Manipulation of the image's mask.  */
   if (img->pixmap)
@@ -1906,9 +1731,7 @@ postprocess_image (f, img)
    SPEC must be a valid Lisp image specification (see valid_image_p).  */
 
 int
-lookup_image (f, spec)
-     struct frame *f;
-     Lisp_Object spec;
+lookup_image (struct frame *f, Lisp_Object spec)
 {
   struct image_cache *c;
   struct image *img;
@@ -2028,9 +1851,7 @@ lookup_image (f, spec)
 /* Cache image IMG in the image cache of frame F.  */
 
 static void
-cache_image (f, img)
-     struct frame *f;
-     struct image *img;
+cache_image (struct frame *f, struct image *img)
 {
   struct image_cache *c = FRAME_IMAGE_CACHE (f);
   int i;
@@ -2070,10 +1891,10 @@ cache_image (f, img)
 /* Mark Lisp objects in image IMG.  */
 
 static void
-mark_image (img)
-     struct image *img;
+mark_image (struct image *img)
 {
   mark_object (img->spec);
+  mark_object (img->dependencies);
 
   if (!NILP (img->data.lisp_val))
     mark_object (img->data.lisp_val);
@@ -2095,7 +1916,7 @@ mark_image_cache (struct image_cache *c)
 
 \f
 /***********************************************************************
-                         X / MAC / W32 support code
+                         X / NS / W32 support code
  ***********************************************************************/
 
 #ifdef HAVE_NTGUI
@@ -2138,10 +1959,10 @@ w32_delayed_load (Lisp_Object libraries, Lisp_Object type)
 
 #endif /* HAVE_NTGUI */
 
-static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
-                                           XImagePtr *, Pixmap *));
-static void x_destroy_x_image P_ ((XImagePtr));
-static void x_put_x_image P_ ((struct frame *, XImagePtr, Pixmap, int, int));
+static int x_create_x_image_and_pixmap (struct frame *, int, int, int,
+                                        XImagePtr *, Pixmap *);
+static void x_destroy_x_image (XImagePtr);
+static void x_put_x_image (struct frame *, XImagePtr, Pixmap, int, int);
 
 
 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
@@ -2154,11 +1975,8 @@ static void x_put_x_image P_ ((struct frame *, XImagePtr, Pixmap, int, int));
    should indicate the bit depth of the image.  */
 
 static int
-x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
-     struct frame *f;
-     int width, height, depth;
-     XImagePtr *ximg;
-     Pixmap *pixmap;
+x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
+                            XImagePtr *ximg, Pixmap *pixmap)
 {
 #ifdef HAVE_X_WINDOWS
   Display *display = FRAME_X_DISPLAY (f);
@@ -2280,34 +2098,24 @@ x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
 
 #endif /* HAVE_NTGUI */
 
-#ifdef MAC_OS
-  Display *display = FRAME_X_DISPLAY (f);
-  Window window = FRAME_X_WINDOW (f);
-
-  xassert (interrupt_input_blocked);
-
-  /* Allocate a pixmap of the same size.  */
-  *pixmap = XCreatePixmap (display, window, width, height, depth);
-  if (*pixmap == NO_PIXMAP)
+#ifdef HAVE_NS
+  *pixmap = ns_image_for_XPM(width, height, depth);
+  if (*pixmap == 0)
     {
       *ximg = NULL;
-      image_error ("Unable to create X pixmap", Qnil, Qnil);
+      image_error ("Unable to allocate NSImage for XPM pixmap", Qnil, Qnil);
       return 0;
     }
-
-  LockPixels (GetGWorldPixMap (*pixmap));
   *ximg = *pixmap;
   return 1;
-
-#endif  /* MAC_OS */
+#endif
 }
 
 
 /* Destroy XImage XIMG.  Free XIMG->data.  */
 
 static void
-x_destroy_x_image (ximg)
-     XImagePtr ximg;
+x_destroy_x_image (XImagePtr ximg)
 {
   xassert (interrupt_input_blocked);
   if (ximg)
@@ -2322,9 +2130,9 @@ x_destroy_x_image (ximg)
       ximg->data = NULL;
       xfree (ximg);
 #endif /* HAVE_NTGUI */
-#ifdef MAC_OS
-      XDestroyImage (ximg);
-#endif /* MAC_OS */
+#ifdef HAVE_NS
+      ns_release_object(ximg);
+#endif /* HAVE_NS */
     }
 }
 
@@ -2333,11 +2141,7 @@ x_destroy_x_image (ximg)
    are width and height of both the image and pixmap.  */
 
 static void
-x_put_x_image (f, ximg, pixmap, width, height)
-     struct frame *f;
-     XImagePtr ximg;
-     Pixmap pixmap;
-     int width, height;
+x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int height)
 {
 #ifdef HAVE_X_WINDOWS
   GC gc;
@@ -2356,9 +2160,10 @@ x_put_x_image (f, ximg, pixmap, width, height)
 #endif
 #endif /* HAVE_NTGUI */
 
-#ifdef MAC_OS
+#ifdef HAVE_NS
   xassert (ximg == pixmap);
-#endif  /* MAC_OS */
+  ns_retain_object(ximg);
+#endif
 }
 
 \f
@@ -2366,7 +2171,7 @@ x_put_x_image (f, ximg, pixmap, width, height)
                              File Handling
  ***********************************************************************/
 
-static unsigned char *slurp_file P_ ((char *, int *));
+static unsigned char *slurp_file (char *, int *);
 
 
 /* Find image file FILE.  Look in data-directory/images, then
@@ -2374,8 +2179,7 @@ static unsigned char *slurp_file P_ ((char *, int *));
    found, or nil if not found.  */
 
 Lisp_Object
-x_find_image_file (file)
-     Lisp_Object file;
+x_find_image_file (Lisp_Object file)
 {
   Lisp_Object file_found, search_path;
   struct gcpro gcpro1, gcpro2;
@@ -2410,9 +2214,7 @@ x_find_image_file (file)
    occurred.  *SIZE is set to the size of the file.  */
 
 static unsigned char *
-slurp_file (file, size)
-     char *file;
-     int *size;
+slurp_file (char *file, int *size)
 {
   FILE *fp = NULL;
   unsigned char *buf = NULL;
@@ -2441,381 +2243,20 @@ slurp_file (file, size)
 }
 
 
-\f
-#ifdef MAC_OS
-
-/***********************************************************************
-                       MAC Image Load Functions
- ***********************************************************************/
-
-static int image_load_quicktime P_ ((struct frame *, struct image *img,
-                                    OSType));
-#ifdef MAC_OSX
-static int image_load_quartz2d P_ ((struct frame *, struct image *img, int));
-#endif
-
-static OSErr
-find_image_fsspec (specified_file, file, fss)
-     Lisp_Object specified_file, *file;
-     FSSpec *fss;
-{
-  OSErr err;
-  AEDesc desc;
-
-  *file = x_find_image_file (specified_file);
-  if (!STRINGP (*file))
-    return fnfErr;             /* file or directory not found;
-                                  incomplete pathname */
-  /* Try to open the image file.  */
-  err = AECoercePtr (TYPE_FILE_NAME, SDATA (*file),
-                    SBYTES (*file), typeFSS, &desc);
-  if (err == noErr)
-    {
-#if TARGET_API_MAC_CARBON
-      err = AEGetDescData (&desc, fss, sizeof (FSSpec));
-#else
-      *fss = *(FSSpec *)(*(desc.dataHandle));
-#endif
-      AEDisposeDesc (&desc);
-    }
-  return err;
-}
-
-static int
-image_load_qt_1 (f, img, type, fss, dh)
-     struct frame *f;
-     struct image *img;
-     OSType type;
-     const FSSpec *fss;
-     Handle dh;
-{
-  ComponentResult err;
-  GraphicsImportComponent gi;
-  Rect rect;
-  int width, height;
-  ImageDescriptionHandle desc_handle;
-  short draw_all_pixels;
-  Lisp_Object specified_bg;
-  XColor color;
-  XImagePtr ximg;
-  RGBColor bg_color;
-
-  err = OpenADefaultComponent (GraphicsImporterComponentType, type, &gi);
-  if (err != noErr)
-    {
-      image_error ("Cannot get importer component for `%s'", img->spec, Qnil);
-      return 0;
-    }
-  if (dh == NULL)
-    {
-      /* read from file system spec */
-      err = GraphicsImportSetDataFile (gi, fss);
-      if (err != noErr)
-       {
-         image_error ("Cannot set fsspec to graphics importer for '%s'",
-                      img->spec, Qnil);
-         goto error;
-       }
-    }
-  else
-    {
-      /* read from data handle */
-      err = GraphicsImportSetDataHandle (gi, dh);
-      if (err != noErr)
-       {
-         image_error ("Cannot set data handle to graphics importer for `%s'",
-                      img->spec, Qnil);
-         goto error;
-       }
-    }
-  err = GraphicsImportGetImageDescription (gi, &desc_handle);
-  if (err != noErr || desc_handle == NULL)
-    {
-      image_error ("Error reading `%s'", img->spec, Qnil);
-      goto error;
-    }
-  width = img->width = (*desc_handle)->width;
-  height = img->height = (*desc_handle)->height;
-  DisposeHandle ((Handle)desc_handle);
-
-  if (!check_image_size (f, width, height))
-    {
-      image_error ("Invalid image size", Qnil, Qnil);
-      goto error;
-    }
-
-  err = GraphicsImportDoesDrawAllPixels (gi, &draw_all_pixels);
-#if 0
-  /* Don't check the error code here.  It may have an undocumented
-     value -32766. */
-  if (err != noErr)
-    {
-      image_error ("Error reading `%s'", img->spec, Qnil);
-      goto error;
-    }
-#endif
-  if (draw_all_pixels != graphicsImporterDrawsAllPixels)
-    {
-      specified_bg = image_spec_value (img->spec, QCbackground, NULL);
-      if (!STRINGP (specified_bg) ||
-         !mac_defined_color (f, SDATA (specified_bg), &color, 0))
-       {
-         color.pixel = FRAME_BACKGROUND_PIXEL (f);
-         color.red = RED16_FROM_ULONG (color.pixel);
-         color.green = GREEN16_FROM_ULONG (color.pixel);
-         color.blue = BLUE16_FROM_ULONG (color.pixel);
-       }
-    }
-
-  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
-    goto error;
-  if (draw_all_pixels != graphicsImporterDrawsAllPixels)
-    {
-      CGrafPtr old_port;
-      GDHandle old_gdh;
-
-      GetGWorld (&old_port, &old_gdh);
-      SetGWorld (ximg, NULL);
-      bg_color.red = color.red;
-      bg_color.green = color.green;
-      bg_color.blue = color.blue;
-      RGBBackColor (&bg_color);
-#if TARGET_API_MAC_CARBON
-      GetPortBounds (ximg, &rect);
-      EraseRect (&rect);
-#else
-      EraseRect (&(ximg->portRect));
-#endif
-      SetGWorld (old_port, old_gdh);
-    }
-  GraphicsImportSetGWorld (gi, ximg, NULL);
-  GraphicsImportDraw (gi);
-  CloseComponent (gi);
-
-  /* Maybe fill in the background field while we have ximg handy. */
-  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
-    IMAGE_BACKGROUND (img, f, ximg);
-
-  /* Put the image into the pixmap.  */
-  x_put_x_image (f, ximg, img->pixmap, width, height);
-  x_destroy_x_image (ximg);
-  return 1;
-
- error:
-  CloseComponent (gi);
-  return 0;
-}
-
-
-/* Load an image using the QuickTime Graphics Importer.
-   Note: The alpha channel does not work for PNG images. */
-static int
-image_load_quicktime (f, img, type)
-     struct frame *f;
-     struct image *img;
-     OSType type;
-{
-  Lisp_Object specified_file;
-  Lisp_Object specified_data;
-  OSErr err;
-
-  specified_file = image_spec_value (img->spec, QCfile, NULL);
-  specified_data = image_spec_value (img->spec, QCdata, NULL);
-
-  if (NILP (specified_data))
-    {
-      /* Read from a file */
-      Lisp_Object file;
-      FSSpec fss;
-
-      err = find_image_fsspec (specified_file, &file, &fss);
-      if (err != noErr)
-       {
-         if (err == fnfErr)
-           image_error ("Cannot find image file `%s'", specified_file, Qnil);
-         else
-           image_error ("Cannot open `%s'", file, Qnil);
-         return 0;
-       }
-      return image_load_qt_1 (f, img, type, &fss, NULL);
-    }
-  else
-    {
-      /* Memory source! */
-      int success_p;
-      Handle dh;
-
-      err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data));
-      if (err != noErr)
-       {
-         image_error ("Cannot allocate data handle for `%s'",
-                      img->spec, Qnil);
-         return 0;
-       }
-      success_p = image_load_qt_1 (f, img, type, NULL, dh);
-      DisposeHandle (dh);
-      return success_p;
-    }
-}
-
-
-#ifdef MAC_OSX
-/* Load a PNG/JPEG image using Quartz 2D decoding routines.
-   CGImageCreateWithPNGDataProvider is provided after Mac OS X 10.2.
-   So don't use this function directly but determine at runtime
-   whether it exists. */
-typedef CGImageRef (*CGImageCreateWithPNGDataProviderProcType)
-  (CGDataProviderRef, const float [], bool, CGColorRenderingIntent);
-static CGImageCreateWithPNGDataProviderProcType MyCGImageCreateWithPNGDataProvider;
-
-
-static void
-init_image_func_pointer ()
-{
-  if (NSIsSymbolNameDefined ("_CGImageCreateWithPNGDataProvider"))
-    {
-      MyCGImageCreateWithPNGDataProvider
-       = (CGImageCreateWithPNGDataProviderProcType)
-       NSAddressOfSymbol (NSLookupAndBindSymbol
-                          ("_CGImageCreateWithPNGDataProvider"));
-    }
-  else
-    MyCGImageCreateWithPNGDataProvider = NULL;
-}
-
-
-static int
-image_load_quartz2d (f, img, png_p)
-     struct frame *f;
-     struct image *img;
-     int png_p;
-{
-  Lisp_Object file, specified_file;
-  Lisp_Object specified_data, specified_bg;
-  struct gcpro gcpro1;
-  CGDataProviderRef source;
-  CGImageRef image;
-  int width, height;
-  XColor color;
-  XImagePtr ximg = NULL;
-  CGContextRef context;
-  CGRect rectangle;
-
-  /* Open the 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))
-    {
-      CFStringRef path;
-      CFURLRef url;
-
-      file = x_find_image_file (specified_file);
-      if (!STRINGP (file))
-       {
-         image_error ("Cannot find image file `%s'", specified_file, Qnil);
-         UNGCPRO;
-         return 0;
-       }
-      path = cfstring_create_with_utf8_cstring (SDATA (file));
-      url = CFURLCreateWithFileSystemPath (NULL, path,
-                                          kCFURLPOSIXPathStyle, 0);
-      CFRelease (path);
-      source = CGDataProviderCreateWithURL (url);
-      CFRelease (url);
-    }
-  else
-    source = CGDataProviderCreateWithData (NULL, SDATA (specified_data),
-                                          SBYTES (specified_data), NULL);
-
-  if (png_p)
-    image = (*MyCGImageCreateWithPNGDataProvider) (source, NULL, FALSE,
-                                                  kCGRenderingIntentDefault);
-  else
-    image = CGImageCreateWithJPEGDataProvider (source, NULL, FALSE,
-                                              kCGRenderingIntentDefault);
-
-  CGDataProviderRelease (source);
-  if (image == NULL)
-    {
-      UNGCPRO;
-      image_error ("Error reading image `%s'", img->spec, Qnil);
-      return 0;
-    }
-  width = img->width = CGImageGetWidth (image);
-  height = img->height = CGImageGetHeight (image);
-
-  if (!check_image_size (f, width, height))
-    {
-      CGImageRelease (image);
-      UNGCPRO;
-      image_error ("Invalid image size", Qnil, Qnil);
-      return 0;
-    }
-
-  if (png_p)
-    {
-      specified_bg = image_spec_value (img->spec, QCbackground, NULL);
-      if (!STRINGP (specified_bg) ||
-         !mac_defined_color (f, SDATA (specified_bg), &color, 0))
-       {
-         color.pixel = FRAME_BACKGROUND_PIXEL (f);
-         color.red = RED16_FROM_ULONG (color.pixel);
-         color.green = GREEN16_FROM_ULONG (color.pixel);
-         color.blue = BLUE16_FROM_ULONG (color.pixel);
-       }
-    }
-
-  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
-    {
-      CGImageRelease (image);
-      UNGCPRO;
-      return 0;
-    }
-  rectangle = CGRectMake (0, 0, width, height);
-  QDBeginCGContext (ximg, &context);
-  if (png_p)
-    {
-      CGContextSetRGBFillColor (context, color.red / 65535.0,
-                               color.green / 65535.0,
-                               color.blue / 65535.0, 1.0);
-      CGContextFillRect (context, rectangle);
-    }
-  CGContextDrawImage (context, rectangle, image);
-  QDEndCGContext (ximg, &context);
-  CGImageRelease (image);
-
-  /* Maybe fill in the background field while we have ximg handy. */
-  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
-    IMAGE_BACKGROUND (img, f, ximg);
-
-  /* Put the image into the pixmap.  */
-  x_put_x_image (f, ximg, img->pixmap, width, height);
-  x_destroy_x_image (ximg);
-  UNGCPRO;
-  return 1;
-}
-#endif
-
-#endif  /* MAC_OS */
-
 \f
 /***********************************************************************
                              XBM images
  ***********************************************************************/
 
-static int xbm_scan P_ ((unsigned char **, unsigned char *, char *, int *));
-static int xbm_load P_ ((struct frame *f, struct image *img));
-static int xbm_load_image P_ ((struct frame *f, struct image *img,
-                              unsigned char *, unsigned char *));
-static int xbm_image_p P_ ((Lisp_Object object));
-static int xbm_read_bitmap_data P_ ((struct frame *f,
-                                    unsigned char *, unsigned char *,
-                                    int *, int *, unsigned char **));
-static int xbm_file_p P_ ((Lisp_Object));
+static int xbm_scan (unsigned char **, unsigned char *, char *, int *);
+static int xbm_load (struct frame *f, struct image *img);
+static int xbm_load_image (struct frame *f, struct image *img,
+                           unsigned char *, unsigned char *);
+static int xbm_image_p (Lisp_Object object);
+static int xbm_read_bitmap_data (struct frame *f,
+                                 unsigned char *, unsigned char *,
+                                 int *, int *, unsigned char **, int);
+static int xbm_file_p (Lisp_Object);
 
 
 /* Indices of image specification fields in xbm_format, below.  */
@@ -2841,7 +2282,7 @@ enum xbm_keyword_index
 /* Vector of image_keyword structures describing the format
    of valid XBM image specifications.  */
 
-static struct image_keyword xbm_format[XBM_LAST] =
+static const struct image_keyword xbm_format[XBM_LAST] =
 {
   {":type",            IMAGE_SYMBOL_VALUE,                     1},
   {":file",            IMAGE_STRING_VALUE,                     0},
@@ -2908,8 +2349,7 @@ enum xbm_token
    displayed is used.  */
 
 static int
-xbm_image_p (object)
-     Lisp_Object object;
+xbm_image_p (Lisp_Object object)
 {
   struct image_keyword kw[XBM_LAST];
 
@@ -3002,10 +2442,7 @@ xbm_image_p (object)
    scanning a number, store its value in *IVAL.  */
 
 static int
-xbm_scan (s, end, sval, ival)
-     unsigned char **s, *end;
-     char *sval;
-     int *ival;
+xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival)
 {
   unsigned int c;
 
@@ -3169,12 +2606,9 @@ convert_mono_to_color_image (f, img, foreground, background)
 
 
 static void
-Create_Pixmap_From_Bitmap_Data (f, img, data, fg, bg, non_default_colors)
-     struct frame *f;
-     struct image *img;
-     char *data;
-     RGB_PIXEL_COLOR fg, bg;
-     int non_default_colors;
+Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
+                               RGB_PIXEL_COLOR fg, RGB_PIXEL_COLOR bg,
+                               int non_default_colors)
 {
 #ifdef HAVE_NTGUI
   img->pixmap
@@ -3183,6 +2617,10 @@ Create_Pixmap_From_Bitmap_Data (f, img, data, fg, bg, non_default_colors)
   /* If colors were specified, transfer the bitmap to a color one.  */
   if (non_default_colors)
     convert_mono_to_color_image (f, img, fg, bg);
+
+#elif defined (HAVE_NS)
+  img->pixmap = ns_image_from_XBM(data, img->width, img->height);
+
 #else
   img->pixmap
     = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
@@ -3191,7 +2629,7 @@ Create_Pixmap_From_Bitmap_Data (f, img, data, fg, bg, non_default_colors)
                                   img->width, img->height,
                                   fg, bg,
                                   DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
-#endif /* HAVE_NTGUI */
+#endif /* !HAVE_NTGUI && !HAVE_NS */
 }
 
 
@@ -3201,14 +2639,14 @@ Create_Pixmap_From_Bitmap_Data (f, img, data, fg, bg, non_default_colors)
    buffer's end.  Set *WIDTH and *HEIGHT to the width and height of
    the image.  Return in *DATA the bitmap data allocated with xmalloc.
    Value is non-zero if successful.  DATA null means just test if
-   CONTENTS looks like an in-memory XBM file.  */
+   CONTENTS looks like an in-memory XBM file.  If INHIBIT_IMAGE_ERROR
+   is non-zero, inhibit the call to image_error when the image size is
+   invalid (the bitmap remains unread).  */
 
 static int
-xbm_read_bitmap_data (f, contents, end, width, height, data)
-     struct frame *f;
-     unsigned char *contents, *end;
-     int *width, *height;
-     unsigned char **data;
+xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *end,
+                     int *width, int *height, unsigned char **data,
+                     int inhibit_image_error)
 {
   unsigned char *s = contents;
   char buffer[BUFSIZ];
@@ -3259,7 +2697,11 @@ xbm_read_bitmap_data (f, contents, end, width, height, data)
     }
 
   if (!check_image_size (f, *width, *height))
-    goto failure;
+    {
+      if (!inhibit_image_error)
+       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
+      goto failure;
+    }
   else if (data == NULL)
     goto success;
 
@@ -3353,16 +2795,15 @@ xbm_read_bitmap_data (f, contents, end, width, height, data)
    successful.  */
 
 static int
-xbm_load_image (f, img, contents, end)
-     struct frame *f;
-     struct image *img;
-     unsigned char *contents, *end;
+xbm_load_image (struct frame *f, struct image *img, unsigned char *contents,
+               unsigned char *end)
 {
   int rc;
   unsigned char *data;
   int success_p = 0;
 
-  rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height, &data);
+  rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height,
+                            &data, 0);
   if (rc)
     {
       unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
@@ -3411,15 +2852,13 @@ xbm_load_image (f, img, contents, end)
 /* Value is non-zero if DATA looks like an in-memory XBM file.  */
 
 static int
-xbm_file_p (data)
-     Lisp_Object data;
+xbm_file_p (Lisp_Object data)
 {
   int w, h;
   return (STRINGP (data)
          && xbm_read_bitmap_data (NULL, SDATA (data),
-                                  (SDATA (data)
-                                   + SBYTES (data)),
-                                  &w, &h, NULL));
+                                  (SDATA (data) + SBYTES (data)),
+                                  &w, &h, NULL, 1));
 }
 
 
@@ -3427,9 +2866,7 @@ xbm_file_p (data)
    non-zero if successful.  */
 
 static int
-xbm_load (f, img)
-     struct frame *f;
-     struct image *img;
+xbm_load (struct frame *f, struct image *img)
 {
   int success_p = 0;
   Lisp_Object file_name;
@@ -3543,7 +2980,7 @@ xbm_load (f, img)
             int nbytes, i;
             /* Windows mono bitmaps are reversed compared with X.  */
             invertedBits = bits;
-            nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR 
+            nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR
               * img->height;
             bits = (char *) alloca(nbytes);
             for (i = 0; i < nbytes; i++)
@@ -3575,13 +3012,13 @@ xbm_load (f, img)
                              XPM images
  ***********************************************************************/
 
-#if defined (HAVE_XPM) || defined (MAC_OS)
+#if defined (HAVE_XPM) || defined (HAVE_NS)
 
-static int xpm_image_p P_ ((Lisp_Object object));
-static int xpm_load P_ ((struct frame *f, struct image *img));
-static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
+static int xpm_image_p (Lisp_Object object);
+static int xpm_load (struct frame *f, struct image *img);
+static int xpm_valid_color_symbols_p (Lisp_Object);
 
-#endif /* HAVE_XPM || MAC_OS */
+#endif /* HAVE_XPM || HAVE_NS */
 
 #ifdef HAVE_XPM
 #ifdef HAVE_NTGUI
@@ -3604,7 +3041,7 @@ static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
 #endif /* HAVE_NTGUI */
 #endif /* HAVE_XPM */
 
-#if defined (HAVE_XPM) || defined (MAC_OS)
+#if defined (HAVE_XPM) || defined (HAVE_NS)
 /* The symbol `xpm' identifying XPM-format images.  */
 
 Lisp_Object Qxpm;
@@ -3630,7 +3067,7 @@ enum xpm_keyword_index
 /* Vector of image_keyword structures describing the format
    of valid XPM image specifications.  */
 
-static struct image_keyword xpm_format[XPM_LAST] =
+static const struct image_keyword xpm_format[XPM_LAST] =
 {
   {":type",            IMAGE_SYMBOL_VALUE,                     1},
   {":file",            IMAGE_STRING_VALUE,                     0},
@@ -3670,12 +3107,12 @@ static struct image_type xpm_type =
 
 #ifdef ALLOC_XPM_COLORS
 
-static void xpm_init_color_cache P_ ((struct frame *, XpmAttributes *));
-static void xpm_free_color_cache P_ ((void));
-static int xpm_lookup_color P_ ((struct frame *, char *, XColor *));
-static int xpm_color_bucket P_ ((char *));
-static struct xpm_cached_color *xpm_cache_color P_ ((struct frame *, char *,
-                                                    XColor *, int));
+static void xpm_init_color_cache (struct frame *, XpmAttributes *);
+static void xpm_free_color_cache (void);
+static int xpm_lookup_color (struct frame *, char *, XColor *);
+static int xpm_color_bucket (char *);
+static struct xpm_cached_color *xpm_cache_color (struct frame *, char *,
+                                                 XColor *, int);
 
 /* An entry in a hash table used to cache color definitions of named
    colors.  This cache is necessary to speed up XPM image loading in
@@ -3703,9 +3140,7 @@ struct xpm_cached_color **xpm_color_cache;
 /* Initialize the color cache.  */
 
 static void
-xpm_init_color_cache (f, attrs)
-     struct frame *f;
-     XpmAttributes *attrs;
+xpm_init_color_cache (struct frame *f, XpmAttributes *attrs)
 {
   size_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
   xpm_color_cache = (struct xpm_cached_color **) xmalloc (nbytes);
@@ -3731,7 +3166,7 @@ xpm_init_color_cache (f, attrs)
 /* Free the color cache.  */
 
 static void
-xpm_free_color_cache ()
+xpm_free_color_cache (void)
 {
   struct xpm_cached_color *p, *next;
   int i;
@@ -3752,8 +3187,7 @@ xpm_free_color_cache ()
    cache.  */
 
 static int
-xpm_color_bucket (color_name)
-     char *color_name;
+xpm_color_bucket (char *color_name)
 {
   unsigned h = 0;
   char *s;
@@ -3769,11 +3203,7 @@ xpm_color_bucket (color_name)
    entry added.  */
 
 static struct xpm_cached_color *
-xpm_cache_color (f, color_name, color, bucket)
-     struct frame *f;
-     char *color_name;
-     XColor *color;
-     int bucket;
+xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
 {
   size_t nbytes;
   struct xpm_cached_color *p;
@@ -3796,10 +3226,7 @@ xpm_cache_color (f, color_name, color, bucket)
    allocation failed.  */
 
 static int
-xpm_lookup_color (f, color_name, color)
-     struct frame *f;
-     char *color_name;
-     XColor *color;
+xpm_lookup_color (struct frame *f, char *color_name, XColor *color)
 {
   struct xpm_cached_color *p;
   int h = xpm_color_bucket (color_name);
@@ -3836,12 +3263,8 @@ xpm_lookup_color (f, color_name, color)
    if successful.  */
 
 static int
-xpm_alloc_color (dpy, cmap, color_name, color, closure)
-     Display *dpy;
-     Colormap cmap;
-     char *color_name;
-     XColor *color;
-     void *closure;
+xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color,
+                void *closure)
 {
   return xpm_lookup_color ((struct frame *) closure, color_name, color);
 }
@@ -3852,12 +3275,7 @@ xpm_alloc_color (dpy, cmap, color_name, color, closure)
    non-zero if successful.  */
 
 static int
-xpm_free_colors (dpy, cmap, pixels, npixels, closure)
-     Display *dpy;
-     Colormap cmap;
-     Pixel *pixels;
-     int npixels;
-     void *closure;
+xpm_free_colors (Display *dpy, Colormap cmap, Pixel *pixels, int npixels, void *closure)
 {
   return 1;
 }
@@ -3897,8 +3315,7 @@ init_xpm_functions (Lisp_Object libraries)
    cdr are strings.  */
 
 static int
-xpm_valid_color_symbols_p (color_symbols)
-     Lisp_Object color_symbols;
+xpm_valid_color_symbols_p (Lisp_Object color_symbols)
 {
   while (CONSP (color_symbols))
     {
@@ -3917,8 +3334,7 @@ xpm_valid_color_symbols_p (color_symbols)
 /* Value is non-zero if OBJECT is a valid XPM image specification.  */
 
 static int
-xpm_image_p (object)
-     Lisp_Object object;
+xpm_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[XPM_LAST];
   bcopy (xpm_format, fmt, sizeof fmt);
@@ -3931,13 +3347,11 @@ xpm_image_p (object)
              || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
 }
 
-#endif /* HAVE_XPM || MAC_OS */
+#endif /* HAVE_XPM || HAVE_NS */
 
 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
 int
-x_create_bitmap_from_xpm_data (f, bits)
-     struct frame *f;
-     char **bits;
+x_create_bitmap_from_xpm_data (struct frame *f, char **bits)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   int id, rc;
@@ -3980,9 +3394,7 @@ x_create_bitmap_from_xpm_data (f, bits)
 #ifdef HAVE_XPM
 
 static int
-xpm_load (f, img)
-     struct frame *f;
-     struct image *img;
+xpm_load (struct frame *f, struct image *img)
 {
   int rc;
   XpmAttributes attrs;
@@ -4210,30 +3622,30 @@ xpm_load (f, img)
 
 #endif /* HAVE_XPM */
 
-#ifdef MAC_OS
+#if defined (HAVE_NS) && !defined (HAVE_XPM)
 
-/* XPM support functions for Mac OS where libxpm is not available.
+/* XPM support functions for NS where libxpm is not available.
    Only XPM version 3 (without any extensions) is supported.  */
 
-static int xpm_scan P_ ((const unsigned char **, const unsigned char *,
-                        const unsigned char **, int *));
+static int xpm_scan (const unsigned char **, const unsigned char *,
+                     const unsigned char **, int *);
 static Lisp_Object xpm_make_color_table_v
-  P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
-       Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
-static void xpm_put_color_table_v P_ ((Lisp_Object, const unsigned char *,
-                                      int, Lisp_Object));
-static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object,
-                                             const unsigned char *, int));
+  (void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
+   Lisp_Object (**) (Lisp_Object, const unsigned char *, int));
+static void xpm_put_color_table_v (Lisp_Object, const unsigned char *,
+                                   int, Lisp_Object);
+static Lisp_Object xpm_get_color_table_v (Lisp_Object,
+                                          const unsigned char *, int);
 static Lisp_Object xpm_make_color_table_h
-  P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
-       Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
-static void xpm_put_color_table_h P_ ((Lisp_Object, const unsigned char *,
-                                      int, Lisp_Object));
-static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object,
-                                             const unsigned char *, int));
-static int xpm_str_to_color_key P_ ((const char *));
-static int xpm_load_image P_ ((struct frame *, struct image *,
-                              const unsigned char *, const unsigned char *));
+  (void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
+   Lisp_Object (**) (Lisp_Object, const unsigned char *, int));
+static void xpm_put_color_table_h (Lisp_Object, const unsigned char *,
+                                   int, Lisp_Object);
+static Lisp_Object xpm_get_color_table_h (Lisp_Object,
+                                          const unsigned char *, int);
+static int xpm_str_to_color_key (const char *);
+static int xpm_load_image (struct frame *, struct image *,
+                           const unsigned char *, const unsigned char *);
 
 /* Tokens returned from xpm_scan.  */
 
@@ -4269,8 +3681,8 @@ xpm_scan (s, end, beg, len)
       if (isalpha (c) || c == '_' || c == '-' || c == '+')
        {
          *beg = *s - 1;
-         while (*s < end &&
-                (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
+         while (*s < end
+                && (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
              ++*s;
          *len = *s - *beg;
          return XPM_TK_IDENT;
@@ -4469,7 +3881,7 @@ xpm_load_image (f, img, contents, end)
 
   if (!check_image_size (f, width, height))
     {
-      image_error ("Invalid image size", Qnil, Qnil);
+      image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       goto failure;
     }
 
@@ -4546,7 +3958,7 @@ xpm_load_image (f, img, contents, end)
 
          if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
            {
-             if (xstricmp (SDATA (XCDR (specified_color)), "None") == 0)
+             if (xstrcasecmp (SDATA (XCDR (specified_color)), "None") == 0)
                color_val = Qt;
              else if (x_defined_color (f, SDATA (XCDR (specified_color)),
                                        &cdef, 0))
@@ -4555,7 +3967,7 @@ xpm_load_image (f, img, contents, end)
        }
       if (NILP (color_val) && max_key > 0)
        {
-         if (xstricmp (max_color, "None") == 0)
+         if (xstrcasecmp (max_color, "None") == 0)
            color_val = Qt;
          else if (x_defined_color (f, max_color, &cdef, 0))
            color_val = make_number (cdef.pixel);
@@ -4568,8 +3980,11 @@ xpm_load_image (f, img, contents, end)
 
   if (!x_create_x_image_and_pixmap (f, width, height, 0,
                                    &ximg, &img->pixmap)
+#ifndef HAVE_NS
       || !x_create_x_image_and_pixmap (f, width, height, 1,
-                                      &mask_img, &img->mask))
+                                      &mask_img, &img->mask)
+#endif
+      )
     {
       image_error ("Out of memory (%s)", img->spec, Qnil);
       goto error;
@@ -4589,9 +4004,14 @@ xpm_load_image (f, img, contents, end)
          XPutPixel (ximg, x, y,
                     (INTEGERP (color_val) ? XINT (color_val)
                      : FRAME_FOREGROUND_PIXEL (f)));
+#ifndef HAVE_NS
          XPutPixel (mask_img, x, y,
                     (!EQ (color_val, Qt) ? PIX_MASK_DRAW
                      : (have_mask = 1, PIX_MASK_RETAIN)));
+#else
+          if (EQ(color_val, Qt))
+            ns_set_alpha(ximg, x, y, 0);
+#endif
        }
       if (y + 1 < height)
        expect (',');
@@ -4606,6 +4026,7 @@ xpm_load_image (f, img, contents, end)
 
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
+#ifndef HAVE_NS
   if (have_mask)
     {
       /* Fill in the background_transparent field while we have the
@@ -4621,7 +4042,7 @@ xpm_load_image (f, img, contents, end)
       Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
       img->mask = NO_PIXMAP;
     }
-
+#endif
   return 1;
 
  failure:
@@ -4687,7 +4108,7 @@ xpm_load (f, img)
   return success_p;
 }
 
-#endif /* MAC_OS */
+#endif /* HAVE_NS && !HAVE_XPM */
 
 
 \f
@@ -4727,7 +4148,7 @@ int ct_colors_allocated;
 /* Initialize the color table.  */
 
 static void
-init_color_table ()
+init_color_table (void)
 {
   int size = CT_SIZE * sizeof (*ct_table);
   ct_table = (struct ct_color **) xmalloc (size);
@@ -4739,7 +4160,7 @@ init_color_table ()
 /* Free memory associated with the color table.  */
 
 static void
-free_color_table ()
+free_color_table (void)
 {
   int i;
   struct ct_color *p, *next;
@@ -4762,9 +4183,7 @@ free_color_table ()
    G, B, and make an entry in the color table.  */
 
 static unsigned long
-lookup_rgb_color (f, r, g, b)
-     struct frame *f;
-     int r, g, b;
+lookup_rgb_color (struct frame *f, int r, int g, int b)
 {
   unsigned hash = CT_HASH_RGB (r, g, b);
   int i = hash % CT_SIZE;
@@ -4859,9 +4278,7 @@ lookup_rgb_color (f, r, g, b)
    table.  If not already present, allocate it.  Value is PIXEL.  */
 
 static unsigned long
-lookup_pixel_color (f, pixel)
-     struct frame *f;
-     unsigned long pixel;
+lookup_pixel_color (struct frame *f, unsigned long pixel)
 {
   int i = pixel % CT_SIZE;
   struct ct_color *p;
@@ -4913,8 +4330,7 @@ lookup_pixel_color (f, pixel)
    allocated via xmalloc.  Set *N to the number of colors.  */
 
 static unsigned long *
-colors_in_color_table (n)
-     int *n;
+colors_in_color_table (int *n)
 {
   int i, j;
   struct ct_color *p;
@@ -4948,15 +4364,13 @@ lookup_rgb_color (f, r, g, b)
 {
   unsigned long pixel;
 
-#ifdef MAC_OS
-  pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
-  gamma_correct (f, &pixel);
-#endif /* MAC_OS */
-
 #ifdef HAVE_NTGUI
   pixel = PALETTERGB (r >> 8, g >> 8, b >> 8);
 #endif /* HAVE_NTGUI */
 
+#ifdef HAVE_NS
+  pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
+#endif /* HAVE_NS */
   return pixel;
 }
 
@@ -4971,9 +4385,9 @@ init_color_table ()
                              Algorithms
  ***********************************************************************/
 
-static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
-static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
-static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int));
+static XColor *x_to_xcolors (struct frame *, struct image *, int);
+static void x_from_xcolors (struct frame *, struct image *, XColor *);
+static void x_detect_edges (struct frame *, struct image *, int[9], int);
 
 #ifdef HAVE_NTGUI
 static void XPutPixel (XImagePtr , int, int, COLORREF);
@@ -5014,10 +4428,7 @@ static int laplace_matrix[9] = {
    allocated with xmalloc; it must be freed by the caller.  */
 
 static XColor *
-x_to_xcolors (f, img, rgb_p)
-     struct frame *f;
-     struct image *img;
-     int rgb_p;
+x_to_xcolors (struct frame *f, struct image *img, int rgb_p)
 {
   int x, y;
   XColor *colors, *p;
@@ -5048,9 +4459,9 @@ x_to_xcolors (f, img, rgb_p)
     {
       XColor *row = p;
 
-#ifdef HAVE_X_WINDOWS
+#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
       for (x = 0; x < img->width; ++x, ++p)
-       p->pixel = XGetPixel (ximg, x, y);
+       p->pixel = GET_PIXEL (ximg, x, y);
       if (rgb_p)
        x_query_colors (f, row, img->width);
 
@@ -5062,16 +4473,9 @@ x_to_xcolors (f, img, rgb_p)
          p->pixel = GET_PIXEL (ximg, x, y);
          if (rgb_p)
            {
-#ifdef MAC_OS
              p->red = RED16_FROM_ULONG (p->pixel);
              p->green = GREEN16_FROM_ULONG (p->pixel);
              p->blue = BLUE16_FROM_ULONG (p->pixel);
-#endif  /* MAC_OS */
-#ifdef HAVE_NTGUI
-             p->red = 256 * GetRValue (p->pixel);
-             p->green = 256 * GetGValue (p->pixel);
-             p->blue = 256 * GetBValue (p->pixel);
-#endif /* HAVE_NTGUI */
            }
        }
 #endif /* HAVE_X_WINDOWS */
@@ -5137,13 +4541,10 @@ XPutPixel (ximg, x, y, color)
    COLORS will be freed; an existing IMG->pixmap will be freed, too.  */
 
 static void
-x_from_xcolors (f, img, colors)
-     struct frame *f;
-     struct image *img;
-     XColor *colors;
+x_from_xcolors (struct frame *f, struct image *img, XColor *colors)
 {
   int x, y;
-  XImagePtr oimg;
+  XImagePtr oimg = NULL;
   Pixmap pixmap;
   XColor *p;
 
@@ -5182,10 +4583,7 @@ x_from_xcolors (f, img, colors)
    outgoing image.  */
 
 static void
-x_detect_edges (f, img, matrix, color_adjust)
-     struct frame *f;
-     struct image *img;
-     int matrix[9], color_adjust;
+x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjust)
 {
   XColor *colors = x_to_xcolors (f, img, 1);
   XColor *new, *p;
@@ -5251,9 +4649,7 @@ x_detect_edges (f, img, matrix, color_adjust)
    on frame F.  */
 
 static void
-x_emboss (f, img)
-     struct frame *f;
-     struct image *img;
+x_emboss (struct frame *f, struct image *img)
 {
   x_detect_edges (f, img, emboss_matrix, 0xffff / 2);
 }
@@ -5264,9 +4660,7 @@ x_emboss (f, img)
    to draw disabled buttons, for example.  */
 
 static void
-x_laplace (f, img)
-     struct frame *f;
-     struct image *img;
+x_laplace (struct frame *f, struct image *img)
 {
   x_detect_edges (f, img, laplace_matrix, 45000);
 }
@@ -5284,10 +4678,8 @@ x_laplace (f, img)
    number.  */
 
 static void
-x_edge_detection (f, img, matrix, color_adjust)
-     struct frame *f;
-     struct image *img;
-     Lisp_Object matrix, color_adjust;
+x_edge_detection (struct frame *f, struct image *img, Lisp_Object matrix,
+                 Lisp_Object color_adjust)
 {
   int i = 0;
   int trans[9];
@@ -5316,9 +4708,7 @@ x_edge_detection (f, img, matrix, color_adjust)
 /* Transform image IMG on frame F so that it looks disabled.  */
 
 static void
-x_disable_image (f, img)
-     struct frame *f;
-     struct image *img;
+x_disable_image (struct frame *f, struct image *img)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
 #ifdef HAVE_NTGUI
@@ -5357,11 +4747,9 @@ x_disable_image (f, img)
       Display *dpy = FRAME_X_DISPLAY (f);
       GC gc;
 
-#ifdef MAC_OS
-#define MaskForeground(f)  PIX_MASK_DRAW
-#else
+#ifndef HAVE_NS  /* TODO: NS support, however this not needed for toolbars */
+
 #define MaskForeground(f)  WHITE_PIX_DEFAULT (f)
-#endif
 
       gc = XCreateGC (dpy, img->pixmap, 0, NULL);
       XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
@@ -5381,6 +4769,7 @@ x_disable_image (f, img)
                     img->width - 1, 0);
          XFreeGC (dpy, gc);
        }
+#endif /* !HAVE_NS */
 #else
       HDC hdc, bmpdc;
       HGDIOBJ prev;
@@ -5421,10 +4810,7 @@ x_disable_image (f, img)
    heuristically.  Value is non-zero if successful. */
 
 static int
-x_build_heuristic_mask (f, img, how)
-     struct frame *f;
-     struct image *img;
-     Lisp_Object how;
+x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
 {
   XImagePtr_or_DC ximg;
 #ifndef HAVE_NTGUI
@@ -5446,11 +4832,13 @@ x_build_heuristic_mask (f, img, how)
     }
 
 #ifndef HAVE_NTGUI
+#ifndef HAVE_NS
   /* Create an image and pixmap serving as mask.  */
   rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1,
                                    &mask_img, &img->mask);
   if (!rc)
     return 0;
+#endif /* !HAVE_NS */
 
   /* Get the X image of IMG->pixmap.  */
   ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, 0, 0,
@@ -5504,16 +4892,21 @@ x_build_heuristic_mask (f, img, how)
 #ifndef HAVE_NTGUI
   for (y = 0; y < img->height; ++y)
     for (x = 0; x < img->width; ++x)
+#ifndef HAVE_NS
       XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg
                                  ? PIX_MASK_DRAW : PIX_MASK_RETAIN));
-
+#else
+      if (XGetPixel (ximg, x, y) == bg)
+        ns_set_alpha(ximg, x, y, 0);
+#endif /* HAVE_NS */
+#ifndef HAVE_NS
   /* Fill in the background_transparent field while we have the mask handy. */
   image_background_transparent (img, f, mask_img);
 
   /* Put mask_img into img->mask.  */
   x_put_x_image (f, mask_img, img->mask, img->width, img->height);
   x_destroy_x_image (mask_img);
-
+#endif /* !HAVE_NS */
 #else
   for (y = 0; y < img->height; ++y)
     for (x = 0; x < img->width; ++x)
@@ -5544,9 +4937,9 @@ x_build_heuristic_mask (f, img, how)
                       PBM (mono, gray, color)
  ***********************************************************************/
 
-static int pbm_image_p P_ ((Lisp_Object object));
-static int pbm_load P_ ((struct frame *f, struct image *img));
-static int pbm_scan_number P_ ((unsigned char **, unsigned char *));
+static int pbm_image_p (Lisp_Object object);
+static int pbm_load (struct frame *f, struct image *img);
+static int pbm_scan_number (unsigned char **, unsigned char *);
 
 /* The symbol `pbm' identifying images of this type.  */
 
@@ -5573,7 +4966,7 @@ enum pbm_keyword_index
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
-static struct image_keyword pbm_format[PBM_LAST] =
+static const struct image_keyword pbm_format[PBM_LAST] =
 {
   {":type",            IMAGE_SYMBOL_VALUE,                     1},
   {":file",            IMAGE_STRING_VALUE,                     0},
@@ -5603,8 +4996,7 @@ static struct image_type pbm_type =
 /* Return non-zero if OBJECT is a valid PBM image specification.  */
 
 static int
-pbm_image_p (object)
-     Lisp_Object object;
+pbm_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[PBM_LAST];
 
@@ -5623,8 +5015,7 @@ pbm_image_p (object)
    end of input.  */
 
 static int
-pbm_scan_number (s, end)
-     unsigned char **s, *end;
+pbm_scan_number (unsigned char **s, unsigned char *end)
 {
   int c = 0, val = -1;
 
@@ -5699,9 +5090,7 @@ pbm_read_file (file, size)
 /* Load PBM image IMG for use on frame F.  */
 
 static int
-pbm_load (f, img)
-     struct frame *f;
-     struct image *img;
+pbm_load (struct frame *f, struct image *img)
 {
   int raw_p, x, y;
   int width, height, max_color_idx = 0;
@@ -5795,13 +5184,18 @@ pbm_load (f, img)
   if (type != PBM_MONO)
     {
       max_color_idx = pbm_scan_number (&p, end);
-      if (raw_p && max_color_idx > 255)
-       max_color_idx = 255;
+      if (max_color_idx > 65535 || max_color_idx < 0)
+       {
+         image_error ("Unsupported maximum PBM color value", Qnil, Qnil);
+         goto error;
+       }
     }
 
-  if (!check_image_size (f, width, height)
-      || (type != PBM_MONO && max_color_idx < 0))
-    goto error;
+  if (!check_image_size (f, width, height))
+    {
+      image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
+      goto error;
+    }
 
   if (!x_create_x_image_and_pixmap (f, width, height, 0,
                                    &ximg, &img->pixmap))
@@ -5861,10 +5255,13 @@ pbm_load (f, img)
     }
   else
     {
-      if (raw_p
-         && ((type == PBM_GRAY)
-             ? (p + height * width > end)
-             : (p + 3 * height * width > end)))
+      int expected_size = height * width;
+      if (max_color_idx > 255)
+       expected_size *= 2;
+      if (type == PBM_COLOR)
+       expected_size *= 3;
+
+      if (raw_p && p + expected_size > end)
        {
          x_destroy_x_image (ximg);
          x_clear_image (f, img);
@@ -5878,13 +5275,25 @@ pbm_load (f, img)
          {
            int r, g, b;
 
-           if (type == PBM_GRAY)
-             r = g = b = raw_p ? *p++ : pbm_scan_number (&p, end);
+           if (type == PBM_GRAY && raw_p)
+             {
+               r = g = b = *p++;
+               if (max_color_idx > 255)
+                 r = g = b = r * 256 + *p++;
+             }
+           else if (type == PBM_GRAY)
+             r = g = b = pbm_scan_number (&p, end);
            else if (raw_p)
              {
                r = *p++;
+               if (max_color_idx > 255)
+                 r = r * 256 + *p++;
                g = *p++;
+               if (max_color_idx > 255)
+                 g = g * 256 + *p++;
                b = *p++;
+               if (max_color_idx > 255)
+                 b = b * 256 + *p++;
              }
            else
              {
@@ -5944,12 +5353,12 @@ pbm_load (f, img)
                                 PNG
  ***********************************************************************/
 
-#if defined (HAVE_PNG) || defined (MAC_OS)
+#if defined (HAVE_PNG) || defined (HAVE_NS)
 
 /* Function prototypes.  */
 
-static int png_image_p P_ ((Lisp_Object object));
-static int png_load P_ ((struct frame *f, struct image *img));
+static int png_image_p (Lisp_Object object);
+static int png_load (struct frame *f, struct image *img);
 
 /* The symbol `png' identifying images of this type.  */
 
@@ -5975,7 +5384,7 @@ enum png_keyword_index
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
-static struct image_keyword png_format[PNG_LAST] =
+static const struct image_keyword png_format[PNG_LAST] =
 {
   {":type",            IMAGE_SYMBOL_VALUE,                     1},
   {":data",            IMAGE_STRING_VALUE,                     0},
@@ -6003,8 +5412,7 @@ static struct image_type png_type =
 /* Return non-zero if OBJECT is a valid PNG image specification.  */
 
 static int
-png_image_p (object)
-     Lisp_Object object;
+png_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[PNG_LAST];
   bcopy (png_format, fmt, sizeof fmt);
@@ -6016,22 +5424,16 @@ png_image_p (object)
   return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
 }
 
-#endif /* HAVE_PNG || MAC_OS */
+#endif /* HAVE_PNG || HAVE_NS */
 
 
 #ifdef HAVE_PNG
 
-#if defined HAVE_LIBPNG_PNG_H
-# include <libpng/png.h>
-#else
-# include <png.h>
-#endif
-
 #ifdef HAVE_NTGUI
 /* PNG library details.  */
 
 DEF_IMGLIB_FN (png_get_io_ptr);
-DEF_IMGLIB_FN (png_check_sig);
+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);
@@ -6062,7 +5464,7 @@ init_png_functions (Lisp_Object libraries)
     return 0;
 
   LOAD_IMGLIB_FN (library, png_get_io_ptr);
-  LOAD_IMGLIB_FN (library, png_check_sig);
+  LOAD_IMGLIB_FN (library, png_sig_cmp);
   LOAD_IMGLIB_FN (library, png_create_read_struct);
   LOAD_IMGLIB_FN (library, png_create_info_struct);
   LOAD_IMGLIB_FN (library, png_destroy_read_struct);
@@ -6087,7 +5489,7 @@ init_png_functions (Lisp_Object libraries)
 #else
 
 #define fn_png_get_io_ptr              png_get_io_ptr
-#define fn_png_check_sig               png_check_sig
+#define fn_png_sig_cmp                 png_sig_cmp
 #define fn_png_create_read_struct      png_create_read_struct
 #define fn_png_create_info_struct      png_create_info_struct
 #define fn_png_destroy_read_struct     png_destroy_read_struct
@@ -6114,9 +5516,7 @@ init_png_functions (Lisp_Object libraries)
    is initialized.  */
 
 static void
-my_png_error (png_ptr, msg)
-     png_struct *png_ptr;
-     char *msg;
+my_png_error (png_struct *png_ptr, const char *msg)
 {
   xassert (png_ptr != NULL);
   image_error ("PNG error: %s", build_string (msg), Qnil);
@@ -6125,9 +5525,7 @@ my_png_error (png_ptr, msg)
 
 
 static void
-my_png_warning (png_ptr, msg)
-     png_struct *png_ptr;
-     char *msg;
+my_png_warning (png_struct *png_ptr, const char *msg)
 {
   xassert (png_ptr != NULL);
   image_error ("PNG warning: %s", build_string (msg), Qnil);
@@ -6148,10 +5546,7 @@ struct png_memory_storage
    bytes from the input to DATA.  */
 
 static void
-png_read_from_memory (png_ptr, data, length)
-     png_structp png_ptr;
-     png_bytep data;
-     png_size_t length;
+png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
 {
   struct png_memory_storage *tbr
     = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr);
@@ -6169,10 +5564,7 @@ png_read_from_memory (png_ptr, data, length)
    bytes from the input to DATA.  */
 
 static void
-png_read_from_file (png_ptr, data, length)
-     png_structp png_ptr;
-     png_bytep data;
-     png_size_t length;
+png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
 {
   FILE *fp = (FILE *) fn_png_get_io_ptr (png_ptr);
 
@@ -6185,9 +5577,7 @@ png_read_from_file (png_ptr, data, length)
    successful.  */
 
 static int
-png_load (f, img)
-     struct frame *f;
-     struct image *img;
+png_load (struct frame *f, struct image *img)
 {
   Lisp_Object file, specified_file;
   Lisp_Object specified_data;
@@ -6205,7 +5595,6 @@ png_load (f, img)
   png_byte channels;
   png_uint_32 row_bytes;
   int transparent_p;
-  double screen_gamma;
   struct png_memory_storage tbr;  /* Data to be read */
 
   /* Find out what file to load.  */
@@ -6235,7 +5624,7 @@ png_load (f, img)
 
       /* Check PNG signature.  */
       if (fread (sig, 1, sizeof sig, fp) != sizeof sig
-         || !fn_png_check_sig (sig, sizeof sig))
+         || fn_png_sig_cmp (sig, 0, sizeof sig))
        {
          image_error ("Not a PNG file: `%s'", file, Qnil);
          UNGCPRO;
@@ -6252,7 +5641,7 @@ png_load (f, img)
 
       /* Check PNG signature.  */
       if (tbr.len < sizeof sig
-         || !fn_png_check_sig (tbr.bytes, sizeof sig))
+         || fn_png_sig_cmp (tbr.bytes, 0, sizeof sig))
        {
          image_error ("Not a PNG image: `%s'", img->spec, Qnil);
          UNGCPRO;
@@ -6321,8 +5710,10 @@ png_load (f, img)
                   &interlace_type, NULL, NULL);
 
   if (!check_image_size (f, width, height))
-    goto error;
-
+    {
+      image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
+      goto error;
+    }
   /* If image contains simply transparency data, we prefer to
      construct a clipping mask.  */
   if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
@@ -6347,27 +5738,6 @@ png_load (f, img)
       || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
     fn_png_set_gray_to_rgb (png_ptr);
 
-  screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2);
-
-#if 0 /* Avoid double gamma correction for PNG images. */
-  { /* Tell the PNG lib to handle gamma correction for us.  */
-    int intent;
-    double image_gamma;
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
-    if (png_get_sRGB (png_ptr, info_ptr, &intent))
-      /* The libpng documentation says this is right in this case.  */
-      png_set_gamma (png_ptr, screen_gamma, 0.45455);
-    else
-#endif
-      if (png_get_gAMA (png_ptr, info_ptr, &image_gamma))
-       /* Image contains gamma information.  */
-       png_set_gamma (png_ptr, screen_gamma, image_gamma);
-      else
-       /* Use the standard default for the image gamma.  */
-       png_set_gamma (png_ptr, screen_gamma, 0.45455);
-  }
-#endif /* if 0 */
-
   /* Handle alpha channel by combining the image with a background
      color.  Do this only if a real alpha channel is supplied.  For
      simple transparency, we prefer a clipping mask.  */
@@ -6376,39 +5746,30 @@ png_load (f, img)
       /* png_color_16 *image_bg; */
       Lisp_Object specified_bg
        = image_spec_value (img->spec, QCbackground, NULL);
+      int shift = (bit_depth == 16) ? 0 : 8;
 
       if (STRINGP (specified_bg))
        /* The user specified `:background', use that.  */
        {
-         /* W32 version incorrectly used COLORREF here!!  ++kfs */
          XColor color;
          if (x_defined_color (f, SDATA (specified_bg), &color, 0))
            {
              png_color_16 user_bg;
 
              bzero (&user_bg, sizeof user_bg);
-             user_bg.red = color.red >> 8;
-             user_bg.green = color.green >> 8;
-             user_bg.blue = color.blue >> 8;
+             user_bg.red = color.red >> shift;
+             user_bg.green = color.green >> shift;
+             user_bg.blue = color.blue >> shift;
 
              fn_png_set_background (png_ptr, &user_bg,
                                     PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
            }
        }
-      /* The commented-out code checked if the png specifies a default
-        background color, and uses that.  Since we use the current
-        frame background, it is OK for us to ignore this.
-
-      else if (fn_png_get_bKGD (png_ptr, info_ptr, &image_bg))
-       fn_png_set_background (png_ptr, image_bg,
-                              PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
-       */
       else
        {
-         /* Image does not contain a background color with which
-            to combine the image data via an alpha channel.  Use
-            the frame's background instead.  */
-#ifdef HAVE_X_WINDOWS
+         /* We use the current frame background, ignoring any default
+            background color set by the image.  */
+#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
          XColor color;
          png_color_16 frame_background;
 
@@ -6416,37 +5777,11 @@ png_load (f, img)
          x_query_color (f, &color);
 
          bzero (&frame_background, sizeof frame_background);
-         frame_background.red = color.red >> 8;
-         frame_background.green = color.green >> 8;
-         frame_background.blue = color.blue >> 8;
+         frame_background.red = color.red >> shift;
+         frame_background.green = color.green >> shift;
+         frame_background.blue = color.blue >> shift;
 #endif /* HAVE_X_WINDOWS */
 
-#ifdef HAVE_NTGUI
-         COLORREF color;
-         png_color_16 frame_background;
-         color = FRAME_BACKGROUND_PIXEL (f);
-#if 0 /* W32 TODO : Colormap support.  */
-         x_query_color (f, &color);
-#endif
-         bzero (&frame_background, sizeof frame_background);
-         frame_background.red = GetRValue (color);
-         frame_background.green = GetGValue (color);
-         frame_background.blue = GetBValue (color);
-#endif /* HAVE_NTGUI */
-
-#ifdef MAC_OS
-         unsigned long color;
-         png_color_16 frame_background;
-         color = FRAME_BACKGROUND_PIXEL (f);
-#if 0 /* MAC/W32 TODO : Colormap support.  */
-         x_query_color (f, &color);
-#endif
-         bzero (&frame_background, sizeof frame_background);
-         frame_background.red = RED_FROM_ULONG (color);
-         frame_background.green = GREEN_FROM_ULONG (color);
-         frame_background.blue = BLUE_FROM_ULONG (color);
-#endif /* MAC_OS */
-
          fn_png_set_background (png_ptr, &frame_background,
                                 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
        }
@@ -6590,20 +5925,16 @@ png_load (f, img)
 
 #else /* HAVE_PNG */
 
-#ifdef MAC_OS
+#ifdef HAVE_NS
 static int
-png_load (f, img)
-     struct frame *f;
-     struct image *img;
+png_load (struct frame *f, struct image *img)
 {
-#ifdef MAC_OSX
-  if (MyCGImageCreateWithPNGDataProvider)
-    return image_load_quartz2d (f, img, 1);
-  else
-#endif
-    return image_load_quicktime (f, img, kQTFileTypePNG);
+  return ns_load_image(f, img,
+                       image_spec_value (img->spec, QCfile, NULL),
+                       image_spec_value (img->spec, QCdata, NULL));
 }
-#endif  /* MAC_OS */
+#endif  /* HAVE_NS */
+
 
 #endif /* !HAVE_PNG */
 
@@ -6613,10 +5944,10 @@ png_load (f, img)
                                 JPEG
  ***********************************************************************/
 
-#if defined (HAVE_JPEG) || defined (MAC_OS)
+#if defined (HAVE_JPEG) || defined (HAVE_NS)
 
-static int jpeg_image_p P_ ((Lisp_Object object));
-static int jpeg_load P_ ((struct frame *f, struct image *img));
+static int jpeg_image_p (Lisp_Object object);
+static int jpeg_load (struct frame *f, struct image *img);
 
 /* The symbol `jpeg' identifying images of this type.  */
 
@@ -6642,7 +5973,7 @@ enum jpeg_keyword_index
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
-static struct image_keyword jpeg_format[JPEG_LAST] =
+static const struct image_keyword jpeg_format[JPEG_LAST] =
 {
   {":type",            IMAGE_SYMBOL_VALUE,                     1},
   {":data",            IMAGE_STRING_VALUE,                     0},
@@ -6670,8 +6001,7 @@ static struct image_type jpeg_type =
 /* Return non-zero if OBJECT is a valid JPEG image specification.  */
 
 static int
-jpeg_image_p (object)
-     Lisp_Object object;
+jpeg_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[JPEG_LAST];
 
@@ -6684,7 +6014,7 @@ jpeg_image_p (object)
   return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
 }
 
-#endif /* HAVE_JPEG || MAC_OS */
+#endif /* HAVE_JPEG || HAVE_NS */
 
 #ifdef HAVE_JPEG
 
@@ -6703,7 +6033,6 @@ jpeg_image_p (object)
 
 #include <jpeglib.h>
 #include <jerror.h>
-#include <setjmp.h>
 
 #ifdef HAVE_STLIB_H_1
 #define HAVE_STDLIB_H 1
@@ -6771,8 +6100,7 @@ struct my_jpeg_error_mgr
 
 
 static void
-my_error_exit (cinfo)
-     j_common_ptr cinfo;
+my_error_exit (j_common_ptr cinfo)
 {
   struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
   longjmp (mgr->setjmp_buffer, 1);
@@ -6784,8 +6112,7 @@ my_error_exit (cinfo)
    libjpeg.doc from the JPEG lib distribution.  */
 
 static void
-our_common_init_source (cinfo)
-     j_decompress_ptr cinfo;
+our_common_init_source (j_decompress_ptr cinfo)
 {
 }
 
@@ -6794,8 +6121,7 @@ our_common_init_source (cinfo)
    jpeg_finish_decompress() after all data has been processed.  */
 
 static void
-our_common_term_source (cinfo)
-     j_decompress_ptr cinfo;
+our_common_term_source (j_decompress_ptr cinfo)
 {
 }
 
@@ -6807,8 +6133,7 @@ our_common_term_source (cinfo)
 static JOCTET our_memory_buffer[2];
 
 static boolean
-our_memory_fill_input_buffer (cinfo)
-     j_decompress_ptr cinfo;
+our_memory_fill_input_buffer (j_decompress_ptr cinfo)
 {
   /* Insert a fake EOI marker.  */
   struct jpeg_source_mgr *src = cinfo->src;
@@ -6826,9 +6151,7 @@ our_memory_fill_input_buffer (cinfo)
    is the JPEG data source manager.  */
 
 static void
-our_memory_skip_input_data (cinfo, num_bytes)
-     j_decompress_ptr cinfo;
-     long num_bytes;
+our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
 {
   struct jpeg_source_mgr *src = (struct jpeg_source_mgr *) cinfo->src;
 
@@ -6848,10 +6171,7 @@ our_memory_skip_input_data (cinfo, num_bytes)
    reading the image.  */
 
 static void
-jpeg_memory_src (cinfo, data, len)
-     j_decompress_ptr cinfo;
-     JOCTET *data;
-     unsigned int len;
+jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len)
 {
   struct jpeg_source_mgr *src;
 
@@ -6894,8 +6214,7 @@ struct jpeg_stdio_mgr
    whenever more data is needed.  The data is read from a FILE *.  */
 
 static boolean
-our_stdio_fill_input_buffer (cinfo)
-     j_decompress_ptr cinfo;
+our_stdio_fill_input_buffer (j_decompress_ptr cinfo)
 {
   struct jpeg_stdio_mgr *src;
 
@@ -6926,9 +6245,7 @@ our_stdio_fill_input_buffer (cinfo)
    is the JPEG data source manager.  */
 
 static void
-our_stdio_skip_input_data (cinfo, num_bytes)
-     j_decompress_ptr cinfo;
-     long num_bytes;
+our_stdio_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
 {
   struct jpeg_stdio_mgr *src;
   src = (struct jpeg_stdio_mgr *) cinfo->src;
@@ -6958,9 +6275,7 @@ our_stdio_skip_input_data (cinfo, num_bytes)
    reading the image.  */
 
 static void
-jpeg_file_src (cinfo, fp)
-     j_decompress_ptr cinfo;
-     FILE *fp;
+jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
 {
   struct jpeg_stdio_mgr *src;
 
@@ -6994,9 +6309,7 @@ jpeg_file_src (cinfo, fp)
    from the JPEG lib.  */
 
 static int
-jpeg_load (f, img)
-     struct frame *f;
-     struct image *img;
+jpeg_load (struct frame *f, struct image *img)
 {
   struct jpeg_decompress_struct cinfo;
   struct my_jpeg_error_mgr mgr;
@@ -7089,7 +6402,7 @@ jpeg_load (f, img)
 
   if (!check_image_size (f, width, height))
     {
-      image_error ("Invalid image size", Qnil, Qnil);
+      image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       longjmp (mgr.setjmp_buffer, 2);
     }
 
@@ -7168,19 +6481,15 @@ jpeg_load (f, img)
 
 #else /* HAVE_JPEG */
 
-#ifdef MAC_OS
+#ifdef HAVE_NS
 static int
-jpeg_load (f, img)
-     struct frame *f;
-     struct image *img;
+jpeg_load (struct frame *f, struct image *img)
 {
-#ifdef MAC_OSX
-  return image_load_quartz2d (f, img, 0);
-#else
-  return image_load_quicktime (f, img, kQTFileTypeJPEG);
-#endif
+  return ns_load_image(f, img,
+                       image_spec_value (img->spec, QCfile, NULL),
+                       image_spec_value (img->spec, QCdata, NULL));
 }
-#endif  /* MAC_OS */
+#endif  /* HAVE_NS */
 
 #endif /* !HAVE_JPEG */
 
@@ -7190,10 +6499,10 @@ jpeg_load (f, img)
                                 TIFF
  ***********************************************************************/
 
-#if defined (HAVE_TIFF) || defined (MAC_OS)
+#if defined (HAVE_TIFF) || defined (HAVE_NS)
 
-static int tiff_image_p P_ ((Lisp_Object object));
-static int tiff_load P_ ((struct frame *f, struct image *img));
+static int tiff_image_p (Lisp_Object object);
+static int tiff_load (struct frame *f, struct image *img);
 
 /* The symbol `tiff' identifying images of this type.  */
 
@@ -7213,13 +6522,14 @@ enum tiff_keyword_index
   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 struct image_keyword tiff_format[TIFF_LAST] =
+static const struct image_keyword tiff_format[TIFF_LAST] =
 {
   {":type",            IMAGE_SYMBOL_VALUE,                     1},
   {":data",            IMAGE_STRING_VALUE,                     0},
@@ -7230,7 +6540,8 @@ static struct image_keyword tiff_format[TIFF_LAST] =
   {":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}
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0},
+  {":index",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0}
 };
 
 /* Structure describing the image type `tiff'.  */
@@ -7247,8 +6558,7 @@ static struct image_type tiff_type =
 /* Return non-zero if OBJECT is a valid TIFF image specification.  */
 
 static int
-tiff_image_p (object)
-     Lisp_Object object;
+tiff_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[TIFF_LAST];
   bcopy (tiff_format, fmt, sizeof fmt);
@@ -7260,7 +6570,7 @@ tiff_image_p (object)
   return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
 }
 
-#endif /* HAVE_TIFF || MAC_OS */
+#endif /* HAVE_TIFF || HAVE_NS */
 
 #ifdef HAVE_TIFF
 
@@ -7276,6 +6586,7 @@ DEF_IMGLIB_FN (TIFFClientOpen);
 DEF_IMGLIB_FN (TIFFGetField);
 DEF_IMGLIB_FN (TIFFReadRGBAImage);
 DEF_IMGLIB_FN (TIFFClose);
+DEF_IMGLIB_FN (TIFFSetDirectory);
 
 static int
 init_tiff_functions (Lisp_Object libraries)
@@ -7292,6 +6603,7 @@ init_tiff_functions (Lisp_Object libraries)
   LOAD_IMGLIB_FN (library, TIFFGetField);
   LOAD_IMGLIB_FN (library, TIFFReadRGBAImage);
   LOAD_IMGLIB_FN (library, TIFFClose);
+  LOAD_IMGLIB_FN (library, TIFFSetDirectory);
   return 1;
 }
 
@@ -7304,7 +6616,7 @@ init_tiff_functions (Lisp_Object libraries)
 #define fn_TIFFGetField                        TIFFGetField
 #define fn_TIFFReadRGBAImage           TIFFReadRGBAImage
 #define fn_TIFFClose                   TIFFClose
-
+#define fn_TIFFSetDirectory            TIFFSetDirectory
 #endif /* HAVE_NTGUI */
 
 
@@ -7326,10 +6638,7 @@ typedef struct
 tiff_memory_source;
 
 static size_t
-tiff_read_from_memory (data, buf, size)
-     thandle_t data;
-     tdata_t buf;
-     tsize_t size;
+tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size)
 {
   tiff_memory_source *src = (tiff_memory_source *) data;
 
@@ -7341,19 +6650,13 @@ tiff_read_from_memory (data, buf, size)
 }
 
 static size_t
-tiff_write_from_memory (data, buf, size)
-     thandle_t data;
-     tdata_t buf;
-     tsize_t size;
+tiff_write_from_memory (thandle_t data, tdata_t buf, tsize_t size)
 {
   return (size_t) -1;
 }
 
 static toff_t
-tiff_seek_in_memory (data, off, whence)
-     thandle_t data;
-     toff_t off;
-     int whence;
+tiff_seek_in_memory (thandle_t data, toff_t off, int whence)
 {
   tiff_memory_source *src = (tiff_memory_source *) data;
   int idx;
@@ -7384,44 +6687,34 @@ tiff_seek_in_memory (data, off, whence)
 }
 
 static int
-tiff_close_memory (data)
-     thandle_t data;
+tiff_close_memory (thandle_t data)
 {
   /* NOOP */
   return 0;
 }
 
 static int
-tiff_mmap_memory (data, pbase, psize)
-     thandle_t data;
-     tdata_t *pbase;
-     toff_t *psize;
+tiff_mmap_memory (thandle_t data, tdata_t *pbase, toff_t *psize)
 {
   /* It is already _IN_ memory. */
   return 0;
 }
 
 static void
-tiff_unmap_memory (data, base, size)
-     thandle_t data;
-     tdata_t base;
-     toff_t size;
+tiff_unmap_memory (thandle_t data, tdata_t base, toff_t size)
 {
   /* We don't need to do this. */
 }
 
 static toff_t
-tiff_size_of_memory (data)
-     thandle_t data;
+tiff_size_of_memory (thandle_t data)
 {
   return ((tiff_memory_source *) data)->len;
 }
 
 
 static void
-tiff_error_handler (title, format, ap)
-     const char *title, *format;
-     va_list ap;
+tiff_error_handler (const char *title, const char *format, va_list ap)
 {
   char buf[512];
   int len;
@@ -7433,9 +6726,7 @@ tiff_error_handler (title, format, ap)
 
 
 static void
-tiff_warning_handler (title, format, ap)
-     const char *title, *format;
-     va_list ap;
+tiff_warning_handler (const char *title, const char *format, va_list ap)
 {
   char buf[512];
   int len;
@@ -7450,19 +6741,18 @@ tiff_warning_handler (title, format, ap)
    successful.  */
 
 static int
-tiff_load (f, img)
-     struct frame *f;
-     struct image *img;
+tiff_load (struct frame *f, struct image *img)
 {
   Lisp_Object file, specified_file;
   Lisp_Object specified_data;
   TIFF *tiff;
-  int width, height, x, y;
+  int width, height, x, y, count;
   uint32 *buf;
-  int rc;
+  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);
@@ -7518,6 +6808,20 @@ tiff_load (f, img)
        }
     }
 
+  image = image_spec_value (img->spec, QCindex, NULL);
+  if (INTEGERP (image))
+    {
+      int ino = XFASTINT (image);
+      if (!fn_TIFFSetDirectory (tiff, ino))
+       {
+         image_error ("Invalid image number `%s' in image `%s'",
+                      image, img->spec);
+         fn_TIFFClose (tiff);
+         UNGCPRO;
+         return 0;
+       }
+    }
+
   /* Get width and height of the image, and allocate a raster buffer
      of width x height 32-bit values.  */
   fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
@@ -7525,7 +6829,8 @@ tiff_load (f, img)
 
   if (!check_image_size (f, width, height))
     {
-      image_error ("Invalid image size", Qnil, Qnil);
+      image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
+      fn_TIFFClose (tiff);
       UNGCPRO;
       return 0;
     }
@@ -7533,6 +6838,16 @@ tiff_load (f, img)
   buf = (uint32 *) xmalloc (width * height * sizeof *buf);
 
   rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
+
+  /* Count the number of images in the file.  */
+  for (count = 1, rc2 = 1; rc2; count++)
+    rc2 = fn_TIFFSetDirectory (tiff, count);
+
+  if (count > 1)
+    img->data.lisp_val = Fcons (Qcount,
+                               Fcons (make_number (count),
+                                      img->data.lisp_val));
+
   fn_TIFFClose (tiff);
   if (!rc)
     {
@@ -7593,15 +6908,15 @@ tiff_load (f, img)
 
 #else /* HAVE_TIFF */
 
-#ifdef MAC_OS
+#ifdef HAVE_NS
 static int
-tiff_load (f, img)
-     struct frame *f;
-     struct image *img;
+tiff_load (struct frame *f, struct image *img)
 {
-  return image_load_quicktime (f, img, kQTFileTypeTIFF);
+  return ns_load_image(f, img,
+                       image_spec_value (img->spec, QCfile, NULL),
+                       image_spec_value (img->spec, QCdata, NULL));
 }
-#endif /* MAC_OS */
+#endif  /* HAVE_NS */
 
 #endif /* !HAVE_TIFF */
 
@@ -7611,11 +6926,11 @@ tiff_load (f, img)
                                 GIF
  ***********************************************************************/
 
-#if defined (HAVE_GIF) || defined (MAC_OS)
+#if defined (HAVE_GIF) || defined (HAVE_NS)
 
-static int gif_image_p P_ ((Lisp_Object object));
-static int gif_load P_ ((struct frame *f, struct image *img));
-static void gif_clear_image P_ ((struct frame *f, struct image *img));
+static int gif_image_p (Lisp_Object object);
+static int gif_load (struct frame *f, struct image *img);
+static void gif_clear_image (struct frame *f, struct image *img);
 
 /* The symbol `gif' identifying images of this type.  */
 
@@ -7642,7 +6957,7 @@ enum gif_keyword_index
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
-static struct image_keyword gif_format[GIF_LAST] =
+static const struct image_keyword gif_format[GIF_LAST] =
 {
   {":type",            IMAGE_SYMBOL_VALUE,                     1},
   {":data",            IMAGE_STRING_VALUE,                     0},
@@ -7653,7 +6968,7 @@ static struct image_keyword gif_format[GIF_LAST] =
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
-  {":image",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},
+  {":index",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},
   {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
@@ -7671,11 +6986,9 @@ static struct image_type gif_type =
 /* Free X resources of GIF image IMG which is used on frame F.  */
 
 static void
-gif_clear_image (f, img)
-     struct frame *f;
-     struct image *img;
+gif_clear_image (struct frame *f, struct image *img)
 {
-  /* IMG->data.ptr_val may contain extension data.  */
+  /* IMG->data.ptr_val may contain metadata with extension data.  */
   img->data.lisp_val = Qnil;
   x_clear_image (f, img);
 }
@@ -7683,8 +6996,7 @@ gif_clear_image (f, img)
 /* Return non-zero if OBJECT is a valid GIF image specification.  */
 
 static int
-gif_image_p (object)
-     Lisp_Object object;
+gif_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[GIF_LAST];
   bcopy (gif_format, fmt, sizeof fmt);
@@ -7696,11 +7008,11 @@ gif_image_p (object)
   return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
 }
 
-#endif /* HAVE_GIF || MAC_OS */
+#endif /* HAVE_GIF */
 
 #ifdef HAVE_GIF
 
-#if defined (HAVE_NTGUI) || defined (MAC_OS)
+#if defined (HAVE_NTGUI)
 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
    Undefine before redefining to avoid a preprocessor warning.  */
 #ifdef DrawText
@@ -7711,11 +7023,11 @@ gif_image_p (object)
 #include <gif_lib.h>
 #undef DrawText
 
-#else /* HAVE_NTGUI || MAC_OS */
+#else /* HAVE_NTGUI */
 
 #include <gif_lib.h>
 
-#endif /* HAVE_NTGUI || MAC_OS */
+#endif /* HAVE_NTGUI */
 
 
 #ifdef HAVE_NTGUI
@@ -7767,10 +7079,7 @@ gif_memory_source;
 static gif_memory_source *current_gif_memory_src;
 
 static int
-gif_read_from_memory (file, buf, len)
-     GifFileType *file;
-     GifByteType *buf;
-     int len;
+gif_read_from_memory (GifFileType *file, GifByteType *buf, int len)
 {
   gif_memory_source *src = current_gif_memory_src;
 
@@ -7786,13 +7095,11 @@ gif_read_from_memory (file, buf, len)
 /* Load GIF image IMG for use on frame F.  Value is non-zero if
    successful.  */
 
-static int interlace_start[] = {0, 4, 2, 1};
-static int interlace_increment[] = {8, 8, 4, 2};
+static const int interlace_start[] = {0, 4, 2, 1};
+static const int interlace_increment[] = {8, 8, 4, 2};
 
 static int
-gif_load (f, img)
-     struct frame *f;
-     struct image *img;
+gif_load (struct frame *f, struct image *img)
 {
   Lisp_Object file, specified_file;
   Lisp_Object specified_data;
@@ -7853,7 +7160,7 @@ gif_load (f, img)
   /* Before reading entire contents, check the declared image size. */
   if (!check_image_size (f, gif->SWidth, gif->SHeight))
     {
-      image_error ("Invalid image size", Qnil, Qnil);
+      image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       fn_DGifCloseFile (gif);
       UNGCPRO;
       return 0;
@@ -7896,7 +7203,7 @@ gif_load (f, img)
 
   if (!check_image_size (f, width, height))
     {
-      image_error ("Invalid image size", Qnil, Qnil);
+      image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       fn_DGifCloseFile (gif);
       UNGCPRO;
       return 0;
@@ -7994,8 +7301,8 @@ gif_load (f, img)
          }
     }
 
-  /* Save GIF image extension data for `image-extension-data'.
-     Format is (count IMAGES FUNCTION "BYTES" ...).  */
+  /* Save GIF image extension data for `image-metadata'.
+     Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)).  */
   img->data.lisp_val = Qnil;
   if (gif->SavedImages[ino].ExtensionBlockCount > 0)
     {
@@ -8005,7 +7312,9 @@ gif_load (f, img)
        img->data.lisp_val = Fcons (make_unibyte_string (ext->Bytes, ext->ByteCount),
                                    Fcons (make_number (ext->Function),
                                           img->data.lisp_val));
-      img->data.lisp_val = Fnreverse (img->data.lisp_val);
+      img->data.lisp_val = Fcons (Qextension_data,
+                                 Fcons (Fnreverse (img->data.lisp_val),
+                                        Qnil));
     }
   if (gif->ImageCount > 1)
     img->data.lisp_val = Fcons (Qcount,
@@ -8029,212 +7338,15 @@ gif_load (f, img)
 
 #else  /* !HAVE_GIF */
 
-#ifdef MAC_OS
+#ifdef HAVE_NS
 static int
-gif_load (f, img)
-     struct frame *f;
-     struct image *img;
+gif_load (struct frame *f, struct image *img)
 {
-  Lisp_Object specified_file, file;
-  Lisp_Object specified_data;
-  OSErr err;
-  Boolean graphic_p, movie_p, prefer_graphic_p;
-  Handle dh = NULL;
-  Movie movie = NULL;
-  Lisp_Object image;
-  Track track = NULL;
-  Media media = NULL;
-  long nsamples;
-  Rect rect;
-  Lisp_Object specified_bg;
-  XColor color;
-  RGBColor bg_color;
-  int width, height;
-  XImagePtr ximg;
-  TimeScale time_scale;
-  TimeValue time, duration;
-  int ino;
-  CGrafPtr old_port;
-  GDHandle old_gdh;
-
-  specified_file = image_spec_value (img->spec, QCfile, NULL);
-  specified_data = image_spec_value (img->spec, QCdata, NULL);
-
-  /* Animated gifs use QuickTime Movie Toolbox.  So initialize it here. */
-  EnterMovies ();
-
-  if (NILP (specified_data))
-    {
-      /* Read from a file */
-      FSSpec fss;
-      short refnum;
-
-      err = find_image_fsspec (specified_file, &file, &fss);
-      if (err != noErr)
-       {
-         if (err == fnfErr)
-           image_error ("Cannot find image file `%s'", specified_file, Qnil);
-         else
-           goto open_error;
-       }
-
-      err = CanQuickTimeOpenFile (&fss, kQTFileTypeGIF, 0,
-                                 &graphic_p, &movie_p, &prefer_graphic_p, 0);
-      if (err != noErr)
-       goto open_error;
-
-      if (!graphic_p && !movie_p)
-       goto open_error;
-      if (prefer_graphic_p)
-       return image_load_qt_1 (f, img, kQTFileTypeGIF, &fss, NULL);
-      err = OpenMovieFile (&fss, &refnum, fsRdPerm);
-      if (err != noErr)
-       goto open_error;
-      err = NewMovieFromFile (&movie, refnum, NULL, NULL, 0, NULL);
-      CloseMovieFile (refnum);
-      if (err != noErr)
-       {
-         image_error ("Error reading `%s'", file, Qnil);
-         return 0;
-       }
-    }
-  else
-    {
-      /* Memory source! */
-      Handle dref = NULL;
-      long file_type_atom[3];
-
-      err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data));
-      if (err != noErr)
-       {
-         image_error ("Cannot allocate data handle for `%s'",
-                      img->spec, Qnil);
-         goto error;
-       }
-
-      file_type_atom[0] = EndianU32_NtoB (sizeof (long) * 3);
-      file_type_atom[1] = EndianU32_NtoB (kDataRefExtensionMacOSFileType);
-      file_type_atom[2] = EndianU32_NtoB (kQTFileTypeGIF);
-      err = PtrToHand (&dh, &dref, sizeof (Handle));
-      if (err == noErr)
-       /* no file name */
-       err = PtrAndHand ("\p", dref, 1);
-      if (err == noErr)
-       err = PtrAndHand (file_type_atom, dref, sizeof (long) * 3);
-      if (err != noErr)
-       {
-         image_error ("Cannot allocate handle data ref for `%s'", img->spec, Qnil);
-         goto error;
-       }
-      err = CanQuickTimeOpenDataRef (dref, HandleDataHandlerSubType, &graphic_p,
-                                    &movie_p, &prefer_graphic_p, 0);
-      if (err != noErr)
-       goto open_error;
-
-      if (!graphic_p && !movie_p)
-       goto open_error;
-      if (prefer_graphic_p)
-       {
-         int success_p;
-
-         DisposeHandle (dref);
-         success_p = image_load_qt_1 (f, img, kQTFileTypeGIF, NULL, dh);
-         DisposeHandle (dh);
-         return success_p;
-       }
-      err = NewMovieFromDataRef (&movie, 0, NULL, dref,
-                                HandleDataHandlerSubType);
-      DisposeHandle (dref);
-      if (err != noErr)
-       goto open_error;
-    }
-
-  image = image_spec_value (img->spec, QCindex, NULL);
-  ino = INTEGERP (image) ? XFASTINT (image) : 0;
-  track = GetMovieIndTrack (movie, 1);
-  media = GetTrackMedia (track);
-  nsamples = GetMediaSampleCount (media);
-  if (ino >= nsamples)
-    {
-      image_error ("Invalid image number `%s' in image `%s'",
-                  image, img->spec);
-      goto error;
-    }
-  time_scale = GetMediaTimeScale (media);
-
-  specified_bg = image_spec_value (img->spec, QCbackground, NULL);
-  if (!STRINGP (specified_bg) ||
-      !mac_defined_color (f, SDATA (specified_bg), &color, 0))
-    {
-      color.pixel = FRAME_BACKGROUND_PIXEL (f);
-      color.red = RED16_FROM_ULONG (color.pixel);
-      color.green = GREEN16_FROM_ULONG (color.pixel);
-      color.blue = BLUE16_FROM_ULONG (color.pixel);
-    }
-  GetMovieBox (movie, &rect);
-  width = img->width = rect.right - rect.left;
-  height = img->height = rect.bottom - rect.top;
-  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
-    goto error;
-
-  GetGWorld (&old_port, &old_gdh);
-  SetGWorld (ximg, NULL);
-  bg_color.red = color.red;
-  bg_color.green = color.green;
-  bg_color.blue = color.blue;
-  RGBBackColor (&bg_color);
-  SetGWorld (old_port, old_gdh);
-  SetMovieActive (movie, 1);
-  SetMovieGWorld (movie, ximg, NULL);
-  SampleNumToMediaTime (media, ino + 1, &time, &duration);
-  SetMovieTimeValue (movie, time);
-  MoviesTask (movie, 0L);
-  DisposeTrackMedia (media);
-  DisposeMovieTrack (track);
-  DisposeMovie (movie);
-  if (dh)
-    DisposeHandle (dh);
-
-  /* Save GIF image extension data for `image-extension-data'.
-     Format is (count IMAGES 0xf9 GRAPHIC_CONTROL_EXTENSION_BLOCK).  */
-  {
-    Lisp_Object gce = make_uninit_string (4);
-    int centisec = ((float)duration / time_scale) * 100.0f + 0.5f;
-
-    /* Fill the delay time field.  */
-    SSET (gce, 1, centisec & 0xff);
-    SSET (gce, 2, (centisec >> 8) & 0xff);
-    /* We don't know about other fields.  */
-    SSET (gce, 0, 0);
-    SSET (gce, 3, 0);
-
-    img->data.lisp_val = list4 (Qcount, make_number (nsamples),
-                               make_number (0xf9), gce);
-  }
-
-  /* Maybe fill in the background field while we have ximg handy. */
-  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
-    IMAGE_BACKGROUND (img, f, ximg);
-
-  /* Put the image into the pixmap.  */
-  x_put_x_image (f, ximg, img->pixmap, width, height);
-  x_destroy_x_image (ximg);
-  return 1;
-
- open_error:
-  image_error ("Cannot open `%s'", file, Qnil);
- error:
-  if (media)
-    DisposeTrackMedia (media);
-  if (track)
-    DisposeMovieTrack (track);
-  if (movie)
-    DisposeMovie (movie);
-  if (dh)
-    DisposeHandle (dh);
-  return 0;
+  return ns_load_image(f, img,
+                       image_spec_value (img->spec, QCfile, NULL),
+                       image_spec_value (img->spec, QCdata, NULL));
 }
-#endif /* MAC_OS */
+#endif /* HAVE_NS */
 
 #endif /* HAVE_GIF */
 
@@ -8248,11 +7360,11 @@ gif_load (f, img)
 
 /* Function prototypes.  */
 
-static int svg_image_p P_ ((Lisp_Object object));
-static int svg_load P_ ((struct frame *f, struct image *img));
+static int svg_image_p (Lisp_Object object);
+static int svg_load (struct frame *f, struct image *img);
 
-static int svg_load_image P_ ((struct frame *, struct image *,
-                              unsigned char *, unsigned int));
+static int svg_load_image (struct frame *, struct image *,
+                           unsigned char *, unsigned int);
 
 /* The symbol `svg' identifying images of this type. */
 
@@ -8278,7 +7390,7 @@ enum svg_keyword_index
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
-static struct image_keyword svg_format[SVG_LAST] =
+static const struct image_keyword svg_format[SVG_LAST] =
 {
   {":type",            IMAGE_SYMBOL_VALUE,                     1},
   {":data",            IMAGE_STRING_VALUE,                     0},
@@ -8317,8 +7429,7 @@ static struct image_type svg_type =
    identify the SVG format.   */
 
 static int
-svg_image_p (object)
-     Lisp_Object object;
+svg_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[SVG_LAST];
   bcopy (svg_format, fmt, sizeof fmt);
@@ -8336,7 +7447,7 @@ svg_image_p (object)
 
 /* SVG library functions.  */
 DEF_IMGLIB_FN (rsvg_handle_new);
-DEF_IMGLIB_FN (rsvg_handle_set_size_callback);
+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);
@@ -8355,20 +7466,21 @@ DEF_IMGLIB_FN (g_type_init);
 DEF_IMGLIB_FN (g_object_unref);
 DEF_IMGLIB_FN (g_error_free);
 
-Lisp_Object Qgdk_pixbuf, Qglib;
+Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
 
 static int
 init_svg_functions (Lisp_Object libraries)
 {
-  HMODULE library, gdklib, glib;
+  HMODULE library, gdklib, glib, gobject;
 
   if (!(glib = w32_delayed_load (libraries, Qglib))
+      || !(gobject = w32_delayed_load (libraries, Qgobject))
       || !(gdklib = w32_delayed_load (libraries, Qgdk_pixbuf))
       || !(library = w32_delayed_load (libraries, Qsvg)))
     return 0;
 
   LOAD_IMGLIB_FN (library, rsvg_handle_new);
-  LOAD_IMGLIB_FN (library, rsvg_handle_set_size_callback);
+  LOAD_IMGLIB_FN (library, rsvg_handle_get_dimensions);
   LOAD_IMGLIB_FN (library, rsvg_handle_write);
   LOAD_IMGLIB_FN (library, rsvg_handle_close);
   LOAD_IMGLIB_FN (library, rsvg_handle_get_pixbuf);
@@ -8383,9 +7495,10 @@ init_svg_functions (Lisp_Object libraries)
   LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_has_alpha);
   LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_bits_per_sample);
 
-  LOAD_IMGLIB_FN (glib, g_type_init);
-  LOAD_IMGLIB_FN (glib, g_object_unref);
+  LOAD_IMGLIB_FN (gobject, g_type_init);
+  LOAD_IMGLIB_FN (gobject, g_object_unref);
   LOAD_IMGLIB_FN (glib, g_error_free);
+
   return 1;
 }
 
@@ -8393,7 +7506,7 @@ init_svg_functions (Lisp_Object libraries)
 /* The following aliases for library functions allow dynamic loading
    to be used on some platforms.  */
 #define fn_rsvg_handle_new             rsvg_handle_new
-#define fn_rsvg_handle_set_size_callback rsvg_handle_set_size_callback
+#define fn_rsvg_handle_get_dimensions   rsvg_handle_get_dimensions
 #define fn_rsvg_handle_write           rsvg_handle_write
 #define fn_rsvg_handle_close           rsvg_handle_close
 #define fn_rsvg_handle_get_pixbuf      rsvg_handle_get_pixbuf
@@ -8418,9 +7531,7 @@ init_svg_functions (Lisp_Object libraries)
    the prototype thus needs to be compatible with that structure.  */
 
 static int
-svg_load (f, img)
-     struct frame *f;
-     struct image *img;
+svg_load (struct frame *f, struct image *img)
 {
   int success_p = 0;
   Lisp_Object file_name;
@@ -8477,17 +7588,13 @@ svg_load (f, img)
 
    Returns non-zero when successful.  */
 static int
-svg_load_image (f, img, contents, size)
-    /* Pointer to emacs frame structure.  */
-     struct frame *f;
-     /* Pointer to emacs image structure.  */
-     struct image *img;
-     /* String containing the SVG XML data to be parsed.  */
-     unsigned char *contents;
-     /* Size of data in bytes.  */
-     unsigned int size;
+svg_load_image (struct frame *f,         /* Pointer to emacs frame structure.  */
+               struct image *img,       /* Pointer to emacs image structure.  */
+               unsigned char *contents, /* String containing the SVG XML data to be parsed.  */
+               unsigned int size)       /* Size of data in bytes.  */
 {
   RsvgHandle *rsvg_handle;
+  RsvgDimensionData dimension_data;
   GError *error = NULL;
   GdkPixbuf *pixbuf;
   int width;
@@ -8504,27 +7611,34 @@ svg_load_image (f, img, contents, size)
      gnome type library functions.  */
   fn_g_type_init ();
   /* Make a handle to a new rsvg object.  */
-  rsvg_handle = fn_rsvg_handle_new ();
+  rsvg_handle = (RsvgHandle *) fn_rsvg_handle_new ();
 
   /* Parse the contents argument and fill in the rsvg_handle.  */
   fn_rsvg_handle_write (rsvg_handle, contents, size, &error);
-  if (error)
-    goto rsvg_error;
+  if (error) goto rsvg_error;
 
   /* The parsing is complete, rsvg_handle is ready to used, close it
      for further writes.  */
   fn_rsvg_handle_close (rsvg_handle, &error);
-  if (error)
-    goto rsvg_error;
+  if (error) goto rsvg_error;
+
+  fn_rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
+  if (! check_image_size (f, dimension_data.width, dimension_data.height))
+    {
+      image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
+      goto rsvg_error;
+    }
+
   /* We can now get a valid pixel buffer from the svg file, if all
      went ok.  */
-  pixbuf = fn_rsvg_handle_get_pixbuf (rsvg_handle);
-  eassert (pixbuf);
+  pixbuf = (GdkPixbuf *) 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    = fn_gdk_pixbuf_get_pixels (pixbuf);
+  pixels    = (const guint8 *) fn_gdk_pixbuf_get_pixels (pixbuf);
   rowstride = fn_gdk_pixbuf_get_rowstride (pixbuf);
 
   /* Validate the svg meta data.  */
@@ -8545,47 +7659,24 @@ svg_load_image (f, img, contents, size)
   /* Handle alpha channel by combining the image with a background
      color.  */
   specified_bg = image_spec_value (img->spec, QCbackground, NULL);
-  if (STRINGP (specified_bg)
-      && x_defined_color (f, SDATA (specified_bg), &background, 0))
-    {
-      background.red   >>= 8;
-      background.green >>= 8;
-      background.blue  >>= 8;
-    }
-  else
+  if (!STRINGP (specified_bg)
+      || !x_defined_color (f, SDATA (specified_bg), &background, 0))
     {
-#ifdef HAVE_X_WINDOWS
-      background.pixel = FRAME_BACKGROUND_PIXEL (f);
-      x_query_color (f, &background);
-
-      /* SVG pixmaps specify transparency in the last byte, so right
-        shift 8 bits to get rid of it, since emacs doesn't support
-        transparency.  */
-      background.red   >>= 8;
-      background.green >>= 8;
-      background.blue  >>= 8;
-#elif defined (MAC_OS)
+#ifndef HAVE_NS
       background.pixel = FRAME_BACKGROUND_PIXEL (f);
-      background.red   = RED_FROM_ULONG (background.pixel);
-      background.green = GREEN_FROM_ULONG (background.pixel);
-      background.blue  = BLUE_FROM_ULONG (background.pixel);
-#elif defined (HAVE_NTGUI)
-      background.pixel = FRAME_BACKGROUND_PIXEL (f);
-#if 0 /* W32 TODO : Colormap support.  */
       x_query_color (f, &background);
-#endif
-
-      /* SVG pixmaps specify transparency in the last byte, so right
-        shift 8 bits to get rid of it, since emacs doesn't support
-        transparency.  */
-      background.red   >>= 8;
-      background.green >>= 8;
-      background.blue  >>= 8;
-#else /* not HAVE_X_WINDOWS && not MAC_OS*/
-#error FIXME
+#else
+      ns_query_color(FRAME_BACKGROUND_COLOR (f), &background, 1);
 #endif
     }
 
+  /* SVG pixmaps specify transparency in the last byte, so right
+     shift 8 bits to get rid of it, since emacs doesn't support
+     transparency.  */
+  background.red   >>= 8;
+  background.green >>= 8;
+  background.blue  >>= 8;
+
   /* This loop handles opacity values, since Emacs assumes
      non-transparent images.  Each pixel must be "flattened" by
      calculating the resulting color, given the transparency of the
@@ -8640,6 +7731,7 @@ svg_load_image (f, img, contents, size)
   return 1;
 
  rsvg_error:
+  fn_g_object_unref (rsvg_handle);
   /* FIXME: Use error->message so the user knows what is the actual
      problem with the image.  */
   image_error ("Error parsing SVG image `%s'", img->spec, Qnil);
@@ -8666,9 +7758,9 @@ Lisp_Object Qpostscript;
 
 #ifdef HAVE_GHOSTSCRIPT
 
-static int gs_image_p P_ ((Lisp_Object object));
-static int gs_load P_ ((struct frame *f, struct image *img));
-static void gs_clear_image P_ ((struct frame *f, struct image *img));
+static int gs_image_p (Lisp_Object object);
+static int gs_load (struct frame *f, struct image *img);
+static void gs_clear_image (struct frame *f, struct image *img);
 
 /* Keyword symbols.  */
 
@@ -8697,7 +7789,7 @@ enum gs_keyword_index
 /* Vector of image_keyword structures describing the format
    of valid user-defined image specifications.  */
 
-static struct image_keyword gs_format[GS_LAST] =
+static const struct image_keyword gs_format[GS_LAST] =
 {
   {":type",            IMAGE_SYMBOL_VALUE,                     1},
   {":pt-width",                IMAGE_POSITIVE_INTEGER_VALUE,           1},
@@ -8729,9 +7821,7 @@ static struct image_type gs_type =
 /* Free X resources of Ghostscript image IMG which is used on frame F.  */
 
 static void
-gs_clear_image (f, img)
-     struct frame *f;
-     struct image *img;
+gs_clear_image (struct frame *f, struct image *img)
 {
   /* IMG->data.ptr_val may contain a recorded colormap.  */
   xfree (img->data.ptr_val);
@@ -8743,8 +7833,7 @@ gs_clear_image (f, img)
    specification.  */
 
 static int
-gs_image_p (object)
-     Lisp_Object object;
+gs_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[GS_LAST];
   Lisp_Object tem;
@@ -8784,9 +7873,7 @@ gs_image_p (object)
    if successful.  */
 
 static int
-gs_load (f, img)
-     struct frame *f;
-     struct image *img;
+gs_load (struct frame *f, struct image *img)
 {
   char buffer[100];
   Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
@@ -8808,7 +7895,7 @@ gs_load (f, img)
 
   if (!check_image_size (f, img->width, img->height))
     {
-      image_error ("Invalid image size", Qnil, Qnil);
+      image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       return 0;
     }
 
@@ -8864,9 +7951,7 @@ gs_load (f, img)
    telling Emacs that Ghostscript has finished drawing.  */
 
 void
-x_kill_gs_process (pixmap, f)
-     Pixmap pixmap;
-     struct frame *f;
+x_kill_gs_process (Pixmap pixmap, struct frame *f)
 {
   struct image_cache *c = FRAME_IMAGE_CACHE (f);
   int class, i;
@@ -9018,27 +8103,27 @@ of `image-library-alist', which see).  */)
   if (CONSP (tested))
     return XCDR (tested);
 
-#if defined (HAVE_XPM) || defined (MAC_OS)
+#if defined (HAVE_XPM) || defined (HAVE_NS)
   if (EQ (type, Qxpm))
     return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries);
 #endif
 
-#if defined (HAVE_JPEG) || defined (MAC_OS)
+#if defined (HAVE_JPEG) || defined (HAVE_NS)
   if (EQ (type, Qjpeg))
     return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries);
 #endif
 
-#if defined (HAVE_TIFF) || defined (MAC_OS)
+#if defined (HAVE_TIFF) || defined (HAVE_NS)
   if (EQ (type, Qtiff))
     return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries);
 #endif
 
-#if defined (HAVE_GIF) || defined (MAC_OS)
+#if defined (HAVE_GIF) || defined (HAVE_NS)
   if (EQ (type, Qgif))
     return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries);
 #endif
 
-#if defined (HAVE_PNG) || defined (MAC_OS)
+#if defined (HAVE_PNG) || defined (HAVE_NS)
   if (EQ (type, Qpng))
     return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries);
 #endif
@@ -9059,7 +8144,7 @@ of `image-library-alist', which see).  */)
 }
 
 void
-syms_of_image ()
+syms_of_image (void)
 {
   extern Lisp_Object Qrisky_local_variable;   /* Syms_of_xdisp has already run.  */
 
@@ -9088,7 +8173,7 @@ 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 ("image-library-alist"), Qrisky_local_variable, Qt);
+  Fput (intern_c_string ("image-library-alist"), Qrisky_local_variable, Qt);
 
   DEFVAR_LISP ("max-image-size", &Vmax_image_size,
     doc: /* Maximum size of images.
@@ -9105,112 +8190,117 @@ non-numeric, there is no explicit limit on the size of images.  */);
   Vimage_type_cache = Qnil;
   staticpro (&Vimage_type_cache);
 
-  Qpbm = intern ("pbm");
+  Qpbm = intern_c_string ("pbm");
   staticpro (&Qpbm);
   ADD_IMAGE_TYPE (Qpbm);
 
-  Qxbm = intern ("xbm");
+  Qxbm = intern_c_string ("xbm");
   staticpro (&Qxbm);
   ADD_IMAGE_TYPE (Qxbm);
 
   define_image_type (&xbm_type, 1);
   define_image_type (&pbm_type, 1);
 
-  Qcount = intern ("count");
+  Qcount = intern_c_string ("count");
   staticpro (&Qcount);
+  Qextension_data = intern_c_string ("extension-data");
+  staticpro (&Qextension_data);
 
-  QCascent = intern (":ascent");
+  QCascent = intern_c_string (":ascent");
   staticpro (&QCascent);
-  QCmargin = intern (":margin");
+  QCmargin = intern_c_string (":margin");
   staticpro (&QCmargin);
-  QCrelief = intern (":relief");
+  QCrelief = intern_c_string (":relief");
   staticpro (&QCrelief);
-  QCconversion = intern (":conversion");
+  QCconversion = intern_c_string (":conversion");
   staticpro (&QCconversion);
-  QCcolor_symbols = intern (":color-symbols");
+  QCcolor_symbols = intern_c_string (":color-symbols");
   staticpro (&QCcolor_symbols);
-  QCheuristic_mask = intern (":heuristic-mask");
+  QCheuristic_mask = intern_c_string (":heuristic-mask");
   staticpro (&QCheuristic_mask);
-  QCindex = intern (":index");
+  QCindex = intern_c_string (":index");
   staticpro (&QCindex);
-  QCmatrix = intern (":matrix");
+  QCmatrix = intern_c_string (":matrix");
   staticpro (&QCmatrix);
-  QCcolor_adjustment = intern (":color-adjustment");
+  QCcolor_adjustment = intern_c_string (":color-adjustment");
   staticpro (&QCcolor_adjustment);
-  QCmask = intern (":mask");
+  QCmask = intern_c_string (":mask");
   staticpro (&QCmask);
 
-  Qlaplace = intern ("laplace");
+  Qlaplace = intern_c_string ("laplace");
   staticpro (&Qlaplace);
-  Qemboss = intern ("emboss");
+  Qemboss = intern_c_string ("emboss");
   staticpro (&Qemboss);
-  Qedge_detection = intern ("edge-detection");
+  Qedge_detection = intern_c_string ("edge-detection");
   staticpro (&Qedge_detection);
-  Qheuristic = intern ("heuristic");
+  Qheuristic = intern_c_string ("heuristic");
   staticpro (&Qheuristic);
 
-  Qpostscript = intern ("postscript");
+  Qpostscript = intern_c_string ("postscript");
   staticpro (&Qpostscript);
 #ifdef HAVE_GHOSTSCRIPT
   ADD_IMAGE_TYPE (Qpostscript);
-  QCloader = intern (":loader");
+  QCloader = intern_c_string (":loader");
   staticpro (&QCloader);
-  QCbounding_box = intern (":bounding-box");
+  QCbounding_box = intern_c_string (":bounding-box");
   staticpro (&QCbounding_box);
-  QCpt_width = intern (":pt-width");
+  QCpt_width = intern_c_string (":pt-width");
   staticpro (&QCpt_width);
-  QCpt_height = intern (":pt-height");
+  QCpt_height = intern_c_string (":pt-height");
   staticpro (&QCpt_height);
 #endif /* HAVE_GHOSTSCRIPT */
 
-#if defined (HAVE_XPM) || defined (MAC_OS)
-  Qxpm = intern ("xpm");
+#if defined (HAVE_XPM) || defined (HAVE_NS)
+  Qxpm = intern_c_string ("xpm");
   staticpro (&Qxpm);
   ADD_IMAGE_TYPE (Qxpm);
 #endif
 
-#if defined (HAVE_JPEG) || defined (MAC_OS)
-  Qjpeg = intern ("jpeg");
+#if defined (HAVE_JPEG) || defined (HAVE_NS)
+  Qjpeg = intern_c_string ("jpeg");
   staticpro (&Qjpeg);
   ADD_IMAGE_TYPE (Qjpeg);
 #endif
 
-#if defined (HAVE_TIFF) || defined (MAC_OS)
-  Qtiff = intern ("tiff");
+#if defined (HAVE_TIFF) || defined (HAVE_NS)
+  Qtiff = intern_c_string ("tiff");
   staticpro (&Qtiff);
   ADD_IMAGE_TYPE (Qtiff);
 #endif
 
-#if defined (HAVE_GIF) || defined (MAC_OS)
-  Qgif = intern ("gif");
+#if defined (HAVE_GIF) || defined (HAVE_NS)
+  Qgif = intern_c_string ("gif");
   staticpro (&Qgif);
   ADD_IMAGE_TYPE (Qgif);
 #endif
 
-#if defined (HAVE_PNG) || defined (MAC_OS)
-  Qpng = intern ("png");
+#if defined (HAVE_PNG) || defined (HAVE_NS)
+  Qpng = intern_c_string ("png");
   staticpro (&Qpng);
   ADD_IMAGE_TYPE (Qpng);
 #endif
 
 #if defined (HAVE_RSVG)
-  Qsvg = intern ("svg");
+  Qsvg = intern_c_string ("svg");
   staticpro (&Qsvg);
   ADD_IMAGE_TYPE (Qsvg);
 #ifdef HAVE_NTGUI
-  Qgdk_pixbuf = intern ("gdk-pixbuf");
+  /* Other libraries used directly by svg code.  */
+  Qgdk_pixbuf = intern_c_string ("gdk-pixbuf");
   staticpro (&Qgdk_pixbuf);
-  Qglib = intern ("glib");
+  Qglib = intern_c_string ("glib");
   staticpro (&Qglib);
+  Qgobject = intern_c_string ("gobject");
+  staticpro (&Qgobject);
 #endif /* HAVE_NTGUI  */
 #endif /* HAVE_RSVG  */
 
   defsubr (&Sinit_image_library);
   defsubr (&Sclear_image_cache);
-  defsubr (&Simage_refresh);
+  defsubr (&Simage_flush);
   defsubr (&Simage_size);
   defsubr (&Simage_mask_p);
-  defsubr (&Simage_extension_data);
+  defsubr (&Simage_metadata);
 
 #if GLYPH_DEBUG
   defsubr (&Simagep);
@@ -9228,19 +8318,19 @@ A cross is always drawn on black & white displays.  */);
   Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
 
   DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
-    doc: /* Time after which cached images are removed from the cache.
-When an image has not been displayed this many seconds, remove it
-from the image cache.  Value must be an integer or nil with nil
-meaning don't clear the cache.  */);
-  Vimage_cache_eviction_delay = make_number (30 * 60);
+    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);
 }
 
 void
-init_image ()
+init_image (void)
 {
-#if defined (MAC_OSX) && TARGET_API_MAC_CARBON
-  init_image_func_pointer ();
-#endif
 }
 
 /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9