diff -Nru gtk+-2.10.7-old/gdk-pixbuf/io-icns.c gtk+-2.10.7-new/gdk-pixbuf/io-icns.c
--- gtk+-2.10.7-old/gdk-pixbuf/io-icns.c	1970-01-01 01:00:00.000000000 +0100
+++ gtk+-2.10.7-new/gdk-pixbuf/io-icns.c	2007-01-14 20:47:37.000000000 +0100
@@ -0,0 +1,399 @@
+/* Mac OS X .icns icons loader
+ *
+ * Copyright (c) 2007 Lyonel Vincent <lyonel@ezix.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixbuf-io.h>
+
+G_MODULE_EXPORT void fill_vtable (GdkPixbufModule * module);
+G_MODULE_EXPORT void fill_info (GdkPixbufFormat * info);
+
+#define IN /**/
+#define OUT /**/
+#define INOUT /**/
+static const char rcsid[] = "$Id: icns.c 1715 2007-01-12 22:56:20Z lyonel $";
+
+struct IcnsBlockHeader
+{
+  char id[4];
+  guint32 size;			/* caution: bigendian */
+};
+typedef struct IcnsBlockHeader IcnsBlockHeader;
+
+/*
+ * load raw icon data from 'icns' resource
+ *
+ * returns TRUE when successful
+ */
+static gboolean
+load_resources (unsigned size, IN gpointer data, size_t datalen,
+		OUT gpointer * picture, OUT size_t * plen,
+		OUT gpointer * mask, OUT size_t * mlen)
+{
+  IcnsBlockHeader *header = NULL;
+  const char *bytes = NULL;
+  const char *current = NULL;
+  guint32 blocklen = 0;
+  guint32 icnslen = 0;
+
+  if (datalen < 2 * sizeof (guint32))
+    return FALSE;
+  if (!data)
+    return FALSE;
+
+  *picture = *mask = NULL;
+  *plen = *mlen = 0;
+
+  bytes = data;
+  header = (IcnsBlockHeader *) data;
+  if (memcmp (header->id, "icns", 4) != 0)
+    return FALSE;
+
+  icnslen = GUINT32_FROM_BE (header->size);
+  if ((icnslen > datalen) || (icnslen < 2 * sizeof (guint32)))
+    return FALSE;
+
+  current = bytes + sizeof (IcnsBlockHeader);
+  while (current - bytes < icnslen)
+    {
+      header = (IcnsBlockHeader *) current;
+      blocklen = GUINT32_FROM_BE (header->size);
+
+      switch (size)
+	{
+	case 128:
+	  if (memcmp (header->id, "it32", 4) == 0)	/* 128x128 icon */
+	    {
+	      *picture = (gpointer) (current + sizeof (IcnsBlockHeader));
+	      *plen = blocklen - sizeof (IcnsBlockHeader);
+	      if (memcmp (*picture, "\0\0\0\0", 4) == 0)
+		{
+		  *picture += 4;
+		  *plen -= 4;
+		}
+	    }
+	  if (memcmp (header->id, "t8mk", 4) == 0)	/* 128x128 mask */
+	    {
+	      *mask = (gpointer) (current + sizeof (IcnsBlockHeader));
+	      *mlen = blocklen - sizeof (IcnsBlockHeader);
+	    }
+	  break;
+	case 48:
+	  if (memcmp (header->id, "ih32", 4) == 0)	/* 48x48 icon */
+	    {
+	      *picture = (gpointer) (current + sizeof (IcnsBlockHeader));
+	      *plen = blocklen - sizeof (IcnsBlockHeader);
+	    }
+	  if (memcmp (header->id, "h8mk", 4) == 0)	/* 48x48 mask */
+	    {
+	      *mask = (gpointer) (current + sizeof (IcnsBlockHeader));
+	      *mlen = blocklen - sizeof (IcnsBlockHeader);
+	    }
+	  break;
+	case 32:
+	  if (memcmp (header->id, "il32", 4) == 0)	/* 32x32 icon */
+	    {
+	      *picture = (gpointer) (current + sizeof (IcnsBlockHeader));
+	      *plen = blocklen - sizeof (IcnsBlockHeader);
+	    }
+	  if (memcmp (header->id, "l8mk", 4) == 0)	/* 32x32 mask */
+	    {
+	      *mask = (gpointer) (current + sizeof (IcnsBlockHeader));
+	      *mlen = blocklen - sizeof (IcnsBlockHeader);
+	    }
+	  break;
+	case 16:
+	  if (memcmp (header->id, "is32", 4) == 0)	/* 16x16 icon */
+	    {
+	      *picture = (gpointer) (current + sizeof (IcnsBlockHeader));
+	      *plen = blocklen - sizeof (IcnsBlockHeader);
+	    }
+	  if (memcmp (header->id, "s8mk", 4) == 0)	/* 16x16 mask */
+	    {
+	      *mask = (gpointer) (current + sizeof (IcnsBlockHeader));
+	      *mlen = blocklen - sizeof (IcnsBlockHeader);
+	    }
+	  break;
+	default:
+	  return FALSE;
+	}
+
+      current += blocklen;
+    }
+
+  return (*picture) && (*mask);
+}
+
+/*
+ * uncompress RLE-encoded bytes into RGBA scratch zone:
+ * if firstbyte >= 0x80, it indicates the number of identical bytes + 125
+ * 	(repeated value is stored next: 1 byte)
+ * otherwise, it indicates the number of non-repeating bytes - 1
+ *	(non-repeating values are stored next: n bytes)
+ */
+static void
+uncompress (unsigned size, INOUT guchar ** source, OUT guchar * target)
+{
+  guchar *wipeit = target;
+  guchar *data = *source;
+  size_t remaining = size * size;
+  size_t i = 0;
+
+  while (remaining > 0)
+    {
+      guint8 count = 0;
+
+      if (data[0] & 0x80)	/* repeating byte */
+	{
+	  count = data[0] - 125;
+
+	  if (count > remaining)
+	    goto _error;
+
+	  for (i = 0; i < count; i++)
+	    {
+	      *target = data[1];
+	      target += 4;
+	    }
+
+	  data += 2;
+	}
+      else			/* non-repeating bytes */
+	{
+	  count = data[0] + 1;
+
+	  if (count > remaining)
+	    goto _error;
+
+	  for (i = 0; i < count; i++)
+	    {
+	      *target = data[i + 1];
+	      target += 4;
+	    }
+	  data += count + 1;
+	}
+
+      remaining -= count;
+    }
+
+  *source = data;
+  return;
+
+_error:			/* wipe the channel before bailing out */
+  for (i = 0; i < size * size; i++)
+    wipeit[i * 4] = 0;
+}
+
+static void
+pixbuf_destroy_function (IN guchar * pixels, gpointer data)
+{
+  if (pixels)
+    free (pixels);
+}
+
+static GdkPixbuf *
+load_icon (unsigned size, IN gpointer data, size_t datalen)
+{
+  guchar *icon = NULL;
+  guchar *mask = NULL;
+  size_t isize = 0, msize = 0, i;
+  guchar *image = NULL;
+
+  if (!load_resources
+      (size, data, datalen, (gpointer *) & icon, &isize, (gpointer *) & mask,
+       &msize))
+    return NULL;
+
+  if (msize != size * size)	/* wrong mask size */
+    return NULL;
+
+  image = (guchar *) g_malloc0 (size * size * 4);	/* 4 bytes/pixel = RGBA */
+
+  if (!image)
+    return NULL;
+
+  if (isize == size * size * 4)	/* icon data is uncompressed */
+    for (i = 0; i < size * size; i++)	/* 4 bytes/pixel = ARGB (A: ignored) */
+      {
+	image[i * 4] = icon[4 * i + 1];	/* R */
+	image[i * 4 + 1] = icon[4 * i + 2];	/* G */
+	image[i * 4 + 2] = icon[4 * i + 3];	/* B */
+      }
+  else
+    {
+      guchar *data = icon;
+
+      uncompress (size, &data, image);	/* R */
+      uncompress (size, &data, image + 1);	/* G */
+      uncompress (size, &data, image + 2);	/* B */
+    }
+
+  for (i = 0; i < size * size; i++)	/* copy mask to alpha channel */
+    image[i * 4 + 3] = mask[i];
+
+  return gdk_pixbuf_new_from_data ((guchar *) image, GDK_COLORSPACE_RGB,	/* RGB image */
+				   TRUE,	/* with alpha channel */
+				   8,	/* 8 bits per sample */
+				   size,	/* width */
+				   size,	/* height */
+				   size * 4,	/* no gap between rows */
+				   pixbuf_destroy_function,	/* free() function */
+				   NULL);	/* param to free() function */
+}
+
+struct loadercontext
+{
+  GdkPixbufModuleUpdatedFunc updated_func;
+  GdkPixbufModulePreparedFunc prepared_func;
+  GdkPixbufModuleSizeFunc size_func;
+  gpointer user_data;
+
+  GByteArray *data;
+};
+typedef struct loadercontext loadercontext;
+
+static gpointer
+icns_image_begin_load (GdkPixbufModuleSizeFunc size_func,
+		       GdkPixbufModulePreparedFunc prepared_func,
+		       GdkPixbufModuleUpdatedFunc updated_func,
+		       gpointer user_data, GError ** error)
+{
+  loadercontext *context = g_new0 (loadercontext, 1);
+
+  if (error != NULL)
+    *error = NULL;
+
+  context->prepared_func = prepared_func;
+  context->updated_func = updated_func;
+  context->size_func = size_func;
+  context->user_data = user_data;
+  context->data = g_byte_array_new ();
+
+  return (gpointer) context;
+}
+
+static gboolean
+icns_image_load_increment (gpointer data,
+			   const guchar * buf, guint size, GError ** error)
+{
+  loadercontext *context = (loadercontext *) data;
+
+  if (error != NULL)
+    *error = NULL;
+
+  g_byte_array_append (context->data, buf, size);
+
+  return TRUE;
+}
+
+static gboolean
+icns_image_stop_load (gpointer data, GError ** error)
+{
+  loadercontext *context = (loadercontext *) data;
+  gboolean result = FALSE;
+  GdkPixbuf *pixbuf = NULL;
+  gint width, height;
+
+  if (error != NULL)
+    *error = NULL;
+
+  width = height = 128;		/* load OS X icon by default */
+
+  /* ask which size we should retrieve */
+  if (context->size_func != NULL)
+    (*context->size_func) (&width, &height, context->user_data);
+
+  if ((width == 0) || (height == 0))	/* we were told to stop loading */
+    return FALSE;
+
+  /* first try to load an icon with the dimensions we were given */
+  if (!(pixbuf = load_icon (height, context->data->data, context->data->len)))
+    if (!
+	(pixbuf = load_icon (width, context->data->data, context->data->len)))
+      /* if that doesn't work, try to load other sizes in decreasing order */
+      if (!(pixbuf = load_icon (128, context->data->data, context->data->len)))	/* standard OS X */
+	if (!(pixbuf = load_icon (48, context->data->data, context->data->len)))	/* not very common */
+	  if (!(pixbuf = load_icon (32, context->data->data, context->data->len)))	/* standard Mac OS Classic (8 & 9) */
+	    if (!(pixbuf = load_icon (16, context->data->data, context->data->len)))	/* used in Mac OS Classic and dialog boxes */
+	      {
+		g_set_error (error, GDK_PIXBUF_ERROR,
+			     GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+			     "Couldn't decode icons");
+		goto _error;
+	      }
+
+  /* notify the caller that we've loaded an icon */
+  if (context->prepared_func != NULL)
+    (*context->prepared_func) (pixbuf, NULL, context->user_data);
+
+  /* notify the caller that the icon has been "updated" */
+  if (context->updated_func != NULL)
+    (*context->updated_func) (pixbuf, 0, 0,
+			      gdk_pixbuf_get_width (pixbuf),
+			      gdk_pixbuf_get_height (pixbuf),
+			      context->user_data);
+
+  result = TRUE;
+
+_error:
+
+  g_byte_array_free (context->data, TRUE);
+  g_free (context);
+
+  return result;
+}
+
+void
+fill_vtable (GdkPixbufModule * module)
+{
+  module->begin_load = icns_image_begin_load;
+  module->stop_load = icns_image_stop_load;
+  module->load_increment = icns_image_load_increment;
+}
+
+void
+fill_info (GdkPixbufFormat * info)
+{
+  static GdkPixbufModulePattern signature[] = {
+    {"icns", NULL, 100},	/* file begins with 'icns' */
+    {NULL, NULL, 0}
+  };
+  static gchar *mime_types[] = {
+    "image/x-icns",
+    NULL
+  };
+  static gchar *extensions[] = {
+    "icns",
+    NULL
+  };
+
+  info->name = "icns";
+  info->signature = signature;
+  info->description = "OS X icon";
+  info->mime_types = mime_types;
+  info->extensions = extensions;
+  info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
+  info->license = "GPL";
+  info->disabled = FALSE;
+}
diff -Nru gtk+-2.10.7-old/gdk-pixbuf/Makefile.am gtk+-2.10.7-new/gdk-pixbuf/Makefile.am
--- gtk+-2.10.7-old/gdk-pixbuf/Makefile.am	2007-01-05 19:35:24.000000000 +0100
+++ gtk+-2.10.7-new/gdk-pixbuf/Makefile.am	2007-01-14 20:47:54.000000000 +0100
@@ -165,6 +165,14 @@
 libpixbufloader_tga_la_LIBADD = $(module_libs)
 
 #
+# The .icns loader
+#
+libpixbufloader_static_icns_la_SOURCES = io-icns.c
+libpixbufloader_icns_la_SOURCES = io-icns.c
+libpixbufloader_icns_la_LDFLAGS = -avoid-version -module $(no_undefined)
+libpixbufloader_icns_la_LIBADD = $(module_libs)
+
+#
 # The PCX loader
 #
 libpixbufloader_static_pcx_la_SOURCES = io-pcx.c
@@ -217,6 +225,9 @@
 TGA_LIB = libpixbufloader-tga.la
 STATIC_TGA_LIB = libpixbufloader-static-tga.la
 
+ICNS_LIB = libpixbufloader-icns.la
+STATIC_ICNS_LIB = libpixbufloader-static-icns.la
+
 PCX_LIB = libpixbufloader-pcx.la
 STATIC_PCX_LIB = libpixbufloader-static-pcx.la
 
@@ -236,6 +247,7 @@
 	$(WBMP_LIB)	\
 	$(XBM_LIB)	\
 	$(TGA_LIB)	\
+	$(ICNS_LIB)	\
 	$(PCX_LIB)
 
 
@@ -258,6 +270,7 @@
 	$(STATIC_WBMP_LIB)	\
 	$(STATIC_XBM_LIB)	\
 	$(STATIC_TGA_LIB)	\
+	$(STATIC_ICNS_LIB)	\
 	$(STATIC_PCX_LIB)
 
 builtin_objs = @INCLUDED_LOADER_OBJ@
