diff -uN gdk-pixbuf.orig/Makefile.am gdk-pixbuf/Makefile.am
--- gdk-pixbuf.orig/Makefile.am	Fri Sep  6 23:14:15 2002
+++ gdk-pixbuf/Makefile.am	Mon Sep  9 22:53:39 2002
@@ -73,24 +73,24 @@
 #
 # The GIF loader
 #
-libpixbufloader_static_gif_la_SOURCES = io-gif.c io-gif-animation.c io-gif-animation.h
-libpixbufloader_gif_la_SOURCES = io-gif.c io-gif-animation.c io-gif-animation.h
+libpixbufloader_static_gif_la_SOURCES = io-gif.c io-gif-animation.c io-gif-animation.h io-gif-collection.c io-gif-collection.h
+libpixbufloader_gif_la_SOURCES = io-gif.c io-gif-animation.c io-gif-animation.h io-gif-collection.c io-gif-collection.h
 libpixbufloader_gif_la_LDFLAGS = -avoid-version -module $(no_undefined)
 libpixbufloader_gif_la_LIBADD = $(module_libs)
 
 #
 # The ICO loader
 #
-libpixbufloader_static_ico_la_SOURCES = io-ico.c
-libpixbufloader_ico_la_SOURCES = io-ico.c
+libpixbufloader_static_ico_la_SOURCES = io-ico.c io-ico-collection.c io-ico-collection.h
+libpixbufloader_ico_la_SOURCES = io-ico.c io-ico-collection.c io-ico-collection.h
 libpixbufloader_ico_la_LDFLAGS = -avoid-version -module $(no_undefined)
 libpixbufloader_ico_la_LIBADD = $(module_libs)
 
 #
 # The ANI loader
 #
-libpixbufloader_static_ani_la_SOURCES = io-ani.c io-ani-animation.c io-ani-animation.h
-libpixbufloader_ani_la_SOURCES = io-ani.c io-ani-animation.c io-ani-animation.h
+libpixbufloader_static_ani_la_SOURCES = io-ani.c io-ani-animation.c io-ani-animation.h io-ani-collection.c io-ani-collection.h	
+libpixbufloader_ani_la_SOURCES = io-ani.c io-ani-animation.c io-ani-animation.h io-ani-collection.c io-ani-collection.h
 libpixbufloader_ani_la_LDFLAGS = -avoid-version -module $(no_undefined)
 libpixbufloader_ani_la_LIBADD = $(module_libs)
 
@@ -276,6 +276,7 @@
 	gdk-pixbuf-i18n.h	\
 	gdk-pixbuf.c		\
 	gdk-pixbuf-animation.c	\
+	gdk-pixbuf-collection.c	\
 	gdk-pixbuf-data.c	\
 	gdk-pixbuf-io.c		\
 	gdk-pixbuf-loader.c	\
diff -uN gdk-pixbuf.orig/gdk-pixbuf-animation.c gdk-pixbuf/gdk-pixbuf-animation.c
--- gdk-pixbuf.orig/gdk-pixbuf-animation.c	Thu Aug 22 23:32:06 2002
+++ gdk-pixbuf/gdk-pixbuf-animation.c	Sun Sep  8 21:30:06 2002
@@ -676,6 +676,14 @@
         return GDK_PIXBUF_ANIMATION_ITER (iter);
 }
 
+GdkPixbufCollection*
+_gdk_pixbuf_non_anim_get_collection (GdkPixbufAnimation *anim)
+{
+        GdkPixbufNonAnim *non_anim = GDK_PIXBUF_NON_ANIM (anim);
+
+        return gdk_pixbuf_non_collection_new (non_anim->pixbuf);
+}
+
 
 
 static void gdk_pixbuf_non_anim_iter_class_init (GdkPixbufNonAnimIterClass *klass);
diff -uN gdk-pixbuf.orig/gdk-pixbuf-collection.c gdk-pixbuf/gdk-pixbuf-collection.c
--- gdk-pixbuf.orig/gdk-pixbuf-collection.c	Thu Jan  1 01:00:00 1970
+++ gdk-pixbuf/gdk-pixbuf-collection.c	Tue Sep 10 22:29:17 2002
@@ -0,0 +1,504 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GdkPixbuf library - Simple collection support
+ *
+ * Copyright (C) 2002 The Free Software Foundation
+ *
+ * Authors:  Anders Carlsson <andersca@gnu.org>
+ *           Matthias Clasen <maclas@gmx.de>
+ *
+ * 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <errno.h>
+#include "gdk-pixbuf-private.h"
+#include "gdk-pixbuf-io.h"
+
+typedef struct _GdkPixbufNonCollection GdkPixbufNonCollection;
+typedef struct _GdkPixbufNonCollectionClass GdkPixbufNonCollectionClass;
+
+#define GDK_TYPE_PIXBUF_NON_COLLECTION		(gdk_pixbuf_non_collection_get_type ())
+#define GDK_PIXBUF_NON_COLLECTION(object)	(G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_NON_COLLECTION, GdkPixbufNonCollection))
+#define GDK_IS_PIXBUF_NON_COLLECTION(object)	(G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_NON_COLLECTION))
+
+/* Private part of the GdkPixbufNonCollection structure */
+struct _GdkPixbufNonCollection {
+	GdkPixbufCollection parent_instance;
+
+	GdkPixbuf *pixbuf;
+};
+
+struct _GdkPixbufNonCollectionClass {
+	GdkPixbufCollectionClass parent_class;
+};
+
+static GType gdk_pixbuf_non_collection_get_type (void) G_GNUC_CONST;
+
+GType
+gdk_pixbuf_collection_get_type (void)
+{
+	static GType object_type = 0;
+
+	if (!object_type) {
+		static const GTypeInfo object_info = {
+			sizeof (GdkPixbufCollectionClass),
+                        (GBaseInitFunc) NULL,
+                        (GBaseFinalizeFunc) NULL,
+                        (GClassInitFunc) NULL,
+                        NULL,           /* class_finalize */
+                        NULL,           /* class_data */
+                        sizeof (GdkPixbufCollection),
+                        0,              /* n_preallocs */
+                        (GInstanceInitFunc) NULL,
+                };
+                
+                object_type = g_type_register_static (G_TYPE_OBJECT,
+                                                      "GdkPixbufCollection",
+                                                      &object_info, 0);
+        }
+	
+        return object_type;
+}
+
+static void
+prepared_notify (GdkPixbuf *pixbuf, 
+		 GdkPixbufAnimation *anim, 
+		 GdkPixbufCollection *coll, 
+		 gpointer user_data)
+{
+	if (coll != NULL)
+		g_object_ref (coll);
+	*((GdkPixbufCollection **)user_data) = coll;
+}
+
+static GdkPixbufCollection *
+generic_load_collection (GdkPixbufModule *module,
+                         FILE *f,
+                         GError **error)
+{
+	guchar buffer[4096];
+	size_t length;
+	GdkPixbufCollection *collection = NULL;
+	gpointer context;
+
+	if (module->load_collection != NULL)
+		return (* module->load_collection) (f, error);
+
+	context = module->begin_load (NULL, prepared_notify, NULL, &collection, error);
+	
+	if (!context)
+		return NULL;
+	
+	while (!feof (f)) {
+		length = fread (buffer, 1, sizeof (buffer), f);
+		if (length > 0)
+			if (!module->load_increment (context, buffer, length, error)) {
+				module->stop_load (context, NULL);
+				if (collection != NULL)
+					g_object_unref (collection);
+				return NULL;
+			}
+	}
+
+	if (!module->stop_load (context, error)) {
+		if (collection != NULL)
+			g_object_unref (collection);
+		return NULL;
+	}
+	
+	return collection;
+}
+
+/**
+ * gdk_pixbuf_collection_new_from_file:
+ * @filename: Name of file to load.
+ * @error: return location for error
+ *
+ * Creates a new collection by loading it from a file.  The file format is
+ * detected automatically.  If the file's format does not support image
+ * collections, then a collection with a single image will be created. 
+ * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
+ *
+ * Return value: A newly-created collection with a reference count of 1, or 
+ * %NULL if any of several error conditions ocurred:  the file could not be 
+ * opened, there was no loader for the file's format, there was not enough 
+ * memory to allocate the image buffer, or the image file contained invalid 
+ * data.
+ **/
+GdkPixbufCollection *
+gdk_pixbuf_collection_new_from_file (const char *filename,
+				     GError    **error)
+{
+	GdkPixbufCollection *collection;
+	int size;
+	FILE *f;
+	guchar buffer[128];
+	GdkPixbufModule *image_module;
+
+	g_return_val_if_fail (filename != NULL, NULL);
+
+	f = fopen (filename, "rb");
+	if (!f) {
+                g_set_error (error,
+                             G_FILE_ERROR,
+                             g_file_error_from_errno (errno),
+                             _("Failed to open file '%s': %s"),
+                             filename, g_strerror (errno));
+		return NULL;
+        }
+
+	size = fread (&buffer, 1, sizeof (buffer), f);
+	if (size == 0) {
+                g_set_error (error,
+                             GDK_PIXBUF_ERROR,
+                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+                             _("Image file '%s' contains no data"),
+                             filename);
+                
+		fclose (f);
+		return NULL;
+	}
+
+	image_module = _gdk_pixbuf_get_module (buffer, size, filename, error);
+	if (!image_module) {
+		fclose (f);
+		return NULL;
+	}
+
+	if (image_module->module == NULL)
+                if (!_gdk_pixbuf_load_module (image_module, error)) {
+                        fclose (f);
+                        return NULL;
+                }
+
+	if (image_module->load_collection == NULL &&
+            image_module->load_animation == NULL) {                
+		GdkPixbuf *pixbuf;
+
+		/* Keep this logic in sync with gdk_pixbuf_new_from_file() */
+		fseek (f, 0, SEEK_SET);
+		pixbuf = _gdk_pixbuf_generic_image_load (image_module, f, error);
+		fclose (f);
+
+                if (pixbuf == NULL && error != NULL && *error == NULL) {
+                        /* I don't trust these crufty longjmp()'ing image libs
+                         * to maintain proper error invariants, and I don't
+                         * want user code to segfault as a result. We need to maintain
+                         * the invariant that error gets set if NULL is returned.
+                         */
+                        
+                        g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.",
+                                   image_module->module_name);
+                        g_set_error (error,
+                                     GDK_PIXBUF_ERROR,
+                                     GDK_PIXBUF_ERROR_FAILED,
+                                     _("Failed to load image '%s': reason not known, probably a corrupt image file"),
+                                     filename);
+                }
+                
+		if (pixbuf == NULL)
+                        return NULL;
+
+                collection = gdk_pixbuf_non_collection_new (pixbuf);
+
+                g_object_unref (pixbuf);
+	} else {
+		fseek (f, 0, SEEK_SET);
+                
+		collection = generic_load_collection (image_module, f, error);
+		
+                if (collection == NULL && error != NULL && *error == NULL) {
+                        /* I don't trust these crufty longjmp()'ing
+                         * image libs to maintain proper error
+                         * invariants, and I don't want user code to
+                         * segfault as a result. We need to maintain
+                         * the invariant that error gets set if NULL
+                         * is returned.
+                         */
+                        
+                        g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.",
+                                   image_module->module_name);
+                        g_set_error (error,
+                                     GDK_PIXBUF_ERROR,
+                                     GDK_PIXBUF_ERROR_FAILED,
+                                     _("Failed to load collection '%s': reason not known, probably a corrupt file"),
+                                     filename);
+                }
+                
+		fclose (f);
+	}
+
+	return collection;
+}
+
+/** 
+ * gdk_pixbuf_collection_get_length:
+ * @collection: a #GdkPixbufCollection
+ * 
+ * Returns the size of the collection.
+ *
+ * Return value: the number of images in the collection.
+ */
+int
+gdk_pixbuf_collection_get_length (GdkPixbufCollection *collection)
+{
+	g_return_val_if_fail (GDK_IS_PIXBUF_COLLECTION (collection), -1);
+
+	return GDK_PIXBUF_COLLECTION_GET_CLASS (collection)->get_length (collection);
+}
+
+/**
+ * gdk_pixbuf_collection_get_pixbuf:
+ * @collection: a #GdkPixbufCollection
+ * @i: the position of the image to return, must be between 0 and the length
+ *    of the collection
+ *
+ * Returns the @i<!-- -->th image of the collection.
+ *
+ * Return value: the @i<!-- -->th image 
+ */
+GdkPixbuf *
+gdk_pixbuf_collection_get_pixbuf (GdkPixbufCollection *collection,
+				  int                  i)
+{
+	g_return_val_if_fail (i >= 0, NULL);
+	g_return_val_if_fail (i < gdk_pixbuf_collection_get_length (collection), NULL);
+
+	return GDK_PIXBUF_COLLECTION_GET_CLASS (collection)->get_pixbuf (collection, i);
+}
+
+/**
+ * gdk_pixbuf_collection_get_pixbuf_width:
+ * @collection: a #GdkPixbufCollection
+ * @i: the position of the image, must be between 0 and the length
+ *    of the collection
+ *
+ * Returns the width of the @i<!-- -->th image of the collection.
+ *
+ * Return value: the width of the @i<!-- -->th image 
+ */
+gint
+gdk_pixbuf_collection_get_pixbuf_width (GdkPixbufCollection *collection,
+					int                  i)
+{
+	g_return_val_if_fail (i >= 0, -1);
+	g_return_val_if_fail (i < gdk_pixbuf_collection_get_length (collection), -1);
+
+	return GDK_PIXBUF_COLLECTION_GET_CLASS (collection)->get_pixbuf_width (collection, i);
+}
+
+/**
+ * gdk_pixbuf_collection_get_pixbuf_height:
+ * @collection: a #GdkPixbufCollection
+ * @i: the position of the image, must be between 0 and the length
+ *    of the collection
+ *
+ * Returns the height of the @i<!-- -->th image of the collection.
+ *
+ * Return value: the height of the @i<!-- -->th image 
+ */
+gint
+gdk_pixbuf_collection_get_pixbuf_height (GdkPixbufCollection *collection,
+					 int                  i)
+{
+	g_return_val_if_fail (i >= 0, -1);
+	g_return_val_if_fail (i < gdk_pixbuf_collection_get_length (collection), -1);
+
+	return GDK_PIXBUF_COLLECTION_GET_CLASS (collection)->get_pixbuf_height (collection, i);
+}
+
+/**
+ * gdk_pixbuf_collection_get_pixbuf_depth:
+ * @collection: a #GdkPixbufCollection
+ * @i: the position of the image, must be between 0 and the length
+ *    of the collection
+ *
+ * Returns the number of bits per pixel which were used to store the
+ * @i<!-- -->th image of the collection.
+ *
+ * Note that this is not the same as the actual bpp of the @i<!-- -->th 
+ * pixbuf, which is always 24 or 32. 
+ *
+ * Return value: the depth of the @i<!-- -->th image 
+ */
+gint
+gdk_pixbuf_collection_get_pixbuf_depth (GdkPixbufCollection *collection,
+                                        int                  i)
+{
+	g_return_val_if_fail (i >= 0, -1);
+	g_return_val_if_fail (i < gdk_pixbuf_collection_get_length (collection), -1);
+	
+	return GDK_PIXBUF_COLLECTION_GET_CLASS (collection)->get_pixbuf_depth (collection, i);
+}
+
+/**
+ * gdk_pixbuf_collection_get_static_image:
+ * @collection: a #GdkPixbufCollection
+ *
+ * If the collection is really just a plain image (has only one image),
+ * this function returns that image. If the collection contains multiple
+ * images, this function returns a reasonable thing to display as a static
+ * representation of the collection, which might be the first image, or 
+ * something more sophisticated. 
+ *
+ * Return value: an image representing the collection 
+ */
+GdkPixbuf *
+gdk_pixbuf_collection_get_static_image (GdkPixbufCollection *collection)
+{
+	return GDK_PIXBUF_COLLECTION_GET_CLASS (collection)->get_static_image (collection);
+}
+
+
+static void       gdk_pixbuf_non_collection_class_init        (GdkPixbufNonCollectionClass *klass);
+static void       gdk_pixbuf_non_collection_finalize          (GObject                     *gobject);
+static gint       gdk_pixbuf_non_collection_get_length        (GdkPixbufCollection         *collection);
+static GdkPixbuf *gdk_pixbuf_non_collection_get_pixbuf        (GdkPixbufCollection         *collection,
+							       int                          i);
+static gint       gdk_pixbuf_non_collection_get_pixbuf_height (GdkPixbufCollection         *collection,
+							       int                          i);
+static gint       gdk_pixbuf_non_collection_get_pixbuf_width  (GdkPixbufCollection         *collection,
+							       int                          i);
+static gint       gdk_pixbuf_non_collection_get_pixbuf_depth  (GdkPixbufCollection         *collection,
+							       int                          i);
+static GdkPixbuf *gdk_pixbuf_non_collection_get_static_image  (GdkPixbufCollection         *collection);
+
+
+
+static gpointer non_parent_class;
+
+GType
+gdk_pixbuf_non_collection_get_type (void)
+{
+	static GType object_type = 0;
+
+	if (!object_type) {
+		static const GTypeInfo object_info = {
+			sizeof (GdkPixbufNonCollectionClass),
+			(GBaseInitFunc) NULL,
+                        (GBaseFinalizeFunc) NULL,
+                        (GClassInitFunc) gdk_pixbuf_non_collection_class_init,
+                        NULL,           /* class_finalize */
+                        NULL,           /* class_data */
+                        sizeof (GdkPixbufNonCollection),
+                        0,              /* n_preallocs */
+                        (GInstanceInitFunc) NULL,
+                };
+                
+                object_type = g_type_register_static (GDK_TYPE_PIXBUF_COLLECTION,
+                                                      "GdkPixbufNonCollection",
+                                                      &object_info, 0);
+        }
+        
+        return object_type;
+}
+			
+static void
+gdk_pixbuf_non_collection_class_init (GdkPixbufNonCollectionClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+        GdkPixbufCollectionClass *collection_class = GDK_PIXBUF_COLLECTION_CLASS (klass);
+        
+        non_parent_class = g_type_class_peek_parent (klass);
+
+        object_class->finalize = gdk_pixbuf_non_collection_finalize;
+
+	collection_class->get_length = gdk_pixbuf_non_collection_get_length;
+	collection_class->get_pixbuf = gdk_pixbuf_non_collection_get_pixbuf;
+	collection_class->get_pixbuf_width = gdk_pixbuf_non_collection_get_pixbuf_width;
+	collection_class->get_pixbuf_height = gdk_pixbuf_non_collection_get_pixbuf_height;
+	collection_class->get_pixbuf_depth = gdk_pixbuf_non_collection_get_pixbuf_depth;
+	collection_class->get_static_image = gdk_pixbuf_non_collection_get_static_image;
+}
+
+static void
+gdk_pixbuf_non_collection_finalize (GObject *object)
+{
+	GdkPixbufNonCollection *non_collection = GDK_PIXBUF_NON_COLLECTION (object);
+
+	if (non_collection->pixbuf)
+		g_object_unref (non_collection->pixbuf);
+
+	G_OBJECT_CLASS (non_parent_class)->finalize (object);
+}
+
+static gint
+gdk_pixbuf_non_collection_get_length (GdkPixbufCollection *collection)
+{
+	if (GDK_PIXBUF_NON_COLLECTION (collection)->pixbuf)
+		return 1;
+	else
+		return 0;
+}
+
+static gint
+gdk_pixbuf_non_collection_get_pixbuf_width (GdkPixbufCollection *collection,
+					     int                  i)
+{
+	return gdk_pixbuf_get_width (GDK_PIXBUF_NON_COLLECTION (collection)->pixbuf);
+}
+
+static gint
+gdk_pixbuf_non_collection_get_pixbuf_height (GdkPixbufCollection *collection,
+					     int                  i)
+{
+	return gdk_pixbuf_get_height (GDK_PIXBUF_NON_COLLECTION (collection)->pixbuf);
+}
+
+static gint
+gdk_pixbuf_non_collection_get_pixbuf_depth (GdkPixbufCollection *collection,
+                                            int                  i)
+{
+	GdkPixbufNonCollection *non_collection = GDK_PIXBUF_NON_COLLECTION (collection);
+	
+	return gdk_pixbuf_get_bits_per_sample (non_collection->pixbuf) *
+		gdk_pixbuf_get_n_channels (non_collection->pixbuf);
+}
+
+static GdkPixbuf *
+gdk_pixbuf_non_collection_get_pixbuf (GdkPixbufCollection *collection,
+				      int                  i)
+{
+	GdkPixbufNonCollection *non_collection = GDK_PIXBUF_NON_COLLECTION (collection);
+
+	return non_collection->pixbuf;
+}
+
+static GdkPixbuf *
+gdk_pixbuf_non_collection_get_static_image (GdkPixbufCollection *collection)
+{
+	GdkPixbufNonCollection *non_collection = GDK_PIXBUF_NON_COLLECTION (collection);
+
+	return non_collection->pixbuf;
+}
+
+
+GdkPixbufCollection *
+gdk_pixbuf_non_collection_new (GdkPixbuf *pixbuf)
+{
+	GdkPixbufNonCollection *non_collection;
+
+	non_collection = g_object_new (GDK_TYPE_PIXBUF_NON_COLLECTION, NULL);
+
+	non_collection->pixbuf = pixbuf;
+	if (pixbuf)
+		g_object_ref (pixbuf);
+
+	return GDK_PIXBUF_COLLECTION (non_collection);
+}
+
+
diff -uN gdk-pixbuf.orig/gdk-pixbuf-io.c gdk-pixbuf/gdk-pixbuf-io.c
--- gdk-pixbuf.orig/gdk-pixbuf-io.c	Fri Sep  6 23:14:15 2002
+++ gdk-pixbuf/gdk-pixbuf-io.c	Sun Sep  8 21:38:51 2002
@@ -583,6 +583,7 @@
 static void
 prepared_notify (GdkPixbuf *pixbuf, 
 		 GdkPixbufAnimation *anim, 
+		 GdkPixbufCollection *coll, 
 		 gpointer user_data)
 {
 	if (pixbuf != NULL)
diff -uN gdk-pixbuf.orig/gdk-pixbuf-io.h gdk-pixbuf/gdk-pixbuf-io.h
--- gdk-pixbuf.orig/gdk-pixbuf-io.h	Thu Aug 22 23:32:06 2002
+++ gdk-pixbuf/gdk-pixbuf-io.h	Sun Sep  8 02:35:15 2002
@@ -43,6 +43,7 @@
 
 typedef void (* ModulePreparedNotifyFunc) (GdkPixbuf          *pixbuf,
                                            GdkPixbufAnimation *anim,
+                                           GdkPixbufCollection *coll,
                                            gpointer            user_data);
 typedef void (* ModuleUpdatedNotifyFunc)  (GdkPixbuf *pixbuf,
                                            int        x,
@@ -78,6 +79,9 @@
 	GdkPixbufAnimation *(* load_animation) (FILE    *f,
                                                 GError **error);
 
+	/* Collection loading */
+	GdkPixbufCollection *(* load_collection) (FILE    *f,
+						  GError **error);
         gboolean (* save) (FILE      *f,
                            GdkPixbuf *pixbuf,
                            gchar    **param_keys,
@@ -94,6 +98,10 @@
                                                GError **error);
 gboolean _gdk_pixbuf_load_module (GdkPixbufModule *image_module,
                                   GError **error);
+
+GdkPixbuf *_gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
+					   FILE *f,
+					   GError **error);
 
 GdkPixbuf *_gdk_pixbuf_generic_image_load (GdkPixbufModule *image_module,
 					   FILE *f,
diff -uN gdk-pixbuf.orig/gdk-pixbuf-loader.c gdk-pixbuf/gdk-pixbuf-loader.c
--- gdk-pixbuf.orig/gdk-pixbuf-loader.c	Sun Jul  7 01:10:45 2002
+++ gdk-pixbuf/gdk-pixbuf-loader.c	Tue Sep 10 21:02:44 2002
@@ -54,6 +54,7 @@
 typedef struct
 {
   GdkPixbufAnimation *animation;
+  GdkPixbufCollection *collection;
   gboolean closed;
   guchar header_buf[LOADER_HEADER_SIZE];
   gint header_buf_offset;
@@ -181,6 +182,9 @@
   if (priv->animation)
     g_object_unref (priv->animation);
   
+  if (priv->collection)
+    g_object_unref (priv->collection);
+  
   g_free (priv);
   
   G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -235,6 +239,7 @@
 static void
 gdk_pixbuf_loader_prepare (GdkPixbuf          *pixbuf,
                            GdkPixbufAnimation *anim,
+                           GdkPixbufCollection *coll,
 			   gpointer            loader)
 {
   GdkPixbufLoaderPrivate *priv = GDK_PIXBUF_LOADER (loader)->priv;
@@ -258,9 +263,12 @@
     g_object_ref (anim);
   else
     anim = gdk_pixbuf_non_anim_new (pixbuf);
-  
   priv->animation = anim;
-  
+
+  if (coll)
+    g_object_ref (coll);
+  priv->collection = coll;  
+
   if (!priv->needs_scale)
     g_signal_emit (loader, pixbuf_loader_signals[AREA_PREPARED], 0);
 }
@@ -274,7 +282,7 @@
 			  gpointer   loader)
 {
   GdkPixbufLoaderPrivate *priv = GDK_PIXBUF_LOADER (loader)->priv;
-  
+
   if (!priv->needs_scale)
     g_signal_emit (loader,
 		   pixbuf_loader_signals[AREA_UPDATED],
@@ -538,6 +546,8 @@
 
   if (priv->animation)
     return gdk_pixbuf_animation_get_static_image (priv->animation);
+  else if (priv->collection)
+    return gdk_pixbuf_collection_get_static_image (priv->collection);
   else
     return NULL;
 }
@@ -568,6 +578,33 @@
   return priv->animation;
 }
 
+
+/**
+ * gdk_pixbuf_loader_get_collection:
+ * @loader: A pixbuf loader
+ *
+ * Queries the #GdkPixbufCollection that a pixbuf loader is currently creating.
+ * In general it only makes sense to call this function after the "area_prepared"
+ * signal has been emitted by the loader. If the loader doesn't have enough
+ * bytes yet (hasn't emitted the "area_prepared" signal) this function will 
+ * return %NULL.
+ *
+ * Return value: The #GdkPixbufCollection that the loader is loading, or %NULL if
+ not enough data has been read to determine the information.
+**/
+GdkPixbufCollection *
+gdk_pixbuf_loader_get_collection (GdkPixbufLoader *loader)
+{
+  GdkPixbufLoaderPrivate *priv;
+  
+  g_return_val_if_fail (loader != NULL, NULL);
+  g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), NULL);
+  
+  priv = loader->priv;
+  
+  return priv->collection;
+}
+
 /**
  * gdk_pixbuf_loader_close:
  * @loader: A pixbuf loader.
@@ -624,6 +661,7 @@
     GdkPixbuf *tmp, *pixbuf;
 
     tmp = gdk_pixbuf_animation_get_static_image (priv->animation);
+
     g_object_ref (tmp);
     pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, tmp->has_alpha, 8, priv->width, priv->height);
     g_object_unref (priv->animation);
@@ -644,6 +682,7 @@
 
   return retval;
 }
+
 
 
 
diff -uN gdk-pixbuf.orig/gdk-pixbuf-loader.h gdk-pixbuf/gdk-pixbuf-loader.h
--- gdk-pixbuf.orig/gdk-pixbuf-loader.h	Sun Jul  7 01:10:45 2002
+++ gdk-pixbuf/gdk-pixbuf-loader.h	Sun Sep  8 02:36:47 2002
@@ -79,6 +79,7 @@
                                                       GError         **error);
 GdkPixbuf *          gdk_pixbuf_loader_get_pixbuf    (GdkPixbufLoader *loader);
 GdkPixbufAnimation * gdk_pixbuf_loader_get_animation (GdkPixbufLoader *loader);
+GdkPixbufCollection* gdk_pixbuf_loader_get_collection(GdkPixbufLoader *loader);
 gboolean             gdk_pixbuf_loader_close         (GdkPixbufLoader *loader,
                                                       GError         **error);
 
diff -uN gdk-pixbuf.orig/gdk-pixbuf-private.h gdk-pixbuf/gdk-pixbuf-private.h
--- gdk-pixbuf.orig/gdk-pixbuf-private.h	Fri Oct  5 20:51:47 2001
+++ gdk-pixbuf/gdk-pixbuf-private.h	Mon Sep  9 23:08:05 2002
@@ -131,8 +130,37 @@
 
 GdkPixbufAnimation* gdk_pixbuf_non_anim_new (GdkPixbuf *pixbuf);
 
+typedef struct _GdkPixbufCollectionClass GdkPixbufCollectionClass;
+
+#define GDK_PIXBUF_COLLECTION_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_COLLECTION, GdkPixbufCollectionClass))
+#define GDK_IS_PIXBUF_COLLECTION_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_COLLECTION))
+#define GDK_PIXBUF_COLLECTION_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_COLLECTION, GdkPixbufCollectionClass))
+
+/* Private part of the GdkPixbufCollection structure */
+struct _GdkPixbufCollection {
+        GObject parent_instance;
+};
+
+struct _GdkPixbufCollectionClass {
+        GObjectClass parent_class;
+
+        gint       (* get_length)        (GdkPixbufCollection *collection);
+        GdkPixbuf *(* get_pixbuf)        (GdkPixbufCollection *collection,
+                                          int                  i);
+        gint       (* get_pixbuf_width)  (GdkPixbufCollection *collection,
+                                          int                  i);
+        gint       (* get_pixbuf_height) (GdkPixbufCollection *collection,
+                                          int                  i);
+        gint       (* get_pixbuf_depth)  (GdkPixbufCollection *collection,
+                                          int                  i);
+        GdkPixbuf* (*get_static_image)   (GdkPixbufCollection *collection);
+};
+
+GdkPixbufCollection *gdk_pixbuf_non_collection_new (GdkPixbuf *pixbuf);
+
 
 
+        
 /*  key/value pairs that can be attached by the pixbuf loader  */
 
 gboolean gdk_pixbuf_set_option  (GdkPixbuf   *pixbuf,
diff -uN gdk-pixbuf.orig/gdk-pixbuf.h gdk-pixbuf/gdk-pixbuf.h
--- gdk-pixbuf.orig/gdk-pixbuf.h	Wed Jan  9 17:36:20 2002
+++ gdk-pixbuf/gdk-pixbuf.h	Tue Sep 10 22:17:44 2002
@@ -53,6 +53,7 @@
 typedef struct _GdkPixbuf GdkPixbuf;
 typedef struct _GdkPixbufAnimation GdkPixbufAnimation;
 typedef struct _GdkPixbufAnimationIter GdkPixbufAnimationIter;
+typedef struct _GdkPixbufCollection GdkPixbufCollection;
 typedef struct _GdkPixbufFrame GdkPixbufFrame;
 
 #define GDK_TYPE_PIXBUF              (gdk_pixbuf_get_type ())
@@ -67,6 +68,10 @@
 #define GDK_PIXBUF_ANIMATION_ITER(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_ANIMATION_ITER, GdkPixbufAnimationIter))
 #define GDK_IS_PIXBUF_ANIMATION_ITER(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_ANIMATION_ITER))
 
+#define GDK_TYPE_PIXBUF_COLLECTION		(gdk_pixbuf_collection_get_type ())
+#define GDK_PIXBUF_COLLECTION(object)		(G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_COLLECTION, GdkPixbufCollection))
+#define GDK_IS_PIXBUF_COLLECTION(object)	(G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_COLLECTION))
+
 /* Handler that must free the pixel array */
 typedef void (* GdkPixbufDestroyNotify) (guchar *pixels, gpointer data);
 
@@ -281,6 +286,24 @@
 gboolean                gdk_pixbuf_animation_iter_advance                    (GdkPixbufAnimationIter *iter,
                                                                               const GTimeVal         *current_time);
 
+
+/* Collection support */
+
+GType                 gdk_pixbuf_collection_get_type      (void) G_GNUC_CONST;
+
+GdkPixbufCollection * gdk_pixbuf_collection_new_from_file (const char          *filename,
+							   GError             **error);
+
+int                   gdk_pixbuf_collection_get_length        (GdkPixbufCollection *collection);
+GdkPixbuf           * gdk_pixbuf_collection_get_pixbuf        (GdkPixbufCollection *collection,
+							       int                  i);
+gint                  gdk_pixbuf_collection_get_pixbuf_width  (GdkPixbufCollection *collection,
+							       int                  i);
+gint                  gdk_pixbuf_collection_get_pixbuf_height (GdkPixbufCollection *collection,
+							       int                  i);
+gint                  gdk_pixbuf_collection_get_pixbuf_depth  (GdkPixbufCollection *collection,
+							       int                  i);
+GdkPixbuf            *gdk_pixbuf_collection_get_static_image (GdkPixbufCollection *collection);
 
 
 
diff -uN gdk-pixbuf.orig/io-ani-animation.c gdk-pixbuf/io-ani-animation.c
--- gdk-pixbuf.orig/io-ani-animation.c	Fri Sep  6 23:14:15 2002
+++ gdk-pixbuf/io-ani-animation.c	Tue Sep 10 21:33:12 2002
@@ -26,6 +26,7 @@
 #include "gdk-pixbuf-io.h"
 #include "gdk-pixbuf-private.h"
 #include "io-ani-animation.h"
+#include "io-ani-collection.h"
 
 static void gdk_pixbuf_ani_anim_class_init (GdkPixbufAniAnimClass *klass);
 static void gdk_pixbuf_ani_anim_finalize   (GObject        *object);
@@ -44,7 +45,7 @@
 static gpointer parent_class;
 
 GType
-gdk_pixbuf_ani_anim_get_type (void)
+gdk_pixbuf_ani_anim_get_type (void) 
 {
         static GType object_type = 0;
 
@@ -170,6 +171,20 @@
         return GDK_PIXBUF_ANIMATION_ITER (iter);
 }
 
+GdkPixbufCollection*
+_gdk_pixbuf_ani_anim_get_collection (GdkPixbufAnimation *anim)
+{
+        GdkPixbufAniCollection *collection;
+
+        collection = g_object_new (GDK_TYPE_PIXBUF_ANI_COLLECTION, NULL);
+
+        collection->ani_anim = GDK_PIXBUF_ANI_ANIM (anim);
+
+        g_object_ref (collection->ani_anim);
+        
+        return GDK_PIXBUF_COLLECTION (collection);
+}
+
 
 
 static void gdk_pixbuf_ani_anim_iter_class_init (GdkPixbufAniAnimIterClass *klass);
@@ -335,13 +350,4 @@
 
         return FALSE;
 }
-
-
-
-
-
-
-
-
-
 
diff -uN gdk-pixbuf.orig/io-ani-animation.h gdk-pixbuf/io-ani-animation.h
--- gdk-pixbuf.orig/io-ani-animation.h	Fri Sep  6 23:14:15 2002
+++ gdk-pixbuf/io-ani-animation.h	Mon Sep  9 22:51:36 2002
@@ -109,4 +109,7 @@
 
 GType gdk_pixbuf_ani_anim_iter_get_type (void) G_GNUC_CONST;
 
+GdkPixbufCollection*
+_gdk_pixbuf_ani_anim_get_collection (GdkPixbufAnimation *anim);
+
 #endif
diff -uN gdk-pixbuf.orig/io-ani-collection.c gdk-pixbuf/io-ani-collection.c
--- gdk-pixbuf.orig/io-ani-collection.c	Thu Jan  1 01:00:00 1970
+++ gdk-pixbuf/io-ani-collection.c	Tue Sep 10 21:33:19 2002
@@ -0,0 +1,154 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GdkPixbuf library - ani support
+ *
+ * Copyright (C) 2002 The Free Software Foundation
+ *
+ * Author: Matthias Clasen <maclas@gmx.de>
+ *
+ * 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.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include "gdk-pixbuf-io.h"
+#include "gdk-pixbuf-private.h"
+#include "io-ani-collection.h"
+
+static void gdk_pixbuf_ani_collection_class_init (GdkPixbufAniCollectionClass *klass);
+static void gdk_pixbuf_ani_collection_finalize   (GObject                   *object);
+static gint gdk_pixbuf_ani_collection_get_length (GdkPixbufCollection *collection);
+static GdkPixbuf *gdk_pixbuf_ani_collection_get_pixbuf (GdkPixbufCollection *collection, int i);
+static gint gdk_pixbuf_ani_collection_get_pixbuf_width (GdkPixbufCollection *collection, int i);
+static gint gdk_pixbuf_ani_collection_get_pixbuf_height (GdkPixbufCollection *collection, int i);
+static gint gdk_pixbuf_ani_collection_get_pixbuf_depth (GdkPixbufCollection *collection, int i);
+static GdkPixbuf* gdk_pixbuf_ani_collection_get_static_image (GdkPixbufCollection *collection);
+
+
+static gpointer collection_parent_class;
+
+GType
+gdk_pixbuf_ani_collection_get_type (void)
+{
+        static GType object_type = 0;
+
+        if (!object_type) {
+                static const GTypeInfo object_info = {
+                        sizeof (GdkPixbufAniCollectionClass),
+                        (GBaseInitFunc) NULL,
+                        (GBaseFinalizeFunc) NULL,
+                        (GClassInitFunc) gdk_pixbuf_ani_collection_class_init,
+                        NULL,           /* class_finalize */
+                        NULL,           /* class_data */
+                        sizeof (GdkPixbufAniCollection),
+                        0,              /* n_preallocs */
+                        (GInstanceInitFunc) NULL,
+                };
+                
+                object_type = g_type_register_static (GDK_TYPE_PIXBUF_COLLECTION,
+                                                      "GdkPixbufAniCollection",
+                                                      &object_info, 0);
+        }
+        
+        return object_type;
+}
+
+static void
+gdk_pixbuf_ani_collection_class_init (GdkPixbufAniCollectionClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+        GdkPixbufCollectionClass *collection_class =
+                GDK_PIXBUF_COLLECTION_CLASS (klass);
+        
+        collection_parent_class = g_type_class_peek_parent (klass);
+        
+        object_class->finalize = gdk_pixbuf_ani_collection_finalize;
+
+        collection_class->get_length = gdk_pixbuf_ani_collection_get_length;
+        collection_class->get_pixbuf = gdk_pixbuf_ani_collection_get_pixbuf;
+        collection_class->get_pixbuf_width = gdk_pixbuf_ani_collection_get_pixbuf_width;
+        collection_class->get_pixbuf_height = gdk_pixbuf_ani_collection_get_pixbuf_height;
+        collection_class->get_pixbuf_depth = gdk_pixbuf_ani_collection_get_pixbuf_depth;
+        collection_class->get_static_image = gdk_pixbuf_ani_collection_get_static_image;
+}
+
+static void
+gdk_pixbuf_ani_collection_finalize (GObject *object)
+{
+        GdkPixbufAniCollection *coll = GDK_PIXBUF_ANI_COLLECTION (object);
+
+        g_object_unref (coll->ani_anim);
+        
+        G_OBJECT_CLASS (collection_parent_class)->finalize (object);
+}
+
+static gint 
+gdk_pixbuf_ani_collection_get_length (GdkPixbufCollection *collection)
+{
+        GdkPixbufAniCollection *coll = GDK_PIXBUF_ANI_COLLECTION (collection);
+
+        return coll->ani_anim->n_frames;
+}
+
+static GdkPixbuf *
+gdk_pixbuf_ani_collection_get_pixbuf (GdkPixbufCollection *collection, int i)
+{
+        int k;
+        GdkPixbufAniCollection *coll = GDK_PIXBUF_ANI_COLLECTION (collection);
+
+        k = coll->ani_anim->sequence[i];
+
+        /* this is necessary if the animation is displayed while loading */
+        while (k > 0 && !coll->ani_anim->pixbufs[k])
+                k--;
+
+        return coll->ani_anim->pixbufs[k];
+}
+
+static gint gdk_pixbuf_ani_collection_get_pixbuf_width (GdkPixbufCollection *collection, int i) 
+{
+        GdkPixbuf *pixbuf;
+
+        pixbuf = gdk_pixbuf_ani_collection_get_pixbuf (collection, i);
+
+        return gdk_pixbuf_get_width (pixbuf);
+}
+
+static gint gdk_pixbuf_ani_collection_get_pixbuf_height (GdkPixbufCollection *collection, int i)
+{
+        GdkPixbuf *pixbuf;
+
+        pixbuf = gdk_pixbuf_ani_collection_get_pixbuf (collection, i);
+
+        return gdk_pixbuf_get_height (pixbuf);
+}
+
+static gint gdk_pixbuf_ani_collection_get_pixbuf_depth (GdkPixbufCollection *collection, int i)
+{
+        GdkPixbuf *pixbuf;
+
+        pixbuf = gdk_pixbuf_ani_collection_get_pixbuf (collection, i);
+
+        return gdk_pixbuf_get_bits_per_sample (pixbuf) * gdk_pixbuf_get_n_channels (pixbuf);
+}
+
+static GdkPixbuf *
+gdk_pixbuf_ani_collection_get_static_image (GdkPixbufCollection *collection)
+{
+        GdkPixbufAniCollection *coll = GDK_PIXBUF_ANI_COLLECTION (collection);
+        
+        return gdk_pixbuf_animation_get_static_image (coll->ani_anim);
+}
+
diff -uN gdk-pixbuf.orig/io-ani-collection.h gdk-pixbuf/io-ani-collection.h
--- gdk-pixbuf.orig/io-ani-collection.h	Thu Jan  1 01:00:00 1970
+++ gdk-pixbuf/io-ani-collection.h	Mon Sep  9 23:04:06 2002
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GdkPixbuf library - ANI loader declarations
+ *
+ * Copyright (C) 2002 The Free Software Foundation
+ *
+ * Author: Matthias Clasen <maclas@gmx.de>
+ *
+ * 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.
+ */
+
+#ifndef GDK_PIXBUF_ANI_COLLECTION_H
+#define GDK_PIXBUF_ANI_COLLECTION_H
+
+#include "gdk-pixbuf-private.h"
+#include "io-ani-animation.h"
+
+typedef struct _GdkPixbufAniCollection GdkPixbufAniCollection;
+typedef struct _GdkPixbufAniCollectionClass GdkPixbufAniCollectionClass;
+
+#define GDK_TYPE_PIXBUF_ANI_COLLECTION              (gdk_pixbuf_ani_collection_get_type ())
+#define GDK_PIXBUF_ANI_COLLECTION(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_ANI_COLLECTION, GdkPixbufAniCollection))
+#define GDK_IS_PIXBUF_ANI_COLLECTION(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_ANI_COLLECTION))
+
+#define GDK_PIXBUF_ANI_COLLECTION_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_ANI_COLLECTION, GdkPixbufAniCollectionClass))
+#define GDK_IS_PIXBUF_ANI_COLLECTION_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_ANI_COLLECTION))
+#define GDK_PIXBUF_ANI_COLLECTION_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_ANI_COLLECTION, GdkPixbufAniCollectionClass))
+
+struct _GdkPixbufAniCollection {
+        GdkPixbufCollection parent_instance;
+        
+        GdkPixbufAniAnim   *ani_anim;
+};
+
+struct _GdkPixbufAniCollectionClass {
+        GdkPixbufCollectionClass parent_class;
+};
+
+GType gdk_pixbuf_ani_collection_get_type (void) G_GNUC_CONST;
+
+#endif
diff -uN gdk-pixbuf.orig/io-ani.c gdk-pixbuf/io-ani.c
--- gdk-pixbuf.orig/io-ani.c	Fri Sep  6 23:14:15 2002
+++ gdk-pixbuf/io-ani.c	Tue Sep 10 21:30:53 2002
@@ -29,6 +29,7 @@
 #include "gdk-pixbuf-private.h"
 #include "gdk-pixbuf-io.h"
 #include "io-ani-animation.h"
+#include "io-ani-collection.h"
 
 static int
 lsb_32 (guchar *src)
@@ -164,10 +165,15 @@
 
 	if (context->pos == 0) 
 	{
-		if (context->prepared_func)
+		if (context->prepared_func) {
+			GdkPixbufCollection *collection =
+				_gdk_pixbuf_ani_anim_get_collection (GDK_PIXBUF_ANIMATION (context->animation));
 			(* context->prepared_func) (pixbuf, 
 						    GDK_PIXBUF_ANIMATION (context->animation), 
+						    collection,
 						    context->user_data);
+			g_object_unref (collection);
+		}
 	}
 	else {
 		/* FIXME - this is necessary for nice display of loading 
@@ -605,6 +611,7 @@
 static void
 prepared_notify (GdkPixbuf *pixbuf, 
 		 GdkPixbufAnimation *anim, 
+		 GdkPixbufCollection *coll, 
 		 gpointer user_data)
 {
 	if (anim != NULL)
diff -uN gdk-pixbuf.orig/io-bmp.c gdk-pixbuf/io-bmp.c
--- gdk-pixbuf.orig/io-bmp.c	Wed Sep  4 01:43:21 2002
+++ gdk-pixbuf/io-bmp.c	Sun Sep  8 02:45:21 2002
@@ -342,7 +342,7 @@
 
 		if (State->prepared_func != NULL)
 			/* Notify the client that we are ready to go */
-			(*State->prepared_func) (State->pixbuf, NULL, State->user_data);
+			(*State->prepared_func) (State->pixbuf, NULL, NULL, State->user_data);
 
 	}
 	
diff -uN gdk-pixbuf.orig/io-gif-animation.c gdk-pixbuf/io-gif-animation.c
--- gdk-pixbuf.orig/io-gif-animation.c	Thu Dec 13 22:22:11 2001
+++ gdk-pixbuf/io-gif-animation.c	Mon Sep  9 23:01:11 2002
@@ -27,6 +27,7 @@
 #include "gdk-pixbuf-io.h"
 #include "gdk-pixbuf-private.h"
 #include "io-gif-animation.h"
+#include "io-gif-collection.h"
 
 static void gdk_pixbuf_gif_anim_class_init (GdkPixbufGifAnimClass *klass);
 static void gdk_pixbuf_gif_anim_finalize   (GObject        *object);
@@ -185,6 +186,20 @@
         return GDK_PIXBUF_ANIMATION_ITER (iter);
 }
 
+GdkPixbufCollection*
+_gdk_pixbuf_gif_anim_get_collection (GdkPixbufAnimation *anim)
+{
+        GdkPixbufGifCollection *collection;
+
+        collection = g_object_new (GDK_TYPE_PIXBUF_GIF_COLLECTION, NULL);
+
+        collection->gif_anim = GDK_PIXBUF_GIF_ANIM (anim);
+
+        g_object_ref (collection->gif_anim);
+        
+        return GDK_PIXBUF_COLLECTION (collection);
+}
+
 
 
 static void gdk_pixbuf_gif_anim_iter_class_init (GdkPixbufGifAnimIterClass *klass);
@@ -555,3 +570,5 @@
 
         return iter->current_frame == NULL || iter->current_frame->next == NULL;  
 }
+
+
diff -uN gdk-pixbuf.orig/io-gif-animation.h gdk-pixbuf/io-gif-animation.h
--- gdk-pixbuf.orig/io-gif-animation.h	Mon May  7 17:58:41 2001
+++ gdk-pixbuf/io-gif-animation.h	Mon Sep  9 22:59:22 2002
@@ -89,7 +89,6 @@
 typedef struct _GdkPixbufGifAnimIter GdkPixbufGifAnimIter;
 typedef struct _GdkPixbufGifAnimIterClass GdkPixbufGifAnimIterClass;
 
-
 #define GDK_TYPE_PIXBUF_GIF_ANIM_ITER              (gdk_pixbuf_gif_anim_iter_get_type ())
 #define GDK_PIXBUF_GIF_ANIM_ITER(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_GIF_ANIM_ITER, GdkPixbufGifAnimIter))
 #define GDK_IS_PIXBUF_GIF_ANIM_ITER(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_GIF_ANIM_ITER))
@@ -165,5 +164,8 @@
 
 void gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
                                           GdkPixbufFrame   *frame);
+
+GdkPixbufCollection*
+_gdk_pixbuf_gif_anim_get_collection (GdkPixbufAnimation *anim);
 
 #endif
diff -uN gdk-pixbuf.orig/io-gif-collection.c gdk-pixbuf/io-gif-collection.c
--- gdk-pixbuf.orig/io-gif-collection.c	Thu Jan  1 01:00:00 1970
+++ gdk-pixbuf/io-gif-collection.c	Tue Sep 10 22:08:57 2002
@@ -0,0 +1,159 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GdkPixbuf library - animated gif support
+ *
+ * Copyright (C) 2002 The Free Software Foundation
+ *
+ * Author: Matthias Clasen <maclas@gmx.de> 
+ *
+ * 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.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include "gdk-pixbuf-io.h"
+#include "gdk-pixbuf-private.h"
+#include "io-gif-collection.h"
+
+
+static void gdk_pixbuf_gif_collection_class_init (GdkPixbufGifCollectionClass *klass);
+static void gdk_pixbuf_gif_collection_finalize   (GObject                   *object);
+static gint gdk_pixbuf_gif_collection_get_length (GdkPixbufCollection *collection);
+static GdkPixbuf *gdk_pixbuf_gif_collection_get_pixbuf (GdkPixbufCollection *collection, int i);
+static gint gdk_pixbuf_gif_collection_get_pixbuf_width (GdkPixbufCollection *collection, int i);
+static gint gdk_pixbuf_gif_collection_get_pixbuf_height (GdkPixbufCollection *collection, int i);
+static gint gdk_pixbuf_gif_collection_get_pixbuf_depth (GdkPixbufCollection *collection, int i);
+static GdkPixbuf *gdk_pixbuf_gif_collection_get_static_image (GdkPixbufCollection *collection);
+
+
+static gpointer collection_parent_class;
+
+GType
+gdk_pixbuf_gif_collection_get_type (void)
+{
+        static GType object_type = 0;
+
+        if (!object_type) {
+                static const GTypeInfo object_info = {
+                        sizeof (GdkPixbufGifCollectionClass),
+                        (GBaseInitFunc) NULL,
+                        (GBaseFinalizeFunc) NULL,
+                        (GClassInitFunc) gdk_pixbuf_gif_collection_class_init,
+                        NULL,           /* class_finalize */
+                        NULL,           /* class_data */
+                        sizeof (GdkPixbufGifCollection),
+                        0,              /* n_preallocs */
+                        (GInstanceInitFunc) NULL,
+                };
+                
+                object_type = g_type_register_static (GDK_TYPE_PIXBUF_COLLECTION,
+                                                      "GdkPixbufGifCollection",
+                                                      &object_info, 0);
+        }
+        
+        return object_type;
+}
+
+static void
+gdk_pixbuf_gif_collection_class_init (GdkPixbufGifCollectionClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+        GdkPixbufCollectionClass *collection_class =
+                GDK_PIXBUF_COLLECTION_CLASS (klass);
+        
+        collection_parent_class = g_type_class_peek_parent (klass);
+        
+        object_class->finalize = gdk_pixbuf_gif_collection_finalize;
+
+        collection_class->get_length = gdk_pixbuf_gif_collection_get_length;
+        collection_class->get_pixbuf = gdk_pixbuf_gif_collection_get_pixbuf;
+        collection_class->get_pixbuf_width = gdk_pixbuf_gif_collection_get_pixbuf_width;
+        collection_class->get_pixbuf_height = gdk_pixbuf_gif_collection_get_pixbuf_height;
+        collection_class->get_pixbuf_depth = gdk_pixbuf_gif_collection_get_pixbuf_depth;
+        collection_class->get_static_image = gdk_pixbuf_gif_collection_get_static_image;
+}
+
+static void
+gdk_pixbuf_gif_collection_finalize (GObject *object)
+{
+        GdkPixbufGifCollection *coll = GDK_PIXBUF_GIF_COLLECTION (object);
+
+        g_object_unref (coll->gif_anim);
+        
+        G_OBJECT_CLASS (collection_parent_class)->finalize (object);
+}
+
+static gint 
+gdk_pixbuf_gif_collection_get_length (GdkPixbufCollection *collection)
+{
+        GdkPixbufGifCollection *coll = GDK_PIXBUF_GIF_COLLECTION (collection);
+
+        return coll->gif_anim->n_frames;
+}
+
+static GdkPixbuf *
+gdk_pixbuf_gif_collection_get_pixbuf (GdkPixbufCollection *collection, int i)
+{
+        int k;
+        GdkPixbufGifCollection *coll = GDK_PIXBUF_GIF_COLLECTION (collection);
+        GList *l;
+        GdkPixbufFrame *frame;
+
+        l = coll->gif_anim->frames;
+        for (k = 0; k < i; k++) {
+                l = l->next;
+        }
+        frame = l->data;
+
+        gdk_pixbuf_gif_anim_frame_composite (coll->gif_anim, frame);
+
+        return frame->composited;
+}
+
+static gint gdk_pixbuf_gif_collection_get_pixbuf_width (GdkPixbufCollection *collection, int i) 
+{
+        GdkPixbuf *pixbuf;
+
+        pixbuf = gdk_pixbuf_gif_collection_get_pixbuf (collection, i);
+
+        return gdk_pixbuf_get_width (pixbuf);
+}
+
+static gint gdk_pixbuf_gif_collection_get_pixbuf_height (GdkPixbufCollection *collection, int i)
+{
+        GdkPixbuf *pixbuf;
+
+        pixbuf = gdk_pixbuf_gif_collection_get_pixbuf (collection, i);
+
+        return gdk_pixbuf_get_height (pixbuf);
+}
+
+static gint gdk_pixbuf_gif_collection_get_pixbuf_depth (GdkPixbufCollection *collection, int i)
+{
+        GdkPixbuf *pixbuf;
+
+        pixbuf = gdk_pixbuf_gif_collection_get_pixbuf (collection, i);
+
+        return gdk_pixbuf_get_bits_per_sample (pixbuf) * gdk_pixbuf_get_n_channels (pixbuf);
+}
+
+static GdkPixbuf *
+gdk_pixbuf_gif_collection_get_static_image (GdkPixbufCollection *collection)
+{
+        GdkPixbufGifCollection *coll = GDK_PIXBUF_GIF_COLLECTION (collection);
+        
+        return gdk_pixbuf_animation_get_static_image (coll->gif_anim);
+}
+
diff -uN gdk-pixbuf.orig/io-gif-collection.h gdk-pixbuf/io-gif-collection.h
--- gdk-pixbuf.orig/io-gif-collection.h	Thu Jan  1 01:00:00 1970
+++ gdk-pixbuf/io-gif-collection.h	Mon Sep  9 23:00:17 2002
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GdkPixbuf library - GIF loader declarations
+ *
+ * Copyright (C) 2002 The Free Software Foundation
+ *
+ * Author: Matthias Clasen <maclas@gmx.de>
+ *
+ * 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.
+ */
+
+#ifndef GDK_PIXBUF_GIF_COLLECTION_H
+#define GDK_PIXBUF_GIF_COLLECTION_H
+
+#include "gdk-pixbuf-private.h"
+#include "io-gif-animation.h"
+
+typedef struct _GdkPixbufGifCollection GdkPixbufGifCollection;
+typedef struct _GdkPixbufGifCollectionClass GdkPixbufGifCollectionClass;
+
+#define GDK_TYPE_PIXBUF_GIF_COLLECTION              (gdk_pixbuf_gif_collection_get_type ())
+#define GDK_PIXBUF_GIF_COLLECTION(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_GIF_COLLECTION, GdkPixbufGifCollection))
+#define GDK_IS_PIXBUF_GIF_COLLECTION(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_GIF_COLLECTION))
+
+#define GDK_PIXBUF_GIF_COLLECTION_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_GIF_COLLECTION, GdkPixbufGifCollectionClass))
+#define GDK_IS_PIXBUF_GIF_COLLECTION_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_GIF_COLLECTION))
+#define GDK_PIXBUF_GIF_COLLECTION_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_GIF_COLLECTION, GdkPixbufGifCollectionClass))
+
+struct _GdkPixbufGifCollection {
+        GdkPixbufCollection parent_instance;
+        
+        GdkPixbufGifAnim   *gif_anim;
+};
+
+struct _GdkPixbufGifCollectionClass {
+        GdkPixbufCollectionClass parent_class;
+};
+
+GType gdk_pixbuf_gif_collection_get_type (void) G_GNUC_CONST;
+
+#endif
+
diff -uN gdk-pixbuf.orig/io-gif.c gdk-pixbuf/io-gif.c
--- gdk-pixbuf.orig/io-gif.c	Sun Jul  7 01:10:45 2002
+++ gdk-pixbuf/io-gif.c	Tue Sep 10 21:32:24 2002
@@ -60,6 +60,7 @@
 #include "gdk-pixbuf-private.h"
 #include "gdk-pixbuf-io.h"
 #include "io-gif-animation.h"
+#include "io-gif-collection.h"
 
 
 
@@ -821,10 +822,15 @@
 
                 /* Only call prepare_func for the first frame */
 		if (context->animation->frames->next == NULL) { 
-                        if (context->prepare_func)
+                        if (context->prepare_func) {
+                                GdkPixbufCollection *collection = 
+                                        _gdk_pixbuf_gif_anim_get_collection (GDK_PIXBUF_ANIMATION (context->animation));
                                 (* context->prepare_func) (context->frame->pixbuf,
                                                            GDK_PIXBUF_ANIMATION (context->animation),
+                                                           collection,
                                                            context->user_data);
+                                g_object_unref (collection);
+                        }
                 } else {
                         /* Otherwise init frame with last frame */
                         GList *link;
diff -uN gdk-pixbuf.orig/io-ico-collection.c gdk-pixbuf/io-ico-collection.c
--- gdk-pixbuf.orig/io-ico-collection.c	Thu Jan  1 01:00:00 1970
+++ gdk-pixbuf/io-ico-collection.c	Tue Sep 10 21:33:26 2002
@@ -0,0 +1,154 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GdkPixbuf library - ICO support
+ *
+ * Copyright (C) 2002 The Free Software Foundation
+ *
+ * Author: Matthias Clasen <maclas@gmx.de>
+ *
+ * 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.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include "gdk-pixbuf-io.h"
+#include "gdk-pixbuf-private.h"
+#include "io-ico-collection.h"
+
+
+static void gdk_pixbuf_ico_collection_class_init (GdkPixbufIcoCollectionClass *klass);
+static void gdk_pixbuf_ico_collection_finalize   (GObject                   *object);
+static gint gdk_pixbuf_ico_collection_get_length (GdkPixbufCollection *collection);
+static GdkPixbuf *gdk_pixbuf_ico_collection_get_pixbuf (GdkPixbufCollection *collection, int i);
+static gint gdk_pixbuf_ico_collection_get_pixbuf_width (GdkPixbufCollection *collection, int i);
+static gint gdk_pixbuf_ico_collection_get_pixbuf_height (GdkPixbufCollection *collection, int i);
+static gint gdk_pixbuf_ico_collection_get_pixbuf_depth (GdkPixbufCollection *collection, int i);
+static GdkPixbuf* gdk_pixbuf_ico_collection_get_static_image (GdkPixbufCollection *collection);
+
+
+static gpointer collection_parent_class;
+
+GType
+gdk_pixbuf_ico_collection_get_type (void)
+{
+        static GType object_type = 0;
+
+        if (!object_type) {
+                static const GTypeInfo object_info = {
+                        sizeof (GdkPixbufIcoCollectionClass),
+                        (GBaseInitFunc) NULL,
+                        (GBaseFinalizeFunc) NULL,
+                        (GClassInitFunc) gdk_pixbuf_ico_collection_class_init,
+                        NULL,           /* class_finalize */
+                        NULL,           /* class_data */
+                        sizeof (GdkPixbufIcoCollection),
+                        0,              /* n_preallocs */
+                        (GInstanceInitFunc) NULL,
+                };
+                
+                object_type = g_type_register_static (GDK_TYPE_PIXBUF_COLLECTION,
+                                                      "GdkPixbufIcoCollection",
+                                                      &object_info, 0);
+        }
+        
+        return object_type;
+}
+
+static void
+gdk_pixbuf_ico_collection_class_init (GdkPixbufIcoCollectionClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+        GdkPixbufCollectionClass *collection_class =
+                GDK_PIXBUF_COLLECTION_CLASS (klass);
+        
+        collection_parent_class = g_type_class_peek_parent (klass);
+        
+        object_class->finalize = gdk_pixbuf_ico_collection_finalize;
+
+        collection_class->get_length = gdk_pixbuf_ico_collection_get_length;
+        collection_class->get_pixbuf = gdk_pixbuf_ico_collection_get_pixbuf;
+        collection_class->get_pixbuf_width = gdk_pixbuf_ico_collection_get_pixbuf_width;
+        collection_class->get_pixbuf_height = gdk_pixbuf_ico_collection_get_pixbuf_height;
+        collection_class->get_pixbuf_depth = gdk_pixbuf_ico_collection_get_pixbuf_depth;
+        collection_class->get_static_image = gdk_pixbuf_ico_collection_get_static_image;
+}
+
+static void
+gdk_pixbuf_ico_collection_finalize (GObject *object)
+{
+        GdkPixbufIcoCollection *coll = GDK_PIXBUF_ICO_COLLECTION (object);
+        int i;
+
+        for (i = 0; i < coll->n_pixbufs; i++)
+                if (coll->pixbufs[i])
+                        g_object_unref (coll->pixbufs[i]);
+
+        g_free (coll->pixbufs);
+        g_free (coll->depth);
+        
+        G_OBJECT_CLASS (collection_parent_class)->finalize (object);
+}
+
+static gint 
+gdk_pixbuf_ico_collection_get_length (GdkPixbufCollection *collection)
+{
+        GdkPixbufIcoCollection *coll = GDK_PIXBUF_ICO_COLLECTION (collection);
+
+        return coll->n_pixbufs;
+}
+
+static GdkPixbuf *
+gdk_pixbuf_ico_collection_get_pixbuf (GdkPixbufCollection *collection, int i)
+{
+        GdkPixbufIcoCollection *coll = GDK_PIXBUF_ICO_COLLECTION (collection);
+
+        return coll->pixbufs[i];
+}
+
+static gint gdk_pixbuf_ico_collection_get_pixbuf_width (GdkPixbufCollection *collection, int i) 
+{
+        GdkPixbuf *pixbuf;
+
+        pixbuf = gdk_pixbuf_ico_collection_get_pixbuf (collection, i);
+
+        return gdk_pixbuf_get_width (pixbuf);
+}
+
+static gint gdk_pixbuf_ico_collection_get_pixbuf_height (GdkPixbufCollection *collection, int i)
+{
+        GdkPixbuf *pixbuf;
+
+        pixbuf = gdk_pixbuf_ico_collection_get_pixbuf (collection, i);
+
+        return gdk_pixbuf_get_height (pixbuf);
+}
+
+static gint gdk_pixbuf_ico_collection_get_pixbuf_depth (GdkPixbufCollection *collection, int i)
+{
+        GdkPixbufIcoCollection *coll = GDK_PIXBUF_ICO_COLLECTION (collection);
+
+        return coll->depth[i];
+}
+
+static GdkPixbuf *
+gdk_pixbuf_ico_collection_get_static_image (GdkPixbufCollection *collection)
+{
+        GdkPixbufIcoCollection *coll = GDK_PIXBUF_ICO_COLLECTION (collection);
+        
+        return gdk_pixbuf_ico_collection_get_pixbuf (collection, coll->preferred);
+}
+
+
+
diff -uN gdk-pixbuf.orig/io-ico-collection.h gdk-pixbuf/io-ico-collection.h
--- gdk-pixbuf.orig/io-ico-collection.h	Thu Jan  1 01:00:00 1970
+++ gdk-pixbuf/io-ico-collection.h	Mon Sep  9 23:05:01 2002
@@ -0,0 +1,58 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GdkPixbuf library - ICO loader declarations
+ *
+ * Copyright (C) 2002 The Free Software Foundation
+ *
+ * Author: Matthias Clasen <maclas@gmx.de>
+ *
+ * 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.
+ */
+
+#ifndef GDK_PIXBUF_ICO_COLLECTION_H
+#define GDK_PIXBUF_ICO_COLLECTION_H
+
+#include "gdk-pixbuf-private.h"
+
+typedef struct _GdkPixbufIcoCollection GdkPixbufIcoCollection;
+typedef struct _GdkPixbufIcoCollectionClass GdkPixbufIcoCollectionClass;
+
+#define GDK_TYPE_PIXBUF_ICO_COLLECTION              (gdk_pixbuf_ico_collection_get_type ())
+#define GDK_PIXBUF_ICO_COLLECTION(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_ICO_COLLECTION, GdkPixbufIcoCollection))
+#define GDK_IS_PIXBUF_ICO_COLLECTION(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_ICO_COLLECTION))
+
+#define GDK_PIXBUF_ICO_COLLECTION_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_ICO_COLLECTION, GdkPixbufIcoCollectionClass))
+#define GDK_IS_PIXBUF_ICO_COLLECTION_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_ICO_COLLECTION))
+#define GDK_PIXBUF_ICO_COLLECTION_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_ICO_COLLECTION, GdkPixbufIcoCollectionClass))
+
+struct _GdkPixbufIcoCollection {
+        GdkPixbufCollection parent_instance;
+        
+        gint n_pixbufs;
+
+        GdkPixbuf **pixbufs;
+
+        gint *depth;
+
+        gint preferred;
+};
+
+struct _GdkPixbufIcoCollectionClass {
+        GdkPixbufCollectionClass parent_class;
+};
+
+GType gdk_pixbuf_ico_collection_get_type (void) G_GNUC_CONST;
+
+#endif
diff -uN gdk-pixbuf.orig/io-ico.c gdk-pixbuf/io-ico.c
--- gdk-pixbuf.orig/io-ico.c	Fri Sep  6 23:09:49 2002
+++ gdk-pixbuf/io-ico.c	Tue Sep 10 22:02:17 2002
@@ -1,3 +1,4 @@
+/* -*- mode: C; c-file-style: "linux" -*- */
 /* GdkPixbuf library - Windows Icon/Cursor image loader
  *
  * Copyright (C) 1999 The Free Software Foundation
@@ -41,6 +42,7 @@
 #include <string.h>
 #include "gdk-pixbuf-private.h"
 #include "gdk-pixbuf-io.h"
+#include "io-ico-collection.h"
 #include <errno.h>
 
 
@@ -147,16 +149,19 @@
 				   1  = 1 bit bitonal 
 				 */
         gboolean cursor;
-        gint x_hot;
-        gint y_hot;
-
+	
 	struct headerpair Header;	/* Decoded (BE->CPU) header */
 	
-	gint			DIBoffset;
-	gint			ImageScore;
+	gint *DIBoffset;
+	gint *x_hot;
+	gint *y_hot;
 
+	gint ImageScore;
+	gint total;
+	
+	gint pos;
 
-	GdkPixbuf *pixbuf;	/* Our "target" */
+	GdkPixbufIcoCollection *collection;
 };
 
 static gpointer
@@ -175,13 +180,17 @@
 {
 	if (context->LineBuf != NULL)
 		g_free (context->LineBuf);
-	context->LineBuf = NULL;
+
 	if (context->HeaderBuf != NULL)
 		g_free (context->HeaderBuf);
 
-	if (context->pixbuf)
-		g_object_unref (context->pixbuf);
+	if (context->collection)
+		g_object_unref (context->collection);
 
+	g_free (context->DIBoffset);
+	g_free (context->x_hot);
+	g_free (context->y_hot);
+	
 	g_free (context);
 }
 
@@ -194,22 +203,59 @@
      1) The one with the highest number of colors
      2) The largest one
  */   
- 
-	gint IconCount = 0; /* The number of icon-versions in the file */
-	guchar *BIH; /* The DIB for the used icon */
  	guchar *Ptr;
  	gint I;
- 
+
  	/* Step 1: The ICO header */
+	if (!State->collection) {
+		gint length = (Data[5] << 8) + (Data[4]);
+				
+		if (length >= 1024) {
+			g_set_error (error,
+				     GDK_PIXBUF_ERROR,
+				     GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+				     _("Invalid header in collection"));
+			return;
+		}
 
-	State->cursor = ((Data[3] << 8) + Data[2] == 2) ? TRUE : FALSE;
+		State->collection = g_object_new (GDK_TYPE_PIXBUF_ICO_COLLECTION, NULL);
+		if (!State->collection) 
+		{
+			g_set_error (error,
+				     GDK_PIXBUF_ERROR,
+				     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+				     _("Not enough memory to load collection"));
+			return;
+		}
 
- 	IconCount = (Data[5] << 8) + (Data[4]);
-	
- 	State->HeaderSize = 6 + IconCount*16;
+		State->collection->n_pixbufs = length;
 
- 	if (State->HeaderSize>State->BytesInHeaderBuf) {
- 		guchar *tmp=g_try_realloc(State->HeaderBuf,State->HeaderSize);
+		State->HeaderSize = 6 + length*16;
+
+		State->cursor = ((Data[3] << 8) + Data[2] == 2) ? TRUE : FALSE;
+
+		State->collection->pixbufs = (GdkPixbuf**) g_try_malloc (sizeof(GdkPixbuf*) * length);
+		State->collection->depth = (gint*) g_try_malloc (sizeof(gint*) * length);
+		State->DIBoffset = (gint*) g_try_malloc (sizeof (gint) * length);
+		State->x_hot = (gint*) g_try_malloc (sizeof (gint) * length);
+		State->y_hot = (gint*) g_try_malloc (sizeof (gint) * length);
+		if (!State->collection->pixbufs ||
+		    !State->collection->depth ||
+		    !State->DIBoffset || 
+		    !State->x_hot || 
+		    !State->y_hot) {
+			g_set_error (error,
+				     GDK_PIXBUF_ERROR,
+				     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+				     _("Not enough memory to load icon"));
+			return;
+		}
+		memset (State->collection->pixbufs, 0, sizeof (GdkPixbuf*) * length);
+		memset (State->collection->depth, 0, sizeof (gint) * length);
+	}
+	
+ 	if (State->HeaderSize > State->BytesInHeaderBuf) {
+ 		guchar *tmp = g_try_realloc (State->HeaderBuf, State->HeaderSize);
 		if (!tmp) {
 			g_set_error (error,
 				     GDK_PIXBUF_ERROR,
@@ -226,10 +272,9 @@
  	/* We now have all the "short-specs" of the versions 
  	   So we iterate through them and select the best one */
  	   
- 	State->ImageScore = 0;
- 	State->DIBoffset  = 0;
+	State->ImageScore = 0;
  	Ptr = Data + 6;
-	for (I=0;I<IconCount;I++) {
+	for (I=0; I < State->collection->n_pixbufs; I++) {
 		int ThisWidth, ThisHeight,ThisColors;
 		int ThisScore;
 		
@@ -242,32 +287,33 @@
 		ThisScore = ThisColors*1024+ThisWidth*ThisHeight; 
 
 		if (ThisScore>State->ImageScore) {
+			State->collection->preferred = I;
 			State->ImageScore = ThisScore;
-			State->x_hot = (Ptr[5] << 8) + Ptr[4];
-			State->y_hot = (Ptr[7] << 8) + Ptr[6];
-			State->DIBoffset = (Ptr[15]<<24)+(Ptr[14]<<16)+
-					   (Ptr[13]<<8) + (Ptr[12]);
-								 
 		}
-		
-		
+		State->x_hot[I] = (Ptr[5] << 8) + Ptr[4];
+		State->y_hot[I] = (Ptr[7] << 8) + Ptr[6];
+		State->DIBoffset[I] = (Ptr[15]<<24)+(Ptr[14]<<16)+
+			(Ptr[13]<<8) + (Ptr[12]);
+		if (State->DIBoffset[I] < 0) {
+			g_set_error (error,
+				     GDK_PIXBUF_ERROR,
+				     GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+				     _("Invalid header in icon"));
+			return;
+		}
 		Ptr += 16;	
 	} 
+}
 
-	if (State->DIBoffset < 0) {
-		g_set_error (error,
-			     GDK_PIXBUF_ERROR,
-			     GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-			     _("Invalid header in icon"));
-		return;
-	}
 
+static void DecodeIconHeader(guchar *BIH, gint Bytes,
+			     struct ico_progressive_state *State,
+			     GError **error) 
+{
 	/* We now have a winner, pointed to in State->DIBoffset,
 	   so we know how many bytes are in the "header" part. */
-	      
-	State->HeaderSize = State->DIBoffset + 40; /* 40 = sizeof(InfoHeader) */
 	
- 	if (State->HeaderSize>State->BytesInHeaderBuf) {
+	if (State->HeaderSize>State->BytesInHeaderBuf) {
  		guchar *tmp=g_try_realloc(State->HeaderBuf,State->HeaderSize);
 		if (!tmp) {
 			g_set_error (error,
@@ -282,8 +328,6 @@
 	if (Bytes<State->HeaderSize) 
 		return;   
 	
-	BIH = Data+State->DIBoffset;
-
 #ifdef DUMPBIH
 	DumpBIH(BIH);
 #endif	
@@ -308,41 +352,43 @@
 			     _("Icon has zero height"));
 		return;
 	}
-	State->Header.depth = (BIH[15] << 8) + (BIH[14]);
+	if (State->collection->depth[State->pos] == 0) {
+		State->Header.depth = (BIH[15] << 8) + (BIH[14]);
 
-	State->Type = State->Header.depth;	
-	if (State->Lines>=State->Header.height)
-		State->Type = 1; /* The transparency mask is 1 bpp */
-	
-	/* Determine the  palette size. If the header indicates 0, it
-	   is actually the maximum for the bpp. You have to love the
-	   guys who made the spec. */
-	I = (int)(BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) + (BIH[32]);
-	I = I*4;
-	if ((I==0)&&(State->Type==1))
-		I = 2*4;
-	if ((I==0)&&(State->Type==4))
-		I = 16*4;
-	if ((I==0)&&(State->Type==8))
-		I = 256*4;
-	
-	State->HeaderSize+=I;
+		State->collection->depth[State->pos] = State->Header.depth;
+
+		/* Determine the  palette size. If the header indicates 0, it
+		   is actually the maximum for the bpp. You have to love the
+		   guys who made the spec. */
+		int I = (int)(BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) + (BIH[32]);
+		I = I*4;
+		if ((I==0)&&(State->Header.depth==1))
+			I = 2*4;
+		if ((I==0)&&(State->Header.depth==4))
+			I = 16*4;
+		if ((I==0)&&(State->Header.depth==8))
+			I = 256*4;
+		
+		State->HeaderSize+=I;
 	
- 	if (State->HeaderSize>State->BytesInHeaderBuf) {
-	        guchar *tmp=g_try_realloc(State->HeaderBuf,State->HeaderSize);
-		if (!tmp) {
-			g_set_error (error,
+		if (State->HeaderSize>State->BytesInHeaderBuf) {
+			guchar *tmp=g_try_realloc(State->HeaderBuf,State->HeaderSize);
+			if (!tmp) {
+				g_set_error (error,
 				     GDK_PIXBUF_ERROR,
-				     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
-				     _("Not enough memory to load icon"));
-			return;
+					     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+					     _("Not enough memory to load icon"));
+				return;
+			}
+			State->HeaderBuf = tmp;
+			State->BytesInHeaderBuf = State->HeaderSize;
 		}
-		State->HeaderBuf = tmp;
- 		State->BytesInHeaderBuf = State->HeaderSize;
- 	}
- 	if (Bytes < State->HeaderSize)
- 		return;
+		if (Bytes < State->HeaderSize)
+			return;
+	}
 
+	State->Type = State->Header.depth;	
+	
 	if ((BIH[16] != 0) || (BIH[17] != 0) || (BIH[18] != 0)
 	    || (BIH[19] != 0)) {
 		/* FIXME: is this the correct message? */
@@ -402,15 +448,12 @@
 		}
 	}
 
-	g_assert(State->LineBuf != NULL);
-
-
-	if (State->pixbuf == NULL) {
-		State->pixbuf =
+	if (State->collection->pixbufs[State->pos] == NULL) {
+		GdkPixbuf *pixbuf =
 		    gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
 				   State->Header.width,
 				   State->Header.height);
-		if (!State->pixbuf) {
+		if (!pixbuf) {
 			g_set_error (error,
 				     GDK_PIXBUF_ERROR,
 				     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
@@ -419,16 +462,19 @@
 		}
 		if (State->cursor) {
 			gchar hot[10];
-			g_snprintf (hot, 10, "%d", State->x_hot);
-			gdk_pixbuf_set_option (State->pixbuf, "x_hot", hot);
-			g_snprintf (hot, 10, "%d", State->y_hot);
-			gdk_pixbuf_set_option (State->pixbuf, "y_hot", hot);
+			g_snprintf (hot, 10, "%d", State->x_hot[State->pos]);
+			gdk_pixbuf_set_option (pixbuf, "x_hot", hot);
+			g_snprintf (hot, 10, "%d", State->y_hot[State->pos]);
+			gdk_pixbuf_set_option (pixbuf, "y_hot", hot);
 		}
 
+		State->collection->pixbufs[State->pos] = pixbuf;
+
 		if (State->prepared_func != NULL)
 			/* Notify the client that we are ready to go */
-			(*State->prepared_func) (State->pixbuf,
+			(*State->prepared_func) (pixbuf,
                                                  NULL,
+                                                 GDK_PIXBUF_COLLECTION (State->collection),
 						 State->user_data);
 
 	}
@@ -455,9 +501,10 @@
 	context->updated_func = updated_func;
 	context->user_data = user_data;
 
-	context->HeaderSize = 54;
+	context->HeaderSize = 14;
 	context->HeaderBuf = g_try_malloc(14 + 40 + 4*256 + 512);
 	if (!context->HeaderBuf) {
+		g_free (context);
 		g_set_error (error,
 			     GDK_PIXBUF_ERROR,
 			     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
@@ -478,7 +525,7 @@
 	memset(&context->Header, 0, sizeof(struct headerpair));
 
 
-	context->pixbuf = NULL;
+	context->collection = NULL;
 
 
 	return (gpointer) context;
@@ -510,15 +557,16 @@
 {
         gint X;
         guchar *Pixels;
+	GdkPixbuf *pixbuf = context->collection->pixbufs[context->pos];
 
         X = 0;
         if (context->Header.Negative == 0)
-                Pixels = (context->pixbuf->pixels +
-                          context->pixbuf->rowstride *
+                Pixels = (pixbuf->pixels +
+                          pixbuf->rowstride *
                           (context->Header.height - context->Lines - 1));
         else
-                Pixels = (context->pixbuf->pixels +
-                          context->pixbuf->rowstride *
+                Pixels = (pixbuf->pixels +
+                          pixbuf->rowstride *
                           context->Lines);
         while (X < context->Header.width) {
                 Pixels[X * 4 + 0] = context->LineBuf[X * 4 + 2];
@@ -533,15 +581,16 @@
 {
 	gint X;
 	guchar *Pixels;
+	GdkPixbuf *pixbuf = context->collection->pixbufs[context->pos];
 
 	X = 0;
 	if (context->Header.Negative == 0)
-		Pixels = (context->pixbuf->pixels +
-			  context->pixbuf->rowstride *
+		Pixels = (pixbuf->pixels +
+			  pixbuf->rowstride *
 			  (context->Header.height - context->Lines - 1));
 	else
-		Pixels = (context->pixbuf->pixels +
-			  context->pixbuf->rowstride *
+		Pixels = (pixbuf->pixels +
+			  pixbuf->rowstride *
 			  context->Lines);
 	while (X < context->Header.width) {
 		Pixels[X * 4 + 0] = context->LineBuf[X * 3 + 2];
@@ -558,13 +607,14 @@
         int i;
         guchar *pixels;
         guchar *src;
+	GdkPixbuf *pixbuf = context->collection->pixbufs[context->pos];
 
         if (context->Header.Negative == 0)
-                pixels = (context->pixbuf->pixels +
-                          context->pixbuf->rowstride * (context->Header.height - context->Lines - 1));
+                pixels = (pixbuf->pixels +
+                          pixbuf->rowstride * (context->Header.height - context->Lines - 1));
         else
-                pixels = (context->pixbuf->pixels +
-                          context->pixbuf->rowstride * context->Lines);
+                pixels = (pixbuf->pixels +
+                          pixbuf->rowstride * context->Lines);
 
         src = context->LineBuf;
 
@@ -594,24 +644,25 @@
 {
 	gint X;
 	guchar *Pixels;
+	GdkPixbuf *pixbuf = context->collection->pixbufs[context->pos];
 
 	X = 0;
 	if (context->Header.Negative == 0)
-		Pixels = (context->pixbuf->pixels +
-			  context->pixbuf->rowstride *
+		Pixels = (pixbuf->pixels +
+			  pixbuf->rowstride *
 			  (context->Header.height - context->Lines - 1));
 	else
-		Pixels = (context->pixbuf->pixels +
-			  context->pixbuf->rowstride *
+		Pixels = (pixbuf->pixels +
+			  pixbuf->rowstride *
 			  context->Lines);
 	while (X < context->Header.width) {
 		/* The joys of having a BGR byteorder */
 		Pixels[X * 4 + 0] =
-		    context->HeaderBuf[4 * context->LineBuf[X] + 42+context->DIBoffset];
+		    context->HeaderBuf[4 * context->LineBuf[X] + 42];
 		Pixels[X * 4 + 1] =
-		    context->HeaderBuf[4 * context->LineBuf[X] + 41+context->DIBoffset];
+		    context->HeaderBuf[4 * context->LineBuf[X] + 41];
 		Pixels[X * 4 + 2] =
-		    context->HeaderBuf[4 * context->LineBuf[X] + 40+context->DIBoffset];
+		    context->HeaderBuf[4 * context->LineBuf[X] + 40];
 		X++;
 	}
 }
@@ -619,15 +670,16 @@
 {
 	gint X;
 	guchar *Pixels;
+	GdkPixbuf *pixbuf = context->collection->pixbufs[context->pos];
 
 	X = 0;
 	if (context->Header.Negative == 0)
-		Pixels = (context->pixbuf->pixels +
-			  context->pixbuf->rowstride *
+		Pixels = (pixbuf->pixels +
+			  pixbuf->rowstride *
 			  (context->Header.height - context->Lines - 1));
 	else
-		Pixels = (context->pixbuf->pixels +
-			  context->pixbuf->rowstride *
+		Pixels = (pixbuf->pixels +
+			  pixbuf->rowstride *
 			  context->Lines);
 	
 	while (X < context->Header.width) {
@@ -636,20 +688,20 @@
 		Pix = context->LineBuf[X/2];
 
 		Pixels[X * 4 + 0] =
-		    context->HeaderBuf[4 * (Pix>>4) + 42+context->DIBoffset];
+		    context->HeaderBuf[4 * (Pix>>4) + 42];
 		Pixels[X * 4 + 1] =
-		    context->HeaderBuf[4 * (Pix>>4) + 41+context->DIBoffset];
+		    context->HeaderBuf[4 * (Pix>>4) + 41];
 		Pixels[X * 4 + 2] =
-		    context->HeaderBuf[4 * (Pix>>4) + 40+context->DIBoffset];
+		    context->HeaderBuf[4 * (Pix>>4) + 40];
 		X++;
 		if (X<context->Header.width) { 
 			/* Handle the other 4 bit pixel only when there is one */
 			Pixels[X * 4 + 0] =
-			    context->HeaderBuf[4 * (Pix&15) + 42+context->DIBoffset];
+			    context->HeaderBuf[4 * (Pix&15) + 42];
 			Pixels[X * 4 + 1] =
-			    context->HeaderBuf[4 * (Pix&15) + 41+context->DIBoffset];
+			    context->HeaderBuf[4 * (Pix&15) + 41];
 			Pixels[X * 4 + 2] =
-			    context->HeaderBuf[4 * (Pix&15) + 40+context->DIBoffset];
+			    context->HeaderBuf[4 * (Pix&15) + 40];
 			X++;
 		}
 	}
@@ -660,15 +712,16 @@
 {
 	gint X;
 	guchar *Pixels;
+	GdkPixbuf *pixbuf = context->collection->pixbufs[context->pos];
 
 	X = 0;
 	if (context->Header.Negative == 0)
-		Pixels = (context->pixbuf->pixels +
-			  context->pixbuf->rowstride *
+		Pixels = (pixbuf->pixels +
+			  pixbuf->rowstride *
 			  (context->Header.height - context->Lines - 1));
 	else
-		Pixels = (context->pixbuf->pixels +
-			  context->pixbuf->rowstride *
+		Pixels = (pixbuf->pixels +
+			  pixbuf->rowstride *
 			  context->Lines);
 	while (X < context->Header.width) {
 		int Bit;
@@ -687,15 +740,16 @@
 {
 	gint X;
 	guchar *Pixels;
+	GdkPixbuf *pixbuf = context->collection->pixbufs[context->pos];
 
 	X = 0;
 	if (context->Header.Negative == 0)
-		Pixels = (context->pixbuf->pixels +
-			  context->pixbuf->rowstride *
+		Pixels = (pixbuf->pixels +
+			  pixbuf->rowstride *
 			  (2*context->Header.height - context->Lines - 1));
 	else
-		Pixels = (context->pixbuf->pixels +
-			  context->pixbuf->rowstride *
+		Pixels = (pixbuf->pixels +
+			  pixbuf->rowstride *
 			  (context->Lines-context->Header.height));
 	while (X < context->Header.width) {
 		int Bit;
@@ -720,6 +774,7 @@
 
 static void OneLine(struct ico_progressive_state *context)
 {
+	context->total += context->LineDone;
 	context->LineDone = 0;
 	
 	if (context->Lines >= context->Header.height*2) {
@@ -755,10 +810,8 @@
 			context->LineWidth = (context->LineWidth / 4) * 4 + 4;
 			
 	}
-	  
-
 	if (context->updated_func != NULL) {
-		(*context->updated_func) (context->pixbuf,
+		(*context->updated_func) (context->collection->pixbufs[context->pos],
 					  0,
 					  context->Lines % context->Header.height,
 					  context->Header.width,
@@ -766,6 +819,14 @@
 					  context->user_data);
 
 	}
+	if (context->Lines >= context->Header.height * 2) {
+		g_free (context->LineBuf);
+		context->LineBuf = NULL;
+		context->Lines = 0;
+		context->Type = 0;
+		context->pos++;
+	}
+
 }
 
 /*
@@ -773,7 +834,7 @@
  * buf - new image data
  * size - length of new image data
  *
- * append image data onto inrecrementally built output image
+ * append image data onto incrementally built output image
  */
 static gboolean
 gdk_pixbuf__ico_image_load_increment(gpointer data,
@@ -788,7 +849,7 @@
 
 	while (size > 0) {
 		g_assert(context->LineDone >= 0);
-		if (context->HeaderDone < context->HeaderSize) {	/* We still 
+		if (context->ImageScore == 0) {	/* We still 
 									   have headerbytes to do */
 			BytesToCopy =
 			    context->HeaderSize - context->HeaderDone;
@@ -801,18 +862,77 @@
 			size -= BytesToCopy;
 			buf += BytesToCopy;
 			context->HeaderDone += BytesToCopy;
-		} 
+
+			if (context->HeaderDone >= 6) {
+			  GError *decode_err = NULL;
+			  DecodeHeader(context->HeaderBuf,
+				       context->HeaderDone, context, &decode_err);
+			  if (decode_err) {
+			    g_propagate_error (error, decode_err);
+			    return FALSE;
+			  }
+			}
+			if (context->ImageScore > 0) {
+				context->total = context->HeaderDone;
+				context->HeaderDone = 0;
+				context->HeaderSize = 40;
+			}
+		}
+		else if (context->pos >= context->collection->n_pixbufs) {
+			return TRUE;
+		}
+		else if (context->Type == 0) {
+			if (context->total < context->DIBoffset[context->pos]) {
+				BytesToCopy =
+					context->DIBoffset[context->pos] - context->total;
+				if (BytesToCopy > size)
+					BytesToCopy = size;
+				
+				size -= BytesToCopy;
+				buf += BytesToCopy;
+				context->total += BytesToCopy;
+			}
+			if (context->total == context->DIBoffset[context->pos]) {
+				BytesToCopy =
+					context->HeaderSize - context->HeaderDone;
+				if (BytesToCopy > size)
+					BytesToCopy = size;
+				
+				memmove(context->HeaderBuf + context->HeaderDone,
+					buf, BytesToCopy);
+				
+				size -= BytesToCopy;
+				buf += BytesToCopy;
+				context->HeaderDone += BytesToCopy;
+					
+				if (context->HeaderDone >= 40) {
+					GError *decode_err = NULL;
+					DecodeIconHeader(context->HeaderBuf,
+							 context->HeaderDone, context, &decode_err);
+					if (decode_err) {
+						g_propagate_error (error, decode_err);
+						return FALSE;
+					}
+				}
+			}
+			if (context->Type > 0) {
+				context->total += context->HeaderDone;
+				context->HeaderDone = 0;
+				context->HeaderSize = 40;
+			}
+
+		}
 		else {
 			BytesToCopy =
-			    context->LineWidth - context->LineDone;
+				context->LineWidth - context->LineDone;
 			if (BytesToCopy > size)
 				BytesToCopy = size;
-
+			
 			if (BytesToCopy > 0) {
 				memmove(context->LineBuf +
-				       context->LineDone, buf,
-				       BytesToCopy);
-
+					context->LineDone, buf,
+					BytesToCopy);
+				
 				size -= BytesToCopy;
 				buf += BytesToCopy;
 				context->LineDone += BytesToCopy;
@@ -824,24 +944,61 @@
 
 		}
 
-		if (context->HeaderDone >= 6) {
-			GError *decode_err = NULL;
-			DecodeHeader(context->HeaderBuf,
-				     context->HeaderDone, context, &decode_err);
-			if (decode_err) {
-				g_propagate_error (error, decode_err);
-				return FALSE;
-			}
-		}
 	}
 
 	return TRUE;
 }
 
+static void
+prepared_notify (GdkPixbuf *pixbuf, 
+		 GdkPixbufAnimation *anim, 
+		 GdkPixbufCollection *coll, 
+		 gpointer user_data)
+{
+	if (coll != NULL)
+		g_object_ref (coll);
+	*((GdkPixbufCollection **)user_data) = coll;
+}
+
+static GdkPixbufCollection *
+gdk_pixbuf__ico_image_load_collection (FILE *f, GError **error)
+{
+	guchar buffer[4096];
+	size_t length;
+	GdkPixbufCollection *coll = NULL;
+	gpointer context;
+
+	context = gdk_pixbuf__ico_image_begin_load (NULL, prepared_notify, 
+						    NULL, &coll, error);
+	
+	if (!context)
+                return NULL;
+	
+	while (!feof (f)) {
+		length = fread (buffer, 1, sizeof (buffer), f);
+		if (length > 0)
+			if (!gdk_pixbuf__ico_image_load_increment (context, buffer, length, error)) {
+				gdk_pixbuf__ico_image_stop_load (context, NULL);
+				if (coll != NULL)
+					g_object_unref (coll);
+				return NULL;
+			}
+	}
+
+	if (!gdk_pixbuf__ico_image_stop_load (context, error)) {
+		if (coll != NULL)
+			g_object_unref (coll);
+		return NULL;
+	}
+	
+	return coll;
+}
+
 void
 gdk_pixbuf__ico_fill_vtable (GdkPixbufModule *module)
 {
-  module->begin_load = gdk_pixbuf__ico_image_begin_load;
-  module->stop_load = gdk_pixbuf__ico_image_stop_load;
-  module->load_increment = gdk_pixbuf__ico_image_load_increment;
+        module->load_collection = gdk_pixbuf__ico_image_load_collection;
+	module->begin_load = gdk_pixbuf__ico_image_begin_load;
+	module->stop_load = gdk_pixbuf__ico_image_stop_load;
+	module->load_increment = gdk_pixbuf__ico_image_load_increment;
 }
diff -uN gdk-pixbuf.orig/io-jpeg.c gdk-pixbuf/io-jpeg.c
--- gdk-pixbuf.orig/io-jpeg.c	Sun Jul  7 01:10:45 2002
+++ gdk-pixbuf/io-jpeg.c	Sun Sep  8 02:41:44 2002
@@ -679,6 +679,7 @@
 			/* Notify the client that we are ready to go */
 			(* context->prepared_func) (context->pixbuf,
                                                     NULL,
+						    NULL,
 						    context->user_data);
 			
 		} else if (!context->did_prescan) {
diff -uN gdk-pixbuf.orig/io-png.c gdk-pixbuf/io-png.c
--- gdk-pixbuf.orig/io-png.c	Thu Aug 22 23:32:06 2002
+++ gdk-pixbuf/io-png.c	Sun Sep  8 02:41:21 2002
@@ -626,7 +626,7 @@
         /* Notify the client that we are ready to go */
 
         if (lc->prepare_func)
-                (* lc->prepare_func) (lc->pixbuf, NULL, lc->notify_user_data);
+                (* lc->prepare_func) (lc->pixbuf, NULL, NULL, lc->notify_user_data);
         
         return;
 }
diff -uN gdk-pixbuf.orig/io-pnm.c gdk-pixbuf/io-pnm.c
--- gdk-pixbuf.orig/io-pnm.c	Sun Jul  7 01:10:45 2002
+++ gdk-pixbuf/io-pnm.c	Sun Sep  8 02:47:02 2002
@@ -998,6 +998,7 @@
 			/* Notify the client that we are ready to go */
 			(* context->prepared_func) (context->pixbuf,
 						    NULL,
+						    NULL,
 						    context->user_data);
 		}
 		
diff -uN gdk-pixbuf.orig/io-ras.c gdk-pixbuf/io-ras.c
--- gdk-pixbuf.orig/io-ras.c	Tue Jul 16 19:32:08 2002
+++ gdk-pixbuf/io-ras.c	Sun Sep  8 02:45:38 2002
@@ -194,6 +194,7 @@
 			/* Notify the client that we are ready to go */
 			(*State->prepared_func) (State->pixbuf,
                                                  NULL,
+						 NULL,
 						 State->user_data);
 
 	}
diff -uN gdk-pixbuf.orig/io-tga.c gdk-pixbuf/io-tga.c
--- gdk-pixbuf.orig/io-tga.c	Wed Sep  4 01:43:21 2002
+++ gdk-pixbuf/io-tga.c	Sun Sep  8 02:48:03 2002
@@ -795,7 +795,7 @@
 		}
 	}
 	if (!ctx->prepared) {
-		(*ctx->pfunc) (ctx->pbuf, NULL, ctx->udata);
+		(*ctx->pfunc) (ctx->pbuf, NULL, NULL, ctx->udata);
 		ctx->prepared = TRUE;
 	}
 	/* We shouldn't get here anyway. */
diff -uN gdk-pixbuf.orig/io-tiff.c gdk-pixbuf/io-tiff.c
--- gdk-pixbuf.orig/io-tiff.c	Sun Jul  7 01:10:45 2002
+++ gdk-pixbuf/io-tiff.c	Sun Sep  8 02:46:38 2002
@@ -249,7 +249,7 @@
 
         G_UNLOCK (tiff_loader);
 	if (context)
-		(* context->prepare_func) (pixbuf, NULL, context->user_data);
+		(* context->prepare_func) (pixbuf, NULL, NULL, context->user_data);
         G_LOCK (tiff_loader);
                 
         if (!TIFFRGBAImageBegin (&img, tiff, 1, emsg) || global_error) {
diff -uN gdk-pixbuf.orig/io-wbmp.c gdk-pixbuf/io-wbmp.c
--- gdk-pixbuf.orig/io-wbmp.c	Sun Jul  7 22:29:48 2002
+++ gdk-pixbuf/io-wbmp.c	Sun Sep  8 02:47:21 2002
@@ -277,7 +277,7 @@
 
 
 		    if(context->prepared_func)
-		      context->prepared_func(context->pixbuf, NULL, context->user_data);
+		      context->prepared_func(context->pixbuf, NULL, NULL, context->user_data);
 		  }
 	      }
 	    else if(context->needmore)
diff -uN gdk-pixbuf.orig/io-xbm.c gdk-pixbuf/io-xbm.c
--- gdk-pixbuf.orig/io-xbm.c	Fri Sep  6 23:09:49 2002
+++ gdk-pixbuf/io-xbm.c	Sun Sep  8 02:47:39 2002
@@ -307,7 +307,7 @@
 	row_stride = gdk_pixbuf_get_rowstride (pixbuf);
 
 	if (context)
-		(* context->prepare_func) (pixbuf, NULL, context->user_data);
+		(* context->prepare_func) (pixbuf, NULL, NULL, context->user_data);
 
 
 	/* Initialize PIXBUF */
diff -uN gdk-pixbuf.orig/io-xpm.c gdk-pixbuf/io-xpm.c
--- gdk-pixbuf.orig/io-xpm.c	Fri Sep  6 23:09:49 2002
+++ gdk-pixbuf/io-xpm.c	Sun Sep  8 02:46:17 2002
@@ -1474,6 +1474,7 @@
                if (pixbuf != NULL) {
                        (* context->prepare_func) (pixbuf,
                                                   NULL,
+						  NULL,
                                                   context->user_data);
                        (* context->update_func) (pixbuf, 0, 0, pixbuf->width, pixbuf->height, context->user_data);
                        g_object_unref (pixbuf);
