Add bug reference.
[bpt/emacs.git] / src / image.c
index 1b024e5..6701637 100644 (file)
@@ -1,13 +1,14 @@
 /* Functions for image support on window system.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
 /* 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 Free Software Foundation, Inc.
+                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+                 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+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
 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
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,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
 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>
 
 #include <config.h>
 #include <stdio.h>
@@ -39,9 +38,10 @@ Boston, MA 02110-1301, USA.  */
 #include "blockinput.h"
 #include "systime.h"
 #include <epaths.h>
 #include "blockinput.h"
 #include "systime.h"
 #include <epaths.h>
-#include "charset.h"
+#include "character.h"
 #include "coding.h"
 #include "coding.h"
-
+#include "termhooks.h"
+#include "font.h"
 
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
@@ -81,49 +81,30 @@ typedef struct w32_bitmap_record Bitmap_Record;
 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
 #endif /* HAVE_NTGUI */
 
 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
 #endif /* HAVE_NTGUI */
 
-
-#ifdef MAC_OS
-#include "macterm.h"
+#ifdef HAVE_NS
+#include "nsterm.h"
+#include <sys/types.h>
 #include <sys/stat.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
 
 #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 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.  */
 
 
 /* Search path for bitmap files.  */
@@ -165,6 +146,7 @@ XGetImage (display, pixmap, x, y, width, height, plane_mask, format)
      unsigned long plane_mask;         /* not used */
      int format;               /* not used */
 {
      unsigned long plane_mask;         /* not used */
      int format;               /* not used */
 {
+#if !USE_MAC_IMAGE_IO
 #if GLYPH_DEBUG
   xassert (x == 0 && y == 0);
   {
 #if GLYPH_DEBUG
   xassert (x == 0 && y == 0);
   {
@@ -176,6 +158,7 @@ XGetImage (display, pixmap, x, y, width, height, plane_mask, format)
 #endif
 
   LockPixels (GetGWorldPixMap (pixmap));
 #endif
 
   LockPixels (GetGWorldPixMap (pixmap));
+#endif
 
   return pixmap;
 }
 
   return pixmap;
 }
@@ -186,6 +169,12 @@ XPutPixel (ximage, x, y, pixel)
      int x, y;
      unsigned long pixel;
 {
      int x, y;
      unsigned long pixel;
 {
+#if USE_MAC_IMAGE_IO
+  if (ximage->bits_per_pixel == 32)
+    ((unsigned int *)(ximage->data + y * ximage->bytes_per_line))[x] = pixel;
+  else
+    ((unsigned char *)(ximage->data + y * ximage->bytes_per_line))[x] = pixel;
+#else
   PixMapHandle pixmap = GetGWorldPixMap (ximage);
   short depth = GetPixDepth (pixmap);
 
   PixMapHandle pixmap = GetGWorldPixMap (ximage);
   short depth = GetPixDepth (pixmap);
 
@@ -226,6 +215,7 @@ XPutPixel (ximage, x, y, pixel)
 
       SetGWorld (old_port, old_gdh);
     }
 
       SetGWorld (old_port, old_gdh);
     }
+#endif
 }
 
 static unsigned long
 }
 
 static unsigned long
@@ -233,6 +223,12 @@ XGetPixel (ximage, x, y)
      XImagePtr ximage;
      int x, y;
 {
      XImagePtr ximage;
      int x, y;
 {
+#if USE_MAC_IMAGE_IO
+  if (ximage->bits_per_pixel == 32)
+    return ((unsigned int *)(ximage->data + y * ximage->bytes_per_line))[x];
+  else
+    return ((unsigned char *)(ximage->data + y * ximage->bytes_per_line))[x];
+#else
   PixMapHandle pixmap = GetGWorldPixMap (ximage);
   short depth = GetPixDepth (pixmap);
 
   PixMapHandle pixmap = GetGWorldPixMap (ximage);
   short depth = GetPixDepth (pixmap);
 
@@ -270,21 +266,78 @@ XGetPixel (ximage, x, y)
       SetGWorld (old_port, old_gdh);
       return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8);
     }
       SetGWorld (old_port, old_gdh);
       return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8);
     }
+#endif
 }
 
 static void
 XDestroyImage (ximg)
      XImagePtr ximg;
 {
 }
 
 static void
 XDestroyImage (ximg)
      XImagePtr ximg;
 {
+#if !USE_MAC_IMAGE_IO
   UnlockPixels (GetGWorldPixMap (ximg));
   UnlockPixels (GetGWorldPixMap (ximg));
+#endif
 }
 
 #if USE_CG_DRAWING
 }
 
 #if USE_CG_DRAWING
+#if USE_MAC_IMAGE_IO
+void
+mac_data_provider_release_data (info, data, size)
+     void *info;
+     const void *data;
+     size_t size;
+{
+  xfree ((void *)data);
+}
+#endif
+
 static CGImageRef
 mac_create_cg_image_from_image (f, img)
      struct frame *f;
      struct image *img;
 {
 static CGImageRef
 mac_create_cg_image_from_image (f, img)
      struct frame *f;
      struct image *img;
 {
+#if USE_MAC_IMAGE_IO
+  XImagePtr ximg = img->pixmap;
+  CGDataProviderRef provider;
+  CGImageRef result;
+
+  if (img->mask)
+    {
+      int x, y;
+      unsigned long color, alpha;
+
+      for (y = 0; y < ximg->height; y++)
+       for (x = 0; x < ximg->width; x++)
+         {
+           color = XGetPixel (ximg, x, y);
+           alpha = XGetPixel (img->mask, x, y);
+           XPutPixel (ximg, x, y,
+                      ARGB_TO_ULONG (alpha,
+                                     RED_FROM_ULONG (color)
+                                     * alpha / PIX_MASK_DRAW,
+                                     GREEN_FROM_ULONG (color)
+                                     * alpha / PIX_MASK_DRAW,
+                                     BLUE_FROM_ULONG (color)
+                                     * alpha / PIX_MASK_DRAW));
+         }
+      xfree (img->mask->data);
+      img->mask->data = NULL;
+    }
+  BLOCK_INPUT;
+  provider = CGDataProviderCreateWithData (NULL, ximg->data,
+                                          ximg->bytes_per_line * ximg->height,
+                                          mac_data_provider_release_data);
+  ximg->data = NULL;
+  result = CGImageCreate (ximg->width, ximg->height, 8, 32,
+                         ximg->bytes_per_line, mac_cg_color_space_rgb,
+                         ((img->mask ? kCGImageAlphaPremultipliedFirst
+                           : kCGImageAlphaNoneSkipFirst)
+                          | kCGBitmapByteOrder32Host),
+                         provider, NULL, 0, kCGRenderingIntentDefault);
+  CGDataProviderRelease (provider);
+  UNBLOCK_INPUT;
+
+  return result;
+#else
   Pixmap mask;
   CGImageRef result = NULL;
 
   Pixmap mask;
   CGImageRef result = NULL;
 
@@ -319,10 +372,38 @@ mac_create_cg_image_from_image (f, img)
   UNBLOCK_INPUT;
 
   return result;
   UNBLOCK_INPUT;
 
   return result;
+#endif
 }
 #endif /* USE_CG_DRAWING */
 #endif /* MAC_OS */
 
 }
 #endif /* USE_CG_DRAWING */
 #endif /* MAC_OS */
 
+#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)
+{
+  /* TODO: not sure what this function is supposed to do.. */
+  ns_retain_object(pixmap);
+  return pixmap;
+}
+
+/* use with imgs created by ns_image_for_XPM */
+unsigned long
+XGetPixel (XImagePtr ximage, int x, int y)
+{
+  return ns_get_pixel(ximage, x, y);
+}
+
+/* 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)
+{
+  ns_put_pixel(ximage, x, y, pixel);
+}
+#endif /* HAVE_NS */
+
 
 /* Functions to access the contents of a bitmap, given an id.  */
 
 
 /* Functions to access the contents of a bitmap, given an id.  */
 
@@ -433,17 +514,18 @@ x_create_bitmap_from_data (f, bits, width, height)
     return -1;
 #endif /* HAVE_NTGUI */
 
     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);
 #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;
 
   dpyinfo->bitmaps[id - 1].file = NULL;
   dpyinfo->bitmaps[id - 1].height = height;
@@ -472,16 +554,32 @@ x_create_bitmap_from_file (f, file)
      struct frame *f;
      Lisp_Object 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_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
 #ifdef HAVE_X_WINDOWS
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   unsigned int width, height;
   Pixmap bitmap;
   int xhot, yhot, result, id;
   unsigned int width, height;
   Pixmap bitmap;
   int xhot, yhot, result, id;
@@ -531,7 +629,7 @@ x_create_bitmap_from_file (f, file)
 /* Free bitmap B.  */
 
 static void
 /* Free bitmap B.  */
 
 static void
-Free_Bitmap_Record (dpyinfo, bm)
+free_bitmap_record (dpyinfo, bm)
      Display_Info *dpyinfo;
      Bitmap_Record *bm;
 {
      Display_Info *dpyinfo;
      Bitmap_Record *bm;
 {
@@ -545,10 +643,9 @@ Free_Bitmap_Record (dpyinfo, bm)
   DeleteObject (bm->pixmap);
 #endif /* HAVE_NTGUI */
 
   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)
     {
 
   if (bm->file)
     {
@@ -573,7 +670,7 @@ x_destroy_bitmap (f, id)
       if (--bm->refcount == 0)
        {
          BLOCK_INPUT;
       if (--bm->refcount == 0)
        {
          BLOCK_INPUT;
-         Free_Bitmap_Record (dpyinfo, bm);
+         free_bitmap_record (dpyinfo, bm);
          UNBLOCK_INPUT;
        }
     }
          UNBLOCK_INPUT;
        }
     }
@@ -590,7 +687,7 @@ x_destroy_all_bitmaps (dpyinfo)
 
   for (i = 0; i < dpyinfo->bitmaps_last; i++, bm++)
     if (bm->refcount > 0)
 
   for (i = 0; i < dpyinfo->bitmaps_last; i++, bm++)
     if (bm->refcount > 0)
-      Free_Bitmap_Record (dpyinfo, bm);
+      free_bitmap_record (dpyinfo, bm);
 
   dpyinfo->bitmaps_last = 0;
 }
 
   dpyinfo->bitmaps_last = 0;
 }
@@ -732,9 +829,9 @@ Lisp_Object Qxbm;
 /* Keywords.  */
 
 extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
 /* Keywords.  */
 
 extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
-extern Lisp_Object QCdata, QCtype, Qcount;
+extern Lisp_Object QCdata, QCtype;
 extern Lisp_Object Qcenter;
 extern Lisp_Object Qcenter;
-Lisp_Object QCascent, QCmargin, QCrelief;
+Lisp_Object QCascent, QCmargin, QCrelief, Qcount;
 Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
 Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
 
 Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
 Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
 
@@ -1183,9 +1280,11 @@ make_image (spec, hash)
      unsigned hash;
 {
   struct image *img = (struct image *) xmalloc (sizeof *img);
      unsigned 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);
 
   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;
   img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
   xassert (img->type != NULL);
   img->spec = spec;
@@ -1206,7 +1305,7 @@ free_image (f, img)
 {
   if (img)
     {
 {
   if (img)
     {
-      struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
+      struct image_cache *c = FRAME_IMAGE_CACHE (f);
 
       /* Remove IMG from the hash table of its cache.  */
       if (img->prev)
 
       /* Remove IMG from the hash table of its cache.  */
       if (img->prev)
@@ -1278,17 +1377,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 (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
 }
 
 
 }
 
 
@@ -1317,15 +1405,16 @@ image_ascent (img, face, slice)
        {
 #ifdef HAVE_NTGUI
          /* W32 specific version.  Why?. ++kfs  */
        {
 #ifdef HAVE_NTGUI
          /* W32 specific version.  Why?. ++kfs  */
-         ascent = height / 2 - (FONT_DESCENT(face->font)
-                                - FONT_BASE(face->font)) / 2;
+         ascent = height / 2 - (FONT_DESCENT (face->font)
+                                - FONT_BASE (face->font)) / 2;
 #else
          /* This expression is arranged so that if the image can't be
             exactly centered, it will be moved slightly up.  This is
             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.  */
 #else
          /* This expression is arranged so that if the image can't be
             exactly centered, it will be moved slightly up.  This is
             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
 #endif /* HAVE_NTGUI */
        }
       else
@@ -1394,6 +1483,14 @@ four_corners_best (ximg, corners, width, height)
 #define Free_Pixmap(display, pixmap) \
   DeleteObject (pixmap)
 
 #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) \
 #else
 
 #define Destroy_Image(ximg, dummy) \
@@ -1402,7 +1499,7 @@ four_corners_best (ximg, corners, width, height)
 #define Free_Pixmap(display, pixmap) \
   XFreePixmap (display, pixmap)
 
 #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,
 
 
 /* Return the `background' field of IMG.  If IMG doesn't have one yet,
@@ -1525,6 +1622,7 @@ x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
     {
       Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
       img->pixmap = NO_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;
     }
 
       img->background_valid = 0;
     }
 
@@ -1537,7 +1635,6 @@ x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
 
   if (colors_p && img->ncolors)
     {
 
   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);
       /* W32_TODO: color table support.  */
 #ifdef HAVE_X_WINDOWS
       x_free_colors (f, img->colors, img->ncolors);
@@ -1547,13 +1644,6 @@ x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
       img->ncolors = 0;
     }
 
       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.  */
 }
 
 /* Free X resources of image IMG which is used on frame F.  */
@@ -1641,7 +1731,7 @@ search_image_cache (f, spec, hash)
      unsigned hash;
 {
   struct image *img;
      unsigned hash;
 {
   struct image *img;
-  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
+  struct image_cache *c = FRAME_IMAGE_CACHE (f);
   int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
 
   if (!c) return NULL;
   int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
 
   if (!c) return NULL;
@@ -1688,7 +1778,7 @@ void
 free_image_cache (f)
      struct frame *f;
 {
 free_image_cache (f)
      struct frame *f;
 {
-  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
+  struct image_cache *c = FRAME_IMAGE_CACHE (f);
   if (c)
     {
       int i;
   if (c)
     {
       int i;
@@ -1701,26 +1791,25 @@ free_image_cache (f)
       xfree (c->images);
       xfree (c->buckets);
       xfree (c);
       xfree (c->images);
       xfree (c->buckets);
       xfree (c);
-      FRAME_X_IMAGE_CACHE (f) = NULL;
+      FRAME_IMAGE_CACHE (f) = NULL;
     }
 }
 
 
     }
 }
 
 
-/* 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-eviction-seconds 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
 
 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_X_IMAGE_CACHE (f);
+  struct image_cache *c = FRAME_IMAGE_CACHE (f);
 
 
-  if (c && INTEGERP (Vimage_cache_eviction_delay))
+  if (c && (!NILP (filter) || INTEGERP (Vimage_cache_eviction_delay)))
     {
       EMACS_TIME t;
       unsigned long old;
     {
       EMACS_TIME t;
       unsigned long old;
@@ -1737,7 +1826,9 @@ clear_image_cache (f, force_p)
        {
          struct image *img = c->images[i];
          if (img != NULL
        {
          struct image *img = c->images[i];
          if (img != NULL
-             && (force_p || img->timestamp < old))
+             && (NILP (filter) ? img->timestamp < old
+                 : (EQ (Qt, filter)
+                    || !NILP (Fmember (filter, img->dependencies)))))
            {
              free_image (f, img);
              ++nfreed;
            {
              free_image (f, img);
              ++nfreed;
@@ -1755,8 +1846,7 @@ clear_image_cache (f, force_p)
          FOR_EACH_FRAME (tail, frame)
            {
              struct frame *f = XFRAME (frame);
          FOR_EACH_FRAME (tail, frame)
            {
              struct frame *f = XFRAME (frame);
-             if (FRAME_WINDOW_P (f)
-                 && FRAME_X_IMAGE_CACHE (f) == c)
+             if (FRAME_IMAGE_CACHE (f) == c)
                clear_current_matrices (f);
            }
 
                clear_current_matrices (f);
            }
 
@@ -1767,25 +1857,33 @@ clear_image_cache (f, force_p)
     }
 }
 
     }
 }
 
+void
+clear_image_caches (Lisp_Object filter)
+{
+  /* FIXME: We want to do
+   * struct terminal *t;
+   * for (t = terminal_list; t; t = t->next_terminal)
+   *   clear_image_cache (t, filter); */
+  Lisp_Object tail, frame;
+  FOR_EACH_FRAME (tail, frame)
+    if (FRAME_WINDOW_P (XFRAME (frame)))
+      clear_image_cache (XFRAME (frame), filter);
+}
 
 DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
        0, 1, 0,
 
 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))
-    {
-      Lisp_Object tail;
-
-      FOR_EACH_FRAME (tail, frame)
-       if (FRAME_WINDOW_P (XFRAME (frame)))
-         clear_image_cache (XFRAME (frame), 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
   else
-    clear_image_cache (check_x_frame (frame), 1);
+    clear_image_cache (check_x_frame (filter), Qt);
 
   return Qnil;
 }
 
   return Qnil;
 }
@@ -1904,6 +2002,7 @@ lookup_image (f, spec)
      struct frame *f;
      Lisp_Object spec;
 {
      struct frame *f;
      Lisp_Object spec;
 {
+  struct image_cache *c;
   struct image *img;
   unsigned hash;
   struct gcpro gcpro1;
   struct image *img;
   unsigned hash;
   struct gcpro gcpro1;
@@ -1914,6 +2013,8 @@ lookup_image (f, spec)
   xassert (FRAME_WINDOW_P (f));
   xassert (valid_image_p (spec));
 
   xassert (FRAME_WINDOW_P (f));
   xassert (valid_image_p (spec));
 
+  c = FRAME_IMAGE_CACHE (f);
+
   GCPRO1 (spec);
 
   /* Look up SPEC in the hash table of the image cache.  */
   GCPRO1 (spec);
 
   /* Look up SPEC in the hash table of the image cache.  */
@@ -1980,8 +2081,8 @@ lookup_image (f, spec)
          if (INTEGERP (relief))
            {
              img->relief = XINT (relief);
          if (INTEGERP (relief))
            {
              img->relief = XINT (relief);
-             img->hmargin += abs (img->relief);
-             img->vmargin += abs (img->relief);
+             img->hmargin += eabs (img->relief);
+             img->vmargin += eabs (img->relief);
            }
 
          if (! img->background_valid)
            }
 
          if (! img->background_valid)
@@ -2023,7 +2124,7 @@ cache_image (f, img)
      struct frame *f;
      struct image *img;
 {
      struct frame *f;
      struct image *img;
 {
-  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
+  struct image_cache *c = FRAME_IMAGE_CACHE (f);
   int i;
 
   /* Find a free slot in c->images.  */
   int i;
 
   /* Find a free slot in c->images.  */
@@ -2058,28 +2159,36 @@ cache_image (f, img)
 /* Call FN on every image in the image cache of frame F.  Used to mark
    Lisp Objects in the image cache.  */
 
 /* Call FN on every image in the image cache of frame F.  Used to mark
    Lisp Objects in the image cache.  */
 
+/* Mark Lisp objects in image IMG.  */
+
+static void
+mark_image (img)
+     struct image *img;
+{
+  mark_object (img->spec);
+  mark_object (img->dependencies);
+
+  if (!NILP (img->data.lisp_val))
+    mark_object (img->data.lisp_val);
+}
+
+
 void
 void
-forall_images_in_image_cache (f, fn)
-     struct frame *f;
-     void (*fn) P_ ((struct image *img));
+mark_image_cache (struct image_cache *c)
 {
 {
-  if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f))
+  if (c)
     {
     {
-      struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
-      if (c)
-       {
-         int i;
-         for (i = 0; i < c->used; ++i)
-           if (c->images[i])
-             fn (c->images[i]);
-       }
+      int i;
+      for (i = 0; i < c->used; ++i)
+       if (c->images[i])
+         mark_image (c->images[i]);
     }
 }
 
 
 \f
 /***********************************************************************
     }
 }
 
 
 \f
 /***********************************************************************
-                         X / MAC / W32 support code
+                         X / NS / W32 support code
  ***********************************************************************/
 
 #ifdef HAVE_NTGUI
  ***********************************************************************/
 
 #ifdef HAVE_NTGUI
@@ -2095,7 +2204,7 @@ forall_images_in_image_cache (f, fn)
 
 /* Load a DLL implementing an image type.
    The `image-library-alist' variable associates a symbol,
 
 /* Load a DLL implementing an image type.
    The `image-library-alist' variable associates a symbol,
-   identifying  an image type, to a list of possible filenames.
+   identifying an image type, to a list of possible filenames.
    The function returns NULL if no library could be loaded for
    the given image type, or if the library was previously loaded;
    else the handle of the DLL.  */
    The function returns NULL if no library could be loaded for
    the given image type, or if the library was previously loaded;
    else the handle of the DLL.  */
@@ -2251,7 +2360,7 @@ x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
 
   if (*pixmap == NULL)
     {
 
   if (*pixmap == NULL)
     {
-      DWORD err = GetLastError();
+      DWORD err = GetLastError ();
       Lisp_Object errcode;
       /* All system errors are < 10000, so the following is safe.  */
       XSETINT (errcode, (int) err);
       Lisp_Object errcode;
       /* All system errors are < 10000, so the following is safe.  */
       XSETINT (errcode, (int) err);
@@ -2264,26 +2373,17 @@ x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
 
 #endif /* HAVE_NTGUI */
 
 
 #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;
     {
       *ximg = NULL;
-      image_error ("Unable to create X pixmap", Qnil, Qnil);
+      image_error ("Unable to allocate NSImage for XPM pixmap", Qnil, Qnil);
       return 0;
     }
       return 0;
     }
-
-  LockPixels (GetGWorldPixMap (*pixmap));
   *ximg = *pixmap;
   return 1;
   *ximg = *pixmap;
   return 1;
-
-#endif  /* MAC_OS */
+#endif
 }
 
 
 }
 
 
@@ -2306,9 +2406,9 @@ x_destroy_x_image (ximg)
       ximg->data = NULL;
       xfree (ximg);
 #endif /* HAVE_NTGUI */
       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 */
     }
 }
 
     }
 }
 
@@ -2340,9 +2440,10 @@ x_put_x_image (f, ximg, pixmap, width, height)
 #endif
 #endif /* HAVE_NTGUI */
 
 #endif
 #endif /* HAVE_NTGUI */
 
-#ifdef MAC_OS
+#ifdef HAVE_NS
   xassert (ximg == pixmap);
   xassert (ximg == pixmap);
-#endif  /* MAC_OS */
+  ns_retain_object(ximg);
+#endif
 }
 
 \f
 }
 
 \f
@@ -2353,7 +2454,7 @@ x_put_x_image (f, ximg, pixmap, width, height)
 static unsigned char *slurp_file P_ ((char *, int *));
 
 
 static unsigned char *slurp_file P_ ((char *, int *));
 
 
-/* Find image file FILE.  Look in data-directory, then
+/* Find image file FILE.  Look in data-directory/images, then
    x-bitmap-file-path.  Value is the encoded full name of the file
    found, or nil if not found.  */
 
    x-bitmap-file-path.  Value is the encoded full name of the file
    found, or nil if not found.  */
 
@@ -2366,10 +2467,14 @@ x_find_image_file (file)
   int fd;
 
   file_found = Qnil;
   int fd;
 
   file_found = Qnil;
-  search_path = Fcons (Vdata_directory, Vx_bitmap_file_path);
+  /* TODO I think this should use something like image-load-path
+     instead.  Unfortunately, that can contain non-string elements.  */
+  search_path = Fcons (Fexpand_file_name (build_string ("images"),
+                                         Vdata_directory),
+                      Vx_bitmap_file_path);
   GCPRO2 (file_found, search_path);
 
   GCPRO2 (file_found, search_path);
 
-  /* Try to find FILE in data-directory, then x-bitmap-file-path.  */
+  /* Try to find FILE in data-directory/images, then x-bitmap-file-path.  */
   fd = openp (search_path, file, Qnil, &file_found, Qnil);
 
   if (fd == -1)
   fd = openp (search_path, file, Qnil, &file_found, Qnil);
 
   if (fd == -1)
@@ -2422,367 +2527,6 @@ slurp_file (file, size)
 
 
 \f
 
 
 \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
  ***********************************************************************/
 /***********************************************************************
                              XBM images
  ***********************************************************************/
@@ -2878,7 +2622,7 @@ enum xbm_token
    3. a vector of strings or bool-vectors, one for each line of the
    bitmap.
 
    3. a vector of strings or bool-vectors, one for each line of the
    bitmap.
 
-   4. A string containing an in-memory XBM file.  WIDTH and HEIGHT
+   4. a string containing an in-memory XBM file.  WIDTH and HEIGHT
    may not be specified in this case because they are defined in the
    XBM file.
 
    may not be specified in this case because they are defined in the
    XBM file.
 
@@ -3120,6 +2864,8 @@ convert_mono_to_color_image (f, img, foreground, background)
   release_frame_dc (f, hdc);
   old_prev = SelectObject (old_img_dc, img->pixmap);
   new_prev = SelectObject (new_img_dc, new_pixmap);
   release_frame_dc (f, hdc);
   old_prev = SelectObject (old_img_dc, img->pixmap);
   new_prev = SelectObject (new_img_dc, new_pixmap);
+  /* Windows convention for mono bitmaps is black = background,
+     white = foreground.  */
   SetTextColor (new_img_dc, background);
   SetBkColor (new_img_dc, foreground);
 
   SetTextColor (new_img_dc, background);
   SetBkColor (new_img_dc, foreground);
 
@@ -3147,7 +2893,7 @@ convert_mono_to_color_image (f, img, foreground, background)
 
 
 static void
 
 
 static void
-Create_Pixmap_From_Bitmap_Data(f, img, data, fg, bg, non_default_colors)
+Create_Pixmap_From_Bitmap_Data (f, img, data, fg, bg, non_default_colors)
      struct frame *f;
      struct image *img;
      char *data;
      struct frame *f;
      struct image *img;
      char *data;
@@ -3161,6 +2907,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);
   /* 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),
 #else
   img->pixmap
     = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
@@ -3169,7 +2919,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)));
                                   img->width, img->height,
                                   fg, bg,
                                   DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
-#endif /* HAVE_NTGUI */
+#endif /* !HAVE_NTGUI && !HAVE_NS */
 }
 
 
 }
 
 
@@ -3515,6 +3265,19 @@ xbm_load (f, img)
          else
            bits = XBOOL_VECTOR (data)->data;
 
          else
            bits = XBOOL_VECTOR (data)->data;
 
+#ifdef WINDOWSNT
+          {
+            char *invertedBits;
+            int nbytes, i;
+            /* Windows mono bitmaps are reversed compared with X.  */
+            invertedBits = bits;
+            nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR 
+              * img->height;
+            bits = (char *) alloca(nbytes);
+            for (i = 0; i < nbytes; i++)
+              bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
+          }
+#endif
          /* Create the pixmap.  */
 
          Create_Pixmap_From_Bitmap_Data (f, img, bits,
          /* Create the pixmap.  */
 
          Create_Pixmap_From_Bitmap_Data (f, img, bits,
@@ -3540,13 +3303,13 @@ xbm_load (f, img)
                              XPM images
  ***********************************************************************/
 
                              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 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));
 
-#endif /* HAVE_XPM || MAC_OS */
+#endif /* HAVE_XPM || HAVE_NS */
 
 #ifdef HAVE_XPM
 #ifdef HAVE_NTGUI
 
 #ifdef HAVE_XPM
 #ifdef HAVE_NTGUI
@@ -3569,7 +3332,7 @@ static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
 #endif /* HAVE_NTGUI */
 #endif /* HAVE_XPM */
 
 #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;
 /* The symbol `xpm' identifying XPM-format images.  */
 
 Lisp_Object Qxpm;
@@ -3896,7 +3659,7 @@ xpm_image_p (object)
              || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
 }
 
              || 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
 
 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
 int
@@ -4175,9 +3938,9 @@ xpm_load (f, img)
 
 #endif /* HAVE_XPM */
 
 
 #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 *,
    Only XPM version 3 (without any extensions) is supported.  */
 
 static int xpm_scan P_ ((const unsigned char **, const unsigned char *,
@@ -4234,8 +3997,8 @@ xpm_scan (s, end, beg, len)
       if (isalpha (c) || c == '_' || c == '-' || c == '+')
        {
          *beg = *s - 1;
       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;
              ++*s;
          *len = *s - *beg;
          return XPM_TK_IDENT;
@@ -4275,7 +4038,7 @@ xpm_scan (s, end, beg, len)
   return XPM_TK_EOF;
 }
 
   return XPM_TK_EOF;
 }
 
-/* Functions for color table lookup in XPM data.  A Key is a string
+/* Functions for color table lookup in XPM data.  A key is a string
    specifying the color of each pixel in XPM data.  A value is either
    an integer that specifies a pixel color, Qt that specifies
    transparency, or Qnil for the unspecified color.  If the length of
    specifying the color of each pixel in XPM data.  A value is either
    an integer that specifies a pixel color, Qt that specifies
    transparency, or Qnil for the unspecified color.  If the length of
@@ -4511,7 +4274,7 @@ xpm_load_image (f, img, contents, end)
 
          if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
            {
 
          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))
                color_val = Qt;
              else if (x_defined_color (f, SDATA (XCDR (specified_color)),
                                        &cdef, 0))
@@ -4520,7 +4283,7 @@ xpm_load_image (f, img, contents, end)
        }
       if (NILP (color_val) && max_key > 0)
        {
        }
       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);
            color_val = Qt;
          else if (x_defined_color (f, max_color, &cdef, 0))
            color_val = make_number (cdef.pixel);
@@ -4533,8 +4296,11 @@ xpm_load_image (f, img, contents, end)
 
   if (!x_create_x_image_and_pixmap (f, width, height, 0,
                                    &ximg, &img->pixmap)
 
   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,
       || !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;
     {
       image_error ("Out of memory (%s)", img->spec, Qnil);
       goto error;
@@ -4554,9 +4320,14 @@ xpm_load_image (f, img, contents, end)
          XPutPixel (ximg, x, y,
                     (INTEGERP (color_val) ? XINT (color_val)
                      : FRAME_FOREGROUND_PIXEL (f)));
          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)));
          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 (',');
        }
       if (y + 1 < height)
        expect (',');
@@ -4571,6 +4342,7 @@ xpm_load_image (f, img, contents, end)
 
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
 
   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
   if (have_mask)
     {
       /* Fill in the background_transparent field while we have the
@@ -4586,7 +4358,7 @@ xpm_load_image (f, img, contents, end)
       Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
       img->mask = NO_PIXMAP;
     }
       Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
       img->mask = NO_PIXMAP;
     }
-
+#endif
   return 1;
 
  failure:
   return 1;
 
  failure:
@@ -4652,7 +4424,7 @@ xpm_load (f, img)
   return success_p;
 }
 
   return success_p;
 }
 
-#endif /* MAC_OS */
+#endif /* HAVE_NS && !HAVE_XPM */
 
 
 \f
 
 
 \f
@@ -4913,15 +4685,13 @@ lookup_rgb_color (f, r, g, b)
 {
   unsigned long pixel;
 
 {
   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_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;
 }
 
   return pixel;
 }
 
@@ -5027,11 +4797,11 @@ x_to_xcolors (f, img, rgb_p)
          p->pixel = GET_PIXEL (ximg, x, y);
          if (rgb_p)
            {
          p->pixel = GET_PIXEL (ximg, x, y);
          if (rgb_p)
            {
-#ifdef MAC_OS
+#if defined (HAVE_NS)
              p->red = RED16_FROM_ULONG (p->pixel);
              p->green = GREEN16_FROM_ULONG (p->pixel);
              p->blue = BLUE16_FROM_ULONG (p->pixel);
              p->red = RED16_FROM_ULONG (p->pixel);
              p->green = GREEN16_FROM_ULONG (p->pixel);
              p->blue = BLUE16_FROM_ULONG (p->pixel);
-#endif  /* MAC_OS */
+#endif  /* HAVE_NS */
 #ifdef HAVE_NTGUI
              p->red = 256 * GetRValue (p->pixel);
              p->green = 256 * GetGValue (p->pixel);
 #ifdef HAVE_NTGUI
              p->red = 256 * GetRValue (p->pixel);
              p->green = 256 * GetGValue (p->pixel);
@@ -5108,7 +4878,7 @@ x_from_xcolors (f, img, colors)
      XColor *colors;
 {
   int x, y;
      XColor *colors;
 {
   int x, y;
-  XImagePtr oimg;
+  XImagePtr oimg = NULL;
   Pixmap pixmap;
   XColor *p;
 
   Pixmap pixmap;
   XColor *p;
 
@@ -5157,7 +4927,7 @@ x_detect_edges (f, img, matrix, color_adjust)
   int x, y, i, sum;
 
   for (i = sum = 0; i < 9; ++i)
   int x, y, i, sum;
 
   for (i = sum = 0; i < 9; ++i)
-    sum += abs (matrix[i]);
+    sum += eabs (matrix[i]);
 
 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
 
 
 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
 
@@ -5322,11 +5092,9 @@ x_disable_image (f, img)
       Display *dpy = FRAME_X_DISPLAY (f);
       GC gc;
 
       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)
 #define MaskForeground(f)  WHITE_PIX_DEFAULT (f)
-#endif
 
       gc = XCreateGC (dpy, img->pixmap, 0, NULL);
       XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
 
       gc = XCreateGC (dpy, img->pixmap, 0, NULL);
       XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
@@ -5346,6 +5114,7 @@ x_disable_image (f, img)
                     img->width - 1, 0);
          XFreeGC (dpy, gc);
        }
                     img->width - 1, 0);
          XFreeGC (dpy, gc);
        }
+#endif /* !HAVE_NS */
 #else
       HDC hdc, bmpdc;
       HGDIOBJ prev;
 #else
       HDC hdc, bmpdc;
       HGDIOBJ prev;
@@ -5411,11 +5180,13 @@ x_build_heuristic_mask (f, img, how)
     }
 
 #ifndef HAVE_NTGUI
     }
 
 #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;
   /* 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,
 
   /* Get the X image of IMG->pixmap.  */
   ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, 0, 0,
@@ -5469,16 +5240,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_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));
       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);
   /* 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)
 #else
   for (y = 0; y < img->height; ++y)
     for (x = 0; x < img->width; ++x)
@@ -5760,13 +5536,18 @@ pbm_load (f, img)
   if (type != PBM_MONO)
     {
       max_color_idx = pbm_scan_number (&p, end);
   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", Qnil, Qnil);
+      goto error;
+    }
 
   if (!x_create_x_image_and_pixmap (f, width, height, 0,
                                    &ximg, &img->pixmap))
 
   if (!x_create_x_image_and_pixmap (f, width, height, 0,
                                    &ximg, &img->pixmap))
@@ -5826,10 +5607,13 @@ pbm_load (f, img)
     }
   else
     {
     }
   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);
        {
          x_destroy_x_image (ximg);
          x_clear_image (f, img);
@@ -5843,13 +5627,25 @@ pbm_load (f, img)
          {
            int r, g, b;
 
          {
            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++;
            else if (raw_p)
              {
                r = *p++;
+               if (max_color_idx > 255)
+                 r = r * 256 + *p++;
                g = *p++;
                g = *p++;
+               if (max_color_idx > 255)
+                 g = g * 256 + *p++;
                b = *p++;
                b = *p++;
+               if (max_color_idx > 255)
+                 b = b * 256 + *p++;
              }
            else
              {
              }
            else
              {
@@ -5909,7 +5705,7 @@ pbm_load (f, img)
                                 PNG
  ***********************************************************************/
 
                                 PNG
  ***********************************************************************/
 
-#if defined (HAVE_PNG) || defined (MAC_OS)
+#if defined (HAVE_PNG) || defined (HAVE_NS)
 
 /* Function prototypes.  */
 
 
 /* Function prototypes.  */
 
@@ -5981,7 +5777,7 @@ png_image_p (object)
   return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
 }
 
   return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
 }
 
-#endif /* HAVE_PNG || MAC_OS */
+#endif /* HAVE_PNG || HAVE_NS */
 
 
 #ifdef HAVE_PNG
 
 
 #ifdef HAVE_PNG
@@ -6170,7 +5966,6 @@ png_load (f, img)
   png_byte channels;
   png_uint_32 row_bytes;
   int transparent_p;
   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.  */
   struct png_memory_storage tbr;  /* Data to be read */
 
   /* Find out what file to load.  */
@@ -6312,35 +6107,15 @@ png_load (f, img)
       || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
     fn_png_set_gray_to_rgb (png_ptr);
 
       || 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.  */
   if (!transparent_p)
     {
   /* 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.  */
   if (!transparent_p)
     {
-      png_color_16 *image_bg;
+      /* png_color_16 *image_bg; */
       Lisp_Object specified_bg
        = image_spec_value (img->spec, QCbackground, NULL);
       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.  */
 
       if (STRINGP (specified_bg))
        /* The user specified `:background', use that.  */
@@ -6352,27 +6127,18 @@ png_load (f, img)
              png_color_16 user_bg;
 
              bzero (&user_bg, sizeof user_bg);
              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);
            }
        }
 
              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
        {
       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.  */
+         /* We use the current frame background, ignoring any default
+            background color set by the image.  */
 #ifdef HAVE_X_WINDOWS
          XColor color;
          png_color_16 frame_background;
 #ifdef HAVE_X_WINDOWS
          XColor color;
          png_color_16 frame_background;
@@ -6381,9 +6147,9 @@ png_load (f, img)
          x_query_color (f, &color);
 
          bzero (&frame_background, sizeof frame_background);
          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
 #endif /* HAVE_X_WINDOWS */
 
 #ifdef HAVE_NTGUI
@@ -6399,19 +6165,6 @@ png_load (f, img)
          frame_background.blue = GetBValue (color);
 #endif /* HAVE_NTGUI */
 
          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);
        }
          fn_png_set_background (png_ptr, &frame_background,
                                 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
        }
@@ -6555,20 +6308,16 @@ png_load (f, img)
 
 #else /* HAVE_PNG */
 
 
 #else /* HAVE_PNG */
 
-#ifdef MAC_OS
+#ifdef HAVE_NS
 static int
 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 */
 
 
 #endif /* !HAVE_PNG */
 
@@ -6578,7 +6327,7 @@ png_load (f, img)
                                 JPEG
  ***********************************************************************/
 
                                 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 P_ ((Lisp_Object object));
 static int jpeg_load P_ ((struct frame *f, struct image *img));
@@ -6649,7 +6398,7 @@ jpeg_image_p (object)
   return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
 }
 
   return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
 }
 
-#endif /* HAVE_JPEG || MAC_OS */
+#endif /* HAVE_JPEG || HAVE_NS */
 
 #ifdef HAVE_JPEG
 
 
 #ifdef HAVE_JPEG
 
@@ -6708,7 +6457,7 @@ init_jpeg_functions (Lisp_Object libraries)
 /* Wrapper since we can't directly assign the function pointer
    to another function pointer that was declared more completely easily.  */
 static boolean
 /* Wrapper since we can't directly assign the function pointer
    to another function pointer that was declared more completely easily.  */
 static boolean
-jpeg_resync_to_restart_wrapper(cinfo, desired)
+jpeg_resync_to_restart_wrapper (cinfo, desired)
      j_decompress_ptr cinfo;
      int desired;
 {
      j_decompress_ptr cinfo;
      int desired;
 {
@@ -7133,19 +6882,15 @@ jpeg_load (f, img)
 
 #else /* HAVE_JPEG */
 
 
 #else /* HAVE_JPEG */
 
-#ifdef MAC_OS
+#ifdef HAVE_NS
 static int
 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 */
 
 
 #endif /* !HAVE_JPEG */
 
@@ -7155,7 +6900,7 @@ jpeg_load (f, img)
                                 TIFF
  ***********************************************************************/
 
                                 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 P_ ((Lisp_Object object));
 static int tiff_load P_ ((struct frame *f, struct image *img));
@@ -7178,6 +6923,7 @@ enum tiff_keyword_index
   TIFF_HEURISTIC_MASK,
   TIFF_MASK,
   TIFF_BACKGROUND,
   TIFF_HEURISTIC_MASK,
   TIFF_MASK,
   TIFF_BACKGROUND,
+  TIFF_INDEX,
   TIFF_LAST
 };
 
   TIFF_LAST
 };
 
@@ -7195,7 +6941,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},
   {":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'.  */
 };
 
 /* Structure describing the image type `tiff'.  */
@@ -7225,7 +6972,7 @@ tiff_image_p (object)
   return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
 }
 
   return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
 }
 
-#endif /* HAVE_TIFF || MAC_OS */
+#endif /* HAVE_TIFF || HAVE_NS */
 
 #ifdef HAVE_TIFF
 
 
 #ifdef HAVE_TIFF
 
@@ -7241,6 +6988,7 @@ DEF_IMGLIB_FN (TIFFClientOpen);
 DEF_IMGLIB_FN (TIFFGetField);
 DEF_IMGLIB_FN (TIFFReadRGBAImage);
 DEF_IMGLIB_FN (TIFFClose);
 DEF_IMGLIB_FN (TIFFGetField);
 DEF_IMGLIB_FN (TIFFReadRGBAImage);
 DEF_IMGLIB_FN (TIFFClose);
+DEF_IMGLIB_FN (TIFFSetDirectory);
 
 static int
 init_tiff_functions (Lisp_Object libraries)
 
 static int
 init_tiff_functions (Lisp_Object libraries)
@@ -7257,6 +7005,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, TIFFGetField);
   LOAD_IMGLIB_FN (library, TIFFReadRGBAImage);
   LOAD_IMGLIB_FN (library, TIFFClose);
+  LOAD_IMGLIB_FN (library, TIFFSetDirectory);
   return 1;
 }
 
   return 1;
 }
 
@@ -7269,7 +7018,7 @@ init_tiff_functions (Lisp_Object libraries)
 #define fn_TIFFGetField                        TIFFGetField
 #define fn_TIFFReadRGBAImage           TIFFReadRGBAImage
 #define fn_TIFFClose                   TIFFClose
 #define fn_TIFFGetField                        TIFFGetField
 #define fn_TIFFReadRGBAImage           TIFFReadRGBAImage
 #define fn_TIFFClose                   TIFFClose
-
+#define fn_TIFFSetDirectory            TIFFSetDirectory
 #endif /* HAVE_NTGUI */
 
 
 #endif /* HAVE_NTGUI */
 
 
@@ -7422,12 +7171,13 @@ tiff_load (f, img)
   Lisp_Object file, specified_file;
   Lisp_Object specified_data;
   TIFF *tiff;
   Lisp_Object file, specified_file;
   Lisp_Object specified_data;
   TIFF *tiff;
-  int width, height, x, y;
+  int width, height, x, y, count;
   uint32 *buf;
   uint32 *buf;
-  int rc;
+  int rc, rc2;
   XImagePtr ximg;
   struct gcpro gcpro1;
   tiff_memory_source memsrc;
   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);
 
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
@@ -7483,6 +7233,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);
   /* 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);
@@ -7491,6 +7255,7 @@ tiff_load (f, img)
   if (!check_image_size (f, width, height))
     {
       image_error ("Invalid image size", Qnil, Qnil);
   if (!check_image_size (f, width, height))
     {
       image_error ("Invalid image size", Qnil, Qnil);
+      fn_TIFFClose (tiff);
       UNGCPRO;
       return 0;
     }
       UNGCPRO;
       return 0;
     }
@@ -7498,6 +7263,16 @@ tiff_load (f, img)
   buf = (uint32 *) xmalloc (width * height * sizeof *buf);
 
   rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
   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)
     {
   fn_TIFFClose (tiff);
   if (!rc)
     {
@@ -7558,15 +7333,15 @@ tiff_load (f, img)
 
 #else /* HAVE_TIFF */
 
 
 #else /* HAVE_TIFF */
 
-#ifdef MAC_OS
+#ifdef HAVE_NS
 static int
 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 */
 
 
 #endif /* !HAVE_TIFF */
 
@@ -7576,7 +7351,7 @@ tiff_load (f, img)
                                 GIF
  ***********************************************************************/
 
                                 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 int gif_image_p P_ ((Lisp_Object object));
 static int gif_load P_ ((struct frame *f, struct image *img));
@@ -7618,7 +7393,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},
   {":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}
 };
 
   {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
 };
 
@@ -7661,11 +7436,11 @@ gif_image_p (object)
   return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
 }
 
   return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
 }
 
-#endif /* HAVE_GIF || MAC_OS */
+#endif /* HAVE_GIF */
 
 #ifdef 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
 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
    Undefine before redefining to avoid a preprocessor warning.  */
 #ifdef DrawText
@@ -7676,11 +7451,11 @@ gif_image_p (object)
 #include <gif_lib.h>
 #undef DrawText
 
 #include <gif_lib.h>
 #undef DrawText
 
-#else /* HAVE_NTGUI || MAC_OS */
+#else /* HAVE_NTGUI */
 
 #include <gif_lib.h>
 
 
 #include <gif_lib.h>
 
-#endif /* HAVE_NTGUI || MAC_OS */
+#endif /* HAVE_NTGUI */
 
 
 #ifdef HAVE_NTGUI
 
 
 #ifdef HAVE_NTGUI
@@ -7806,7 +7581,7 @@ gif_load (f, img)
       memsrc.index = 0;
 
       /* Casting return value avoids a GCC warning on W32.  */
       memsrc.index = 0;
 
       /* Casting return value avoids a GCC warning on W32.  */
-      gif = (GifFileType *)fn_DGifOpen(&memsrc, gif_read_from_memory);
+      gif = (GifFileType *) fn_DGifOpen (&memsrc, gif_read_from_memory);
       if (!gif)
        {
          image_error ("Cannot open memory source `%s'", img->spec, Qnil);
       if (!gif)
        {
          image_error ("Cannot open memory source `%s'", img->spec, Qnil);
@@ -7994,214 +7769,430 @@ gif_load (f, img)
 
 #else  /* !HAVE_GIF */
 
 
 #else  /* !HAVE_GIF */
 
-#ifdef MAC_OS
+#ifdef HAVE_NS
 static int
 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;
+  return ns_load_image(f, img,
+                       image_spec_value (img->spec, QCfile, NULL),
+                       image_spec_value (img->spec, QCdata, NULL));
+}
+#endif /* HAVE_NS */
 
 
-  specified_file = image_spec_value (img->spec, QCfile, NULL);
-  specified_data = image_spec_value (img->spec, QCdata, NULL);
+#endif /* HAVE_GIF */
 
 
-  /* Animated gifs use QuickTime Movie Toolbox.  So initialize it here. */
-  EnterMovies ();
 
 
-  if (NILP (specified_data))
+\f
+/***********************************************************************
+                                SVG
+ ***********************************************************************/
+
+#if defined (HAVE_RSVG)
+
+/* 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_load_image P_ ((struct frame *, struct image *,
+                              unsigned char *, unsigned int));
+
+/* The symbol `svg' identifying images of this type. */
+
+Lisp_Object Qsvg;
+
+/* Indices of image specification fields in svg_format, below.  */
+
+enum svg_keyword_index
+{
+  SVG_TYPE,
+  SVG_DATA,
+  SVG_FILE,
+  SVG_ASCENT,
+  SVG_MARGIN,
+  SVG_RELIEF,
+  SVG_ALGORITHM,
+  SVG_HEURISTIC_MASK,
+  SVG_MASK,
+  SVG_BACKGROUND,
+  SVG_LAST
+};
+
+/* Vector of image_keyword structures describing the format
+   of valid user-defined image specifications.  */
+
+static struct image_keyword svg_format[SVG_LAST] =
+{
+  {":type",            IMAGE_SYMBOL_VALUE,                     1},
+  {":data",            IMAGE_STRING_VALUE,                     0},
+  {":file",            IMAGE_STRING_VALUE,                     0},
+  {":ascent",          IMAGE_ASCENT_VALUE,                     0},
+  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":relief",          IMAGE_INTEGER_VALUE,                    0},
+  {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":mask",            IMAGE_DONT_CHECK_VALUE_TYPE,            0},
+  {":background",      IMAGE_STRING_OR_NIL_VALUE,              0}
+};
+
+/* Structure describing the image type `svg'.  Its the same type of
+   structure defined for all image formats, handled by emacs image
+   functions.  See struct image_type in dispextern.h.  */
+
+static struct image_type svg_type =
+{
+  /* An identifier showing that this is an image structure for the SVG format.  */
+  &Qsvg,
+  /* Handle to a function that can be used to identify a SVG file.  */
+  svg_image_p,
+  /* Handle to function used to load a SVG file.  */
+  svg_load,
+  /* Handle to function to free sresources for SVG.  */
+  x_clear_image,
+  /* An internal field to link to the next image type in a list of
+     image types, will be filled in when registering the format.  */
+  NULL
+};
+
+
+/* Return non-zero if OBJECT is a valid SVG image specification.  Do
+   this by calling parse_image_spec and supplying the keywords that
+   identify the SVG format.   */
+
+static int
+svg_image_p (object)
+     Lisp_Object object;
+{
+  struct image_keyword fmt[SVG_LAST];
+  bcopy (svg_format, fmt, sizeof fmt);
+
+  if (!parse_image_spec (object, fmt, SVG_LAST, Qsvg))
+    return 0;
+
+  /* Must specify either the :data or :file keyword.  */
+  return fmt[SVG_FILE].count + fmt[SVG_DATA].count == 1;
+}
+
+#include <librsvg/rsvg.h>
+
+#ifdef HAVE_NTGUI
+
+/* SVG library functions.  */
+DEF_IMGLIB_FN (rsvg_handle_new);
+DEF_IMGLIB_FN (rsvg_handle_get_dimensions);
+DEF_IMGLIB_FN (rsvg_handle_write);
+DEF_IMGLIB_FN (rsvg_handle_close);
+DEF_IMGLIB_FN (rsvg_handle_get_pixbuf);
+DEF_IMGLIB_FN (rsvg_handle_free);
+
+DEF_IMGLIB_FN (gdk_pixbuf_get_width);
+DEF_IMGLIB_FN (gdk_pixbuf_get_height);
+DEF_IMGLIB_FN (gdk_pixbuf_get_pixels);
+DEF_IMGLIB_FN (gdk_pixbuf_get_rowstride);
+DEF_IMGLIB_FN (gdk_pixbuf_get_colorspace);
+DEF_IMGLIB_FN (gdk_pixbuf_get_n_channels);
+DEF_IMGLIB_FN (gdk_pixbuf_get_has_alpha);
+DEF_IMGLIB_FN (gdk_pixbuf_get_bits_per_sample);
+
+DEF_IMGLIB_FN (g_type_init);
+DEF_IMGLIB_FN (g_object_unref);
+DEF_IMGLIB_FN (g_error_free);
+
+Lisp_Object Qgdk_pixbuf, Qglib;
+
+static int
+init_svg_functions (Lisp_Object libraries)
+{
+  HMODULE library, gdklib, glib;
+
+  if (!(glib = w32_delayed_load (libraries, Qglib))
+      || !(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_get_dimensions);
+  LOAD_IMGLIB_FN (library, rsvg_handle_write);
+  LOAD_IMGLIB_FN (library, rsvg_handle_close);
+  LOAD_IMGLIB_FN (library, rsvg_handle_get_pixbuf);
+  LOAD_IMGLIB_FN (library, rsvg_handle_free);
+
+  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_width);
+  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_height);
+  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_pixels);
+  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_rowstride);
+  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_colorspace);
+  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_n_channels);
+  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_has_alpha);
+  LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_bits_per_sample);
+
+  LOAD_IMGLIB_FN (glib, g_type_init);
+  LOAD_IMGLIB_FN (glib, g_object_unref);
+  LOAD_IMGLIB_FN (glib, g_error_free);
+  return 1;
+}
+
+#else
+/* The following aliases for library functions allow dynamic loading
+   to be used on some platforms.  */
+#define fn_rsvg_handle_new             rsvg_handle_new
+#define fn_rsvg_handle_get_dimensions   rsvg_handle_get_dimensions
+#define fn_rsvg_handle_write           rsvg_handle_write
+#define fn_rsvg_handle_close           rsvg_handle_close
+#define fn_rsvg_handle_get_pixbuf      rsvg_handle_get_pixbuf
+#define fn_rsvg_handle_free            rsvg_handle_free
+
+#define fn_gdk_pixbuf_get_width                  gdk_pixbuf_get_width
+#define fn_gdk_pixbuf_get_height         gdk_pixbuf_get_height
+#define fn_gdk_pixbuf_get_pixels         gdk_pixbuf_get_pixels
+#define fn_gdk_pixbuf_get_rowstride      gdk_pixbuf_get_rowstride
+#define fn_gdk_pixbuf_get_colorspace     gdk_pixbuf_get_colorspace
+#define fn_gdk_pixbuf_get_n_channels     gdk_pixbuf_get_n_channels
+#define fn_gdk_pixbuf_get_has_alpha      gdk_pixbuf_get_has_alpha
+#define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
+
+#define fn_g_type_init                    g_type_init
+#define fn_g_object_unref                 g_object_unref
+#define fn_g_error_free                   g_error_free
+#endif /* !HAVE_NTGUI  */
+
+/* Load SVG image IMG for use on frame F.  Value is non-zero if
+   successful. this function will go into the svg_type structure, and
+   the prototype thus needs to be compatible with that structure.  */
+
+static int
+svg_load (f, img)
+     struct frame *f;
+     struct image *img;
+{
+  int success_p = 0;
+  Lisp_Object file_name;
+
+  /* If IMG->spec specifies a file name, create a non-file spec from it.  */
+  file_name = image_spec_value (img->spec, QCfile, NULL);
+  if (STRINGP (file_name))
     {
     {
-      /* Read from a file */
-      FSSpec fss;
-      short refnum;
+      Lisp_Object file;
+      unsigned char *contents;
+      int size;
+      struct gcpro gcpro1;
 
 
-      err = find_image_fsspec (specified_file, &file, &fss);
-      if (err != noErr)
+      file = x_find_image_file (file_name);
+      GCPRO1 (file);
+      if (!STRINGP (file))
        {
        {
-         if (err == fnfErr)
-           image_error ("Cannot find image file `%s'", specified_file, Qnil);
-         else
-           goto open_error;
+         image_error ("Cannot find image file `%s'", file_name, Qnil);
+         UNGCPRO;
+         return 0;
        }
 
        }
 
-      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)
+      /* Read the entire file into memory.  */
+      contents = slurp_file (SDATA (file), &size);
+      if (contents == NULL)
        {
        {
-         image_error ("Error reading `%s'", file, Qnil);
+         image_error ("Error loading SVG image `%s'", img->spec, Qnil);
+         UNGCPRO;
          return 0;
        }
          return 0;
        }
+      /* If the file was slurped into memory properly, parse it.  */
+      success_p = svg_load_image (f, img, contents, size);
+      xfree (contents);
+      UNGCPRO;
     }
     }
+  /* Else its not a file, its a lisp object.  Load the image from a
+     lisp object rather than a file.  */
   else
     {
   else
     {
-      /* Memory source! */
-      Handle dref = NULL;
-      long file_type_atom[3];
+      Lisp_Object data;
 
 
-      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;
-       }
+      data = image_spec_value (img->spec, QCdata, NULL);
+      success_p = svg_load_image (f, img, SDATA (data), SBYTES (data));
+    }
 
 
-      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;
+  return 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;
-    }
+/* svg_load_image is a helper function for svg_load, which does the
+   actual loading given contents and size, apart from frame and image
+   structures, passed from svg_load.
 
 
-  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)
+   Uses librsvg to do most of the image processing.
+
+   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;
+{
+  RsvgHandle *rsvg_handle;
+  RsvgDimensionData dimension_data;
+  GError *error = NULL;
+  GdkPixbuf *pixbuf;
+  int width;
+  int height;
+  const guint8 *pixels;
+  int rowstride;
+  XImagePtr ximg;
+  Lisp_Object specified_bg;
+  XColor background;
+  int x;
+  int y;
+
+  /* g_type_init is a glib function that must be called prior to using
+     gnome type library functions.  */
+  fn_g_type_init ();
+  /* Make a handle to a new rsvg object.  */
+  rsvg_handle = fn_rsvg_handle_new ();
+
+  /* Parse the contents argument and fill in the rsvg_handle.  */
+  fn_rsvg_handle_write (rsvg_handle, contents, size, &error);
+  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;
+
+  fn_rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
+  if (! check_image_size (f, dimension_data.width, dimension_data.height))
+    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);
+  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);
+  rowstride = fn_gdk_pixbuf_get_rowstride (pixbuf);
+
+  /* Validate the svg meta data.  */
+  eassert (fn_gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
+  eassert (fn_gdk_pixbuf_get_n_channels (pixbuf) == 4);
+  eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf));
+  eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
+
+  /* Try to create a x pixmap to hold the svg pixmap.  */
+  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
     {
     {
-      image_error ("Invalid image number `%s' in image `%s'",
-                  image, img->spec);
-      goto error;
+      fn_g_object_unref (pixbuf);
+      return 0;
     }
     }
-  time_scale = GetMediaTimeScale (media);
 
 
+  init_color_table ();
+
+  /* Handle alpha channel by combining the image with a background
+     color.  */
   specified_bg = image_spec_value (img->spec, QCbackground, NULL);
   specified_bg = image_spec_value (img->spec, QCbackground, NULL);
-  if (!STRINGP (specified_bg) ||
-      !mac_defined_color (f, SDATA (specified_bg), &color, 0))
+  if (STRINGP (specified_bg)
+      && x_defined_color (f, SDATA (specified_bg), &background, 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);
+      background.red   >>= 8;
+      background.green >>= 8;
+      background.blue  >>= 8;
     }
     }
-  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;
+  else
+    {
+#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 (HAVE_NTGUI)
+      background.pixel = FRAME_BACKGROUND_PIXEL (f);
+#if 0 /* W32 TODO : Colormap support.  */
+      x_query_color (f, &background);
+#endif
 
 
-  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);
+      /* 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*/
+#error FIXME
+#endif
+    }
 
 
-  /* 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);
-  }
+  /* 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
+     pixel, and the image background color.  */
+  for (y = 0; y < height; ++y)
+    {
+      for (x = 0; x < width; ++x)
+       {
+         unsigned red;
+         unsigned green;
+         unsigned blue;
+         unsigned opacity;
+
+         red     = *pixels++;
+         green   = *pixels++;
+         blue    = *pixels++;
+         opacity = *pixels++;
+
+         red   = ((red * opacity)
+                  + (background.red * ((1 << 8) - opacity)));
+         green = ((green * opacity)
+                  + (background.green * ((1 << 8) - opacity)));
+         blue  = ((blue * opacity)
+                  + (background.blue * ((1 << 8) - opacity)));
+
+         XPutPixel (ximg, x, y, lookup_rgb_color (f, red, green, blue));
+       }
 
 
-  /* 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);
+      pixels += rowstride - 4 * width;
+    }
 
 
-  /* Put the image into the pixmap.  */
+#ifdef COLOR_TABLE_SUPPORT
+  /* Remember colors allocated for this image.  */
+  img->colors = colors_in_color_table (&img->ncolors);
+  free_color_table ();
+#endif /* COLOR_TABLE_SUPPORT */
+
+  fn_g_object_unref (pixbuf);
+
+  img->width  = width;
+  img->height = height;
+
+  /* Maybe fill in the background field while we have ximg handy.
+     Casting avoids a GCC warning.  */
+  IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
+
+  /* Put the image into the pixmap, then free the X image and its
+     buffer.  */
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
+
   return 1;
 
   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);
+ 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);
+  fn_g_error_free (error);
   return 0;
 }
   return 0;
 }
-#endif /* MAC_OS */
 
 
-#endif /* HAVE_GIF */
+#endif /* defined (HAVE_RSVG) */
+
 
 
 \f
 
 
 \f
@@ -8421,7 +8412,7 @@ x_kill_gs_process (pixmap, f)
      Pixmap pixmap;
      struct frame *f;
 {
      Pixmap pixmap;
      struct frame *f;
 {
-  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
+  struct image_cache *c = FRAME_IMAGE_CACHE (f);
   int class, i;
   struct image *img;
 
   int class, i;
   struct image *img;
 
@@ -8571,31 +8562,36 @@ of `image-library-alist', which see).  */)
   if (CONSP (tested))
     return XCDR (tested);
 
   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 (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 (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 (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 (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
 
   if (EQ (type, Qpng))
     return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries);
 #endif
 
+#if defined (HAVE_RSVG)
+  if (EQ (type, Qsvg))
+    return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries);
+#endif
+
 #ifdef HAVE_GHOSTSCRIPT
   if (EQ (type, Qpostscript))
     return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
 #ifdef HAVE_GHOSTSCRIPT
   if (EQ (type, Qpostscript))
     return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
@@ -8620,7 +8616,7 @@ syms_of_image ()
      defining the supported image types.  */
   DEFVAR_LISP ("image-types", &Vimage_types,
     doc: /* List of potentially supported image types.
      defining the supported image types.  */
   DEFVAR_LISP ("image-types", &Vimage_types,
     doc: /* List of potentially supported image types.
-Each element of the list is a symbol for a image type, like 'jpeg or 'png.
+Each element of the list is a symbol for an image type, like 'jpeg or 'png.
 To check whether it is really supported, use `image-type-available-p'.  */);
   Vimage_types = Qnil;
 
 To check whether it is really supported, use `image-type-available-p'.  */);
   Vimage_types = Qnil;
 
@@ -8655,15 +8651,18 @@ non-numeric, there is no explicit limit on the size of images.  */);
 
   Qpbm = intern ("pbm");
   staticpro (&Qpbm);
 
   Qpbm = intern ("pbm");
   staticpro (&Qpbm);
-  ADD_IMAGE_TYPE(Qpbm);
+  ADD_IMAGE_TYPE (Qpbm);
 
   Qxbm = intern ("xbm");
   staticpro (&Qxbm);
 
   Qxbm = intern ("xbm");
   staticpro (&Qxbm);
-  ADD_IMAGE_TYPE(Qxbm);
+  ADD_IMAGE_TYPE (Qxbm);
 
   define_image_type (&xbm_type, 1);
   define_image_type (&pbm_type, 1);
 
 
   define_image_type (&xbm_type, 1);
   define_image_type (&pbm_type, 1);
 
+  Qcount = intern ("count");
+  staticpro (&Qcount);
+
   QCascent = intern (":ascent");
   staticpro (&QCascent);
   QCmargin = intern (":margin");
   QCascent = intern (":ascent");
   staticpro (&QCascent);
   QCmargin = intern (":margin");
@@ -8697,7 +8696,7 @@ non-numeric, there is no explicit limit on the size of images.  */);
   Qpostscript = intern ("postscript");
   staticpro (&Qpostscript);
 #ifdef HAVE_GHOSTSCRIPT
   Qpostscript = intern ("postscript");
   staticpro (&Qpostscript);
 #ifdef HAVE_GHOSTSCRIPT
-  ADD_IMAGE_TYPE(Qpostscript);
+  ADD_IMAGE_TYPE (Qpostscript);
   QCloader = intern (":loader");
   staticpro (&QCloader);
   QCbounding_box = intern (":bounding-box");
   QCloader = intern (":loader");
   staticpro (&QCloader);
   QCbounding_box = intern (":bounding-box");
@@ -8708,36 +8707,48 @@ non-numeric, there is no explicit limit on the size of images.  */);
   staticpro (&QCpt_height);
 #endif /* HAVE_GHOSTSCRIPT */
 
   staticpro (&QCpt_height);
 #endif /* HAVE_GHOSTSCRIPT */
 
-#if defined (HAVE_XPM) || defined (MAC_OS)
+#if defined (HAVE_XPM) || defined (HAVE_NS)
   Qxpm = intern ("xpm");
   staticpro (&Qxpm);
   Qxpm = intern ("xpm");
   staticpro (&Qxpm);
-  ADD_IMAGE_TYPE(Qxpm);
+  ADD_IMAGE_TYPE (Qxpm);
 #endif
 
 #endif
 
-#if defined (HAVE_JPEG) || defined (MAC_OS)
+#if defined (HAVE_JPEG) || defined (HAVE_NS)
   Qjpeg = intern ("jpeg");
   staticpro (&Qjpeg);
   Qjpeg = intern ("jpeg");
   staticpro (&Qjpeg);
-  ADD_IMAGE_TYPE(Qjpeg);
+  ADD_IMAGE_TYPE (Qjpeg);
 #endif
 
 #endif
 
-#if defined (HAVE_TIFF) || defined (MAC_OS)
+#if defined (HAVE_TIFF) || defined (HAVE_NS)
   Qtiff = intern ("tiff");
   staticpro (&Qtiff);
   Qtiff = intern ("tiff");
   staticpro (&Qtiff);
-  ADD_IMAGE_TYPE(Qtiff);
+  ADD_IMAGE_TYPE (Qtiff);
 #endif
 
 #endif
 
-#if defined (HAVE_GIF) || defined (MAC_OS)
+#if defined (HAVE_GIF) || defined (HAVE_NS)
   Qgif = intern ("gif");
   staticpro (&Qgif);
   Qgif = intern ("gif");
   staticpro (&Qgif);
-  ADD_IMAGE_TYPE(Qgif);
+  ADD_IMAGE_TYPE (Qgif);
 #endif
 
 #endif
 
-#if defined (HAVE_PNG) || defined (MAC_OS)
+#if defined (HAVE_PNG) || defined (HAVE_NS)
   Qpng = intern ("png");
   staticpro (&Qpng);
   Qpng = intern ("png");
   staticpro (&Qpng);
-  ADD_IMAGE_TYPE(Qpng);
+  ADD_IMAGE_TYPE (Qpng);
 #endif
 
 #endif
 
+#if defined (HAVE_RSVG)
+  Qsvg = intern ("svg");
+  staticpro (&Qsvg);
+  ADD_IMAGE_TYPE (Qsvg);
+#ifdef HAVE_NTGUI
+  Qgdk_pixbuf = intern ("gdk-pixbuf");
+  staticpro (&Qgdk_pixbuf);
+  Qglib = intern ("glib");
+  staticpro (&Qglib);
+#endif /* HAVE_NTGUI  */
+#endif /* HAVE_RSVG  */
+
   defsubr (&Sinit_image_library);
   defsubr (&Sclear_image_cache);
   defsubr (&Simage_refresh);
   defsubr (&Sinit_image_library);
   defsubr (&Sclear_image_cache);
   defsubr (&Simage_refresh);
@@ -8771,9 +8782,6 @@ meaning don't clear the cache.  */);
 void
 init_image ()
 {
 void
 init_image ()
 {
-#if defined (MAC_OSX) && TARGET_API_MAC_CARBON
-  init_image_func_pointer ();
-#endif
 }
 
 /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
 }
 
 /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9