changeset 94615:a0615a586d39

Merge from emacs--rel--22 Revision: emacs@sv.gnu.org/emacs--devo--0--patch-1142
author Miles Bader <miles@gnu.org>
date Sun, 04 May 2008 19:46:16 +0000
parents b333cf3be3cc (current diff) 0b1b6deb6e05 (diff)
children 7b6b7f6f8539
files ChangeLog configure configure.in src/ChangeLog src/config.in src/image.c src/macgui.h src/macterm.c src/macterm.h src/s/darwin.h
diffstat 10 files changed, 698 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun May 04 19:46:02 2008 +0000
+++ b/ChangeLog	Sun May 04 19:46:16 2008 +0000
@@ -1,3 +1,10 @@
+2008-05-04  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+
+	* configure.in: Check availability of AvailabilityMacros.h
+	if HAVE_CARBON.
+
+	* configure: Regenerate.
+
 2008-05-03  Glenn Morris  <rgm@gnu.org>
 
 	* configure.in (x_libraries): Remove standard 64-bit directories -
--- a/configure	Sun May 04 19:46:02 2008 +0000
+++ b/configure	Sun May 04 19:46:16 2008 +0000
@@ -15020,6 +15020,146 @@
 #define HAVE_CARBON 1
 _ACEOF
 
+
+for ac_header in AvailabilityMacros.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
   ## Specify the install directory
   carbon_appdir=
   if test "${carbon_appdir_x}" != ""; then
--- a/configure.in	Sun May 04 19:46:02 2008 +0000
+++ b/configure.in	Sun May 04 19:46:16 2008 +0000
@@ -2230,6 +2230,7 @@
 ### Use Mac OS X Carbon API to implement GUI.
 if test "${HAVE_CARBON}" = "yes"; then
   AC_DEFINE(HAVE_CARBON, 1, [Define to 1 if you are using the Carbon API on Mac OS X.])
+  AC_CHECK_HEADERS(AvailabilityMacros.h)
   ## Specify the install directory
   carbon_appdir=
   if test "${carbon_appdir_x}" != ""; then
--- a/src/ChangeLog	Sun May 04 19:46:02 2008 +0000
+++ b/src/ChangeLog	Sun May 04 19:46:16 2008 +0000
@@ -1,3 +1,52 @@
+2008-05-04  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+
+	* image.c [USE_MAC_IMAGE_IO] (image_load_image_io):
+	Create bitmap context in native byte order.
+
+	* macterm.c (XDrawLine)
+	(XCreatePixmapFromBitmapData) [USE_MAC_IMAGE_IO]: Create bitmap
+	context in native byte order.
+
+2008-05-04  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+
+	* config.in: Regenerate.
+
+	* image.c (PIX_MASK_DRAW, PIX_MASK_RETAIN) [USE_MAC_IMAGE_IO]:
+	New definitions for Image I/O support.
+	(XGetImage, XPutPixel, XGetPixel, XDestroyImage)
+	(mac_create_cg_image_from_image, x_create_x_image_and_pixmap)
+	[USE_MAC_IMAGE_IO]: Add implementations for Image I/O support.
+	(mac_data_provider_release_data, image_load_image_io)
+	[USE_MAC_IMAGE_IO]: New functions.
+	(CGImageCreateWithPNGDataProviderProcType) [MAC_OSX]: Remove typedef.
+	(MyCGImageCreateWithPNGDataProvider) [MAC_OSX]: Remove variable.
+	(init_image_func_pointer) [MAC_OSX]: Remove function.
+	(image_load_quartz2d) [MAC_OSX]: Check availability of
+	CGImageCreateWithPNGDataProvider at compile time.
+	Use lowercase `false' for boolean constant.
+	(png_load, jpeg_load, tiff_load, gif_load) [USE_MAC_IMAGE_IO]:
+	Use image_load_image_io.
+	(png_load) [!USE_MAC_IMAGE_IO && MAC_OSX]:
+	Don't check MyCGImageCreateWithPNGDataProvider.
+	(init_image) [MAC_OSX && TARGET_API_MAC_CARBON]:
+	Don't call init_image_func_pointer.
+
+	* macgui.h (Pixmap) [USE_MAC_IMAGE_IO]: New definition for Image I/O.
+
+	* macterm.c (mac_cg_color_space_rgb) [USE_CG_DRAWING]:
+	Make variable non-static.
+	(XDrawLine, XCreatePixmap, XCreatePixmapFromBitmapData, XFreePixmap)
+	[USE_MAC_IMAGE_IO]: Add implementations for Image I/O support.
+
+	* macterm.h (ARGB_TO_ULONG, ALPHA_FROM_ULONG): New macros.
+	(RED_FROM_ULONG): Mask off higher bits.
+	(mac_cg_color_space_rgb) [USE_MAC_IMAGE_IO]: New extern.
+
+	* s/darwin.h [HAVE_CARBON && HAVE_AVAILABILITYMACROS_H]:
+	Include AvailabilityMacros.h.
+	(USE_MAC_IMAGE_IO, LIBS_IMAGE) [HAVE_CARBON]: New defines.
+	(LIBS_CARBON) [HAVE_CARBON]: Use LIBS_IMAGE.
+
 2008-05-03  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* chartab.c (Fset_char_table_range): If range is t, really set all
--- a/src/config.in	Sun May 04 19:46:02 2008 +0000
+++ b/src/config.in	Sun May 04 19:46:16 2008 +0000
@@ -90,6 +90,9 @@
 /* Define to 1 if ALSA is available. */
 #undef HAVE_ALSA
 
+/* Define to 1 if you have the <AvailabilityMacros.h> header file. */
+#undef HAVE_AVAILABILITYMACROS_H
+
 /* Define to 1 if you have the `bcmp' function. */
 #undef HAVE_BCMP
 
--- a/src/image.c	Sun May 04 19:46:02 2008 +0000
+++ b/src/image.c	Sun May 04 19:46:16 2008 +0000
@@ -115,10 +115,15 @@
 
 #define RGB_PIXEL_COLOR unsigned long
 
+#if USE_MAC_IMAGE_IO
+#define PIX_MASK_DRAW	255
+#define PIX_MASK_RETAIN	0
+#else
 /* 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)
+#endif
 
 #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
 #define x_defined_color mac_defined_color
@@ -166,6 +171,7 @@
      unsigned long plane_mask; 	/* not used */
      int format;		/* not used */
 {
+#if !USE_MAC_IMAGE_IO
 #if GLYPH_DEBUG
   xassert (x == 0 && y == 0);
   {
@@ -177,6 +183,7 @@
 #endif
 
   LockPixels (GetGWorldPixMap (pixmap));
+#endif
 
   return pixmap;
 }
@@ -187,6 +194,12 @@
      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);
 
@@ -227,6 +240,7 @@
 
       SetGWorld (old_port, old_gdh);
     }
+#endif
 }
 
 static unsigned long
@@ -234,6 +248,12 @@
      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);
 
@@ -271,21 +291,80 @@
       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;
 {
+#if !USE_MAC_IMAGE_IO
   UnlockPixels (GetGWorldPixMap (ximg));
+#endif
 }
 
 #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;
 {
+#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)
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+			  | kCGBitmapByteOrder32Host
+#endif
+			  , provider, NULL, 0, kCGRenderingIntentDefault);
+  CGDataProviderRelease (provider);
+  UNBLOCK_INPUT;
+
+  return result;
+#else
   Pixmap mask;
   CGImageRef result = NULL;
 
@@ -320,6 +399,7 @@
   UNBLOCK_INPUT;
 
   return result;
+#endif
 }
 #endif /* USE_CG_DRAWING */
 #endif /* MAC_OS */
@@ -2301,7 +2381,9 @@
       return 0;
     }
 
+#if !USE_MAC_IMAGE_IO
   LockPixels (GetGWorldPixMap (*pixmap));
+#endif
   *ximg = *pixmap;
   return 1;
 
@@ -2454,6 +2536,256 @@
 			MAC Image Load Functions
  ***********************************************************************/
 
+#if USE_MAC_IMAGE_IO
+static int
+image_load_image_io (f, img, type)
+     struct frame *f;
+     struct image *img;
+     CFStringRef type;
+{
+  CFDictionaryRef options, src_props = NULL, props = NULL;
+  CFStringRef keys[2];
+  CFTypeRef values[2];
+  Lisp_Object specified_file, specified_data;
+  CGImageSourceRef source = NULL;
+  size_t count;
+  CGImageRef image = NULL;
+  int loop_count = -1;
+  double delay_time = -1.0;
+  int width, height;
+  XImagePtr ximg = NULL;
+  CGContextRef context;
+  CGRect rectangle;
+  int has_alpha_p, gif_p;
+
+  gif_p = UTTypeEqual (type, kUTTypeGIF);
+
+  keys[0] = kCGImageSourceTypeIdentifierHint;
+  values[0] = (CFTypeRef) type;
+  keys[1] = kCGImageSourceShouldCache;
+  values[1] = (CFTypeRef) kCFBooleanFalse;
+  options = CFDictionaryCreate (NULL, (const void **) keys,
+				(const void **) values,
+				sizeof (keys) / sizeof (keys[0]),
+				&kCFTypeDictionaryKeyCallBacks,
+				&kCFTypeDictionaryValueCallBacks);
+  if (options == NULL)
+    {
+      image_error ("Error creating options for image `%s'", img->spec, Qnil);
+      return 0;
+    }
+
+  /* Open the file.  */
+  specified_file = image_spec_value (img->spec, QCfile, NULL);
+  specified_data = image_spec_value (img->spec, QCdata, NULL);
+
+  if (NILP (specified_data))
+    {
+      Lisp_Object file;
+      CFStringRef path;
+      CFURLRef url;
+
+      file = x_find_image_file (specified_file);
+      if (!STRINGP (file))
+	{
+	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
+	  return 0;
+	}
+      path = cfstring_create_with_utf8_cstring (SDATA (file));
+      if (path)
+	{
+	  url = CFURLCreateWithFileSystemPath (NULL, path,
+					       kCFURLPOSIXPathStyle, 0);
+	  CFRelease (path);
+	  if (url)
+	    {
+	      source = CGImageSourceCreateWithURL (url, NULL);
+	      CFRelease (url);
+	    }
+	}
+    }
+  else
+    {
+      CFDataRef data = CFDataCreate (NULL, SDATA (specified_data),
+				     SBYTES (specified_data));
+
+      if (data)
+	{
+	  source = CGImageSourceCreateWithData (data, options);
+	  CFRelease (data);
+	}
+    }
+  CFRelease (options);
+
+  if (source)
+    {
+      CFStringRef real_type = CGImageSourceGetType (source);
+
+      if (real_type && UTTypeEqual (type, real_type))
+	src_props = CGImageSourceCopyProperties (source, NULL);
+      if (src_props)
+	{
+	  EMACS_INT ino = 0;
+
+	  count = CGImageSourceGetCount (source);
+	  if (gif_p)
+	    {
+	      Lisp_Object image = image_spec_value (img->spec, QCindex, NULL);
+
+	      if (INTEGERP (image))
+		ino = XFASTINT (image);
+	    }
+	  if (ino >= 0 && ino < count)
+	    {
+	      props = CGImageSourceCopyPropertiesAtIndex (source, ino, NULL);
+	      if (props)
+		image = CGImageSourceCreateImageAtIndex (source, ino, NULL);
+	    }
+	}
+      CFRelease (source);
+    }
+
+  if (image == NULL)
+    {
+      if (src_props)
+	CFRelease (src_props);
+      if (props)
+	CFRelease (props);
+      image_error ("Error reading image `%s'", img->spec, Qnil);
+      return 0;
+    }
+  else
+    {
+      CFBooleanRef boolean;
+
+      if (CFDictionaryGetValueIfPresent (props, kCGImagePropertyHasAlpha,
+					 (const void **) &boolean))
+	has_alpha_p = CFBooleanGetValue (boolean);
+      if (gif_p)
+	{
+	  CFDictionaryRef dict;
+	  CFNumberRef number;
+
+	  dict = CFDictionaryGetValue (src_props,
+				       kCGImagePropertyGIFDictionary);
+	  if (dict
+	      && CFDictionaryGetValueIfPresent (dict,
+						kCGImagePropertyGIFLoopCount,
+						(const void **) &number))
+	    CFNumberGetValue (number, kCFNumberIntType, &loop_count);
+
+	  dict = CFDictionaryGetValue (props, kCGImagePropertyGIFDictionary);
+	  if (dict
+	      && CFDictionaryGetValueIfPresent (dict,
+						kCGImagePropertyGIFDelayTime,
+						(const void **) &number))
+	    CFNumberGetValue (number, kCFNumberDoubleType, &delay_time);
+	}
+      CFRelease (src_props);
+      CFRelease (props);
+    }
+
+  width = img->width = CGImageGetWidth (image);
+  height = img->height = CGImageGetHeight (image);
+
+  if (!check_image_size (f, width, height))
+    {
+      CGImageRelease (image);
+      image_error ("Invalid image size", Qnil, Qnil);
+      return 0;
+    }
+
+  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
+    {
+      CGImageRelease (image);
+      image_error ("Out of memory (%s)", img->spec, Qnil);
+      return 0;
+    }
+  rectangle = CGRectMake (0, 0, width, height);
+
+  context = CGBitmapContextCreate (ximg->data, ximg->width, ximg->height, 8,
+				   ximg->bytes_per_line,
+				   mac_cg_color_space_rgb,
+				   kCGImageAlphaNoneSkipFirst
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+				   | kCGBitmapByteOrder32Host
+#endif
+				   );
+  if (has_alpha_p)
+    {
+      Lisp_Object specified_bg;
+      XColor color;
+
+      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);
+	}
+      CGContextSetRGBFillColor (context, color.red / 65535.0,
+				color.green / 65535.0,
+				color.blue / 65535.0, 1.0);
+      CGContextFillRect (context, rectangle);
+    }
+  CGContextDrawImage (context, rectangle, image);
+  CGContextRelease (context);
+  CGImageRelease (image);
+
+  /* Save GIF image extension data for `image-extension-data'.
+     Format is (count IMAGES
+		0xff "NETSCAPE2.0" 0x00 DATA_SUB_BLOCK_FOR_LOOP_COUNT
+		0xf9 GRAPHIC_CONTROL_EXTENSION_BLOCK).  */
+  if (gif_p)
+    {
+      img->data.lisp_val = Qnil;
+      if (delay_time >= 0)
+	{
+	  Lisp_Object gce = make_uninit_string (4);
+	  int centisec = delay_time * 100.0 + 0.5;
+
+	  /* 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 = Fcons (make_number (0xf9),
+				      Fcons (gce,
+					     img->data.lisp_val));
+	}
+      if (loop_count >= 0)
+	{
+	  Lisp_Object data_sub_block = make_uninit_string (3);
+
+	  SSET (data_sub_block, 0, 0x01);
+	  SSET (data_sub_block, 1, loop_count & 0xff);
+	  SSET (data_sub_block, 2, (loop_count >> 8) & 0xff);
+	  img->data.lisp_val = Fcons (make_number (0),
+				      Fcons (data_sub_block,
+					     img->data.lisp_val));
+	  img->data.lisp_val = Fcons (make_number (0xff),
+				      Fcons (build_string ("NETSCAPE2.0"),
+					     img->data.lisp_val));
+	}
+      if (count > 1)
+	img->data.lisp_val = Fcons (Qcount,
+				    Fcons (make_number (count),
+					   img->data.lisp_val));
+    }
+
+  /* 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;
+}
+#else  /* !USE_MAC_IMAGE_IO */
 static int image_load_quicktime P_ ((struct frame *, struct image *img,
 				     OSType));
 #ifdef MAC_OSX
@@ -2666,30 +2998,6 @@
 
 
 #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;
@@ -2737,11 +3045,13 @@
     source = CGDataProviderCreateWithData (NULL, SDATA (specified_data),
 					   SBYTES (specified_data), NULL);
 
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
   if (png_p)
-    image = (*MyCGImageCreateWithPNGDataProvider) (source, NULL, FALSE,
-						   kCGRenderingIntentDefault);
+    image = CGImageCreateWithPNGDataProvider (source, NULL, false,
+					      kCGRenderingIntentDefault);
   else
-    image = CGImageCreateWithJPEGDataProvider (source, NULL, FALSE,
+#endif
+    image = CGImageCreateWithJPEGDataProvider (source, NULL, false,
 					       kCGRenderingIntentDefault);
 
   CGDataProviderRelease (source);
@@ -2805,6 +3115,7 @@
   return 1;
 }
 #endif
+#endif	/* !USE_MAC_IMAGE_IO */
 
 #endif  /* MAC_OS */
 
@@ -4275,8 +4586,8 @@
       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;
@@ -6622,12 +6933,13 @@
      struct frame *f;
      struct image *img;
 {
-#ifdef MAC_OSX
-  if (MyCGImageCreateWithPNGDataProvider)
-    return image_load_quartz2d (f, img, 1);
-  else
+#if USE_MAC_IMAGE_IO
+  return image_load_image_io (f, img, kUTTypePNG);
+#elif MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+  return image_load_quartz2d (f, img, 1);
+#else
+  return image_load_quicktime (f, img, kQTFileTypePNG);
 #endif
-    return image_load_quicktime (f, img, kQTFileTypePNG);
 }
 #endif  /* MAC_OS */
 
@@ -7200,7 +7512,9 @@
      struct frame *f;
      struct image *img;
 {
-#ifdef MAC_OSX
+#if USE_MAC_IMAGE_IO
+  return image_load_image_io (f, img, kUTTypeJPEG);
+#elif defined (MAC_OSX)
   return image_load_quartz2d (f, img, 0);
 #else
   return image_load_quicktime (f, img, kQTFileTypeJPEG);
@@ -7625,7 +7939,11 @@
      struct frame *f;
      struct image *img;
 {
+#if USE_MAC_IMAGE_IO
+  return image_load_image_io (f, img, kUTTypeTIFF);
+#else
   return image_load_quicktime (f, img, kQTFileTypeTIFF);
+#endif
 }
 #endif /* MAC_OS */
 
@@ -8061,6 +8379,9 @@
      struct frame *f;
      struct image *img;
 {
+#if USE_MAC_IMAGE_IO
+  return image_load_image_io (f, img, kUTTypeGIF);
+#else  /* !USE_MAC_IMAGE_IO */
   Lisp_Object specified_file, file;
   Lisp_Object specified_data;
   OSErr err;
@@ -8189,8 +8510,8 @@
   time_scale = GetMediaTimeScale (media);
 
   specified_bg = image_spec_value (img->spec, QCbackground, NULL);
-  if (!STRINGP (specified_bg) ||
-      !mac_defined_color (f, SDATA (specified_bg), &color, 0))
+  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);
@@ -8259,6 +8580,7 @@
   if (dh)
     DisposeHandle (dh);
   return 0;
+#endif	/* !USE_MAC_IMAGE_IO */
 }
 #endif /* MAC_OS */
 
@@ -9264,9 +9586,6 @@
 void
 init_image ()
 {
-#if defined (MAC_OSX) && TARGET_API_MAC_CARBON
-  init_image_func_pointer ();
-#endif
 }
 
 /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
--- a/src/macgui.h	Sun May 04 19:46:02 2008 +0000
+++ b/src/macgui.h	Sun May 04 19:46:16 2008 +0000
@@ -154,7 +154,18 @@
 #define mac_get_global_mouse	GetGlobalMouse
 #define mac_is_window_toolbar_visible	IsWindowToolbarVisible
 #define mac_rect_make(f, x, y, w, h)	CGRectMake (x, y, w, h)
+
+#if USE_MAC_IMAGE_IO
+typedef struct _XImage
+{
+  int width, height;		/* size of image */
+  char *data;			/* pointer to image data */
+  int bytes_per_line;		/* accelarator to next line */
+  int bits_per_pixel;		/* bits per pixel (ZPixmap) */
+} *Pixmap;
+#else
 typedef GWorldPtr Pixmap;
+#endif
 
 #define Cursor ThemeCursor
 #define No_Cursor (-1)
--- a/src/macterm.c	Sun May 04 19:46:02 2008 +0000
+++ b/src/macterm.c	Sun May 04 19:46:16 2008 +0000
@@ -335,7 +335,7 @@
 static int max_fringe_bmp = 0;
 static CGImageRef *fringe_bmp = 0;
 
-static CGColorSpaceRef mac_cg_color_space_rgb;
+CGColorSpaceRef mac_cg_color_space_rgb;
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
 static CGColorRef mac_cg_color_black;
 #endif
@@ -508,6 +508,48 @@
      GC gc;
      int x1, y1, x2, y2;
 {
+#if USE_MAC_IMAGE_IO
+  CGContextRef context;
+  XImagePtr ximg = p;
+  CGColorSpaceRef color_space;
+  CGImageAlphaInfo alpha_info;
+  CGFloat gx1 = x1, gy1 = y1, gx2 = x2, gy2 = y2;
+
+  if (y1 != y2)
+    gx1 += 0.5f, gx2 += 0.5f;
+  if (x1 != x2)
+    gy1 += 0.5f, gy2 += 0.5f;
+
+  if (ximg->bits_per_pixel == 32)
+    {
+      color_space = mac_cg_color_space_rgb;
+      alpha_info = (kCGImageAlphaNoneSkipFirst
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+		    | kCGBitmapByteOrder32Host
+#endif
+		    );
+    }
+  else
+    {
+      color_space = NULL;
+      alpha_info = kCGImageAlphaOnly;
+    }
+  if (color_space == NULL)
+    return;
+  context = CGBitmapContextCreate (ximg->data, ximg->width,
+				   ximg->height, 8,
+				   ximg->bytes_per_line, color_space,
+				   alpha_info);
+  if (ximg->bits_per_pixel == 32)
+    CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
+  else
+    CGContextSetGrayStrokeColor (context, gc->xgcv.foreground / 255.0f, 1.0);
+  CGContextMoveToPoint (context, gx1, gy1);
+  CGContextAddLineToPoint (context, gx2, gy2);
+  CGContextClosePath (context);
+  CGContextStrokePath (context);
+  CGContextRelease (context);
+#else
   CGrafPtr old_port;
   GDHandle old_gdh;
 
@@ -537,6 +579,7 @@
   UnlockPixels (GetGWorldPixMap (p));
 
   SetGWorld (old_port, old_gdh);
+#endif
 }
 
 
@@ -748,6 +791,17 @@
      unsigned int width, height;
      unsigned int depth;
 {
+#if USE_MAC_IMAGE_IO
+  XImagePtr ximg;
+
+  ximg = xmalloc (sizeof (*ximg));
+  ximg->width = width;
+  ximg->height = height;
+  ximg->bits_per_pixel = depth == 1 ? 8 : 32;
+  ximg->bytes_per_line = width * (ximg->bits_per_pixel / 8);
+  ximg->data = xmalloc (ximg->bytes_per_line * height);
+  return ximg;
+#else
   Pixmap pixmap;
   Rect r;
   QDErr err;
@@ -768,6 +822,7 @@
   if (err != noErr)
     return NULL;
   return pixmap;
+#endif
 }
 
 
@@ -782,6 +837,38 @@
 {
   Pixmap pixmap;
   BitMap bitmap;
+#if USE_MAC_IMAGE_IO
+  CGDataProviderRef provider;
+  CGImageRef image_mask;
+  CGContextRef context;
+
+  pixmap = XCreatePixmap (display, w, width, height, depth);
+  if (pixmap == NULL)
+    return NULL;
+
+  mac_create_bitmap_from_bitmap_data (&bitmap, data, width, height);
+  provider = CGDataProviderCreateWithData (NULL, bitmap.baseAddr,
+					   bitmap.rowBytes * height, NULL);
+  image_mask = CGImageMaskCreate (width, height, 1, 1, bitmap.rowBytes,
+				  provider, NULL, 0);
+  CGDataProviderRelease (provider);
+
+  context = CGBitmapContextCreate (pixmap->data, width, height, 8,
+				   pixmap->bytes_per_line,
+				   mac_cg_color_space_rgb,
+				   kCGImageAlphaNoneSkipFirst
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+				   | kCGBitmapByteOrder32Host
+#endif
+				   );
+
+  CG_SET_FILL_COLOR (context, fg);
+  CGContextFillRect (context, CGRectMake (0, 0, width, height));
+  CG_SET_FILL_COLOR (context, bg);
+  CGContextDrawImage (context, CGRectMake (0, 0, width, height), image_mask);
+  CGContextRelease (context);
+  CGImageRelease (image_mask);
+#else
   CGrafPtr old_port;
   GDHandle old_gdh;
   static GC gc = NULL;
@@ -810,6 +897,7 @@
 #endif /* not TARGET_API_MAC_CARBON */
   UnlockPixels (GetGWorldPixMap (pixmap));
   SetGWorld (old_port, old_gdh);
+#endif
   mac_free_bitmap (&bitmap);
 
   return pixmap;
@@ -821,7 +909,16 @@
      Display *display;
      Pixmap pixmap;
 {
+#if USE_MAC_IMAGE_IO
+  if (pixmap)
+    {
+      if (pixmap->data)
+	xfree (pixmap->data);
+      xfree (pixmap);
+    }
+#else
   DisposeGWorld (pixmap);
+#endif
 }
 
 
--- a/src/macterm.h	Sun May 04 19:46:02 2008 +0000
+++ b/src/macterm.h	Sun May 04 19:46:16 2008 +0000
@@ -25,8 +25,10 @@
 #include "frame.h"
 
 #define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
+#define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
 
-#define RED_FROM_ULONG(color) ((color) >> 16)
+#define ALPHA_FROM_ULONG(color) ((color) >> 24)
+#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
 #define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
 #define BLUE_FROM_ULONG(color) ((color) & 0xff)
 
@@ -649,6 +651,10 @@
 #define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
 #define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
 
+#if USE_MAC_IMAGE_IO
+extern CGColorSpaceRef mac_cg_color_space_rgb;
+#endif
+
 /* Defined in macselect.c */
 
 extern void x_clear_frame_selections P_ ((struct frame *));
--- a/src/s/darwin.h	Sun May 04 19:46:02 2008 +0000
+++ b/src/s/darwin.h	Sun May 04 19:46:16 2008 +0000
@@ -265,9 +265,31 @@
 /* Indicate that we are compiling for Mac OS X.  */
 #define C_SWITCH_SYSTEM -fpascal-strings -DMAC_OSX
 
+#ifdef HAVE_CARBON
+
+#ifdef HAVE_AVAILABILITYMACROS_H
+#include <AvailabilityMacros.h>
+#endif
+
+/* Whether to use the Image I/O framework for reading images.  */
+#ifndef USE_MAC_IMAGE_IO
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1040 || MAC_OS_X_VERSION_MIN_REQUIRED < 1020)
+#define USE_MAC_IMAGE_IO 1
+#endif
+#endif
+
+/* If the Image I/O framework is not used, fall back on QuickTime.  */
+#if USE_MAC_IMAGE_IO
+#define LIBS_IMAGE
+#else
+#define LIBS_IMAGE -framework QuickTime
+#endif
+
+#endif	/* HAVE_CARBON */
+
 /* Link in the Carbon lib. */
 #ifdef HAVE_CARBON
-#define LIBS_CARBON -framework Carbon -framework QuickTime
+#define LIBS_CARBON -framework Carbon LIBS_IMAGE
 #else
 #define LIBS_CARBON
 #endif