Index: gdk-pixbuf/gdk-pixbuf-scaled-anim.c
===================================================================
--- gdk-pixbuf/gdk-pixbuf-scaled-anim.c	(revision 19976)
+++ gdk-pixbuf/gdk-pixbuf-scaled-anim.c	(working copy)
@@ -117,6 +117,52 @@
 	return gdk_pixbuf_animation_is_static_image (scaled->anim);
 }	
 
+static int
+int_sqrt (int n)
+{
+	int a;
+	for (a=0; n >= (2*a)+1; n -= (2*a++)+1);
+	return a;
+}
+
+static GdkPixbuf*           
+safe_scale (const GdkPixbuf *src, 
+            int              dest_width, 
+            int              dest_height, 
+            GdkInterpType    interp_type) 
+{ 
+	GdkPixbuf* pixbuf_stage1; 
+	GdkPixbuf* pixbuf_stage2; 
+	int        x_ratio, y_ratio, max_ratio, two_step_ratio; 
+	int        temp_width, temp_height; 
+ 
+	g_assert (dest_width > 0); 
+	g_assert (dest_height > 0); 
+ 
+	x_ratio = gdk_pixbuf_get_width (src) / dest_width; 
+	y_ratio = gdk_pixbuf_get_height (src) / dest_height; 
+ 
+	/* The gdk_pixbuf scaling routines do not handle large-ratio downscaling 
+	   very well. Memory usage explodes and the application may freeze or crash. 
+	   For scale-down ratios in excess of 64, do the scale in two equal steps. 
+	   It is faster and safer that way. See bug 80925 for background info. */ 
+ 
+	max_ratio = MAX (x_ratio, y_ratio);
+
+	if (max_ratio > 64) {
+		two_step_ratio = int_sqrt (max_ratio);
+	        temp_width = two_step_ratio * dest_width; 
+		temp_height = two_step_ratio * dest_height; 
+		pixbuf_stage1 = gdk_pixbuf_scale_simple (src, temp_width, temp_height, interp_type); 
+		pixbuf_stage2 = gdk_pixbuf_scale_simple (pixbuf_stage1, dest_width, dest_height, interp_type); 
+		g_object_unref (pixbuf_stage1); 
+	} else 
+		pixbuf_stage2 = gdk_pixbuf_scale_simple (src, dest_width, dest_height, interp_type);
+
+	return pixbuf_stage2;
+}
+
+
 static GdkPixbuf *
 get_scaled_pixbuf (GdkPixbufScaledAnim *scaled, 
                    GdkPixbuf           *pixbuf)
@@ -138,10 +184,10 @@
 	options = g_object_get_qdata (G_OBJECT (pixbuf), quark);
 
 	/* Get a new scaled pixbuf */
-	scaled->current  = gdk_pixbuf_scale_simple (pixbuf, 
-			(int) (gdk_pixbuf_get_width (pixbuf) * scaled->xscale + .5),
-			(int) (gdk_pixbuf_get_height (pixbuf) * scaled->yscale + .5),
-			GDK_INTERP_BILINEAR);
+	scaled->current  = safe_scale (pixbuf, 
+				       (int) (gdk_pixbuf_get_width (pixbuf) * scaled->xscale + .5),
+				       (int) (gdk_pixbuf_get_height (pixbuf) * scaled->yscale + .5),
+				       GDK_INTERP_BILINEAR);
 
 	/* Copy the original pixbuf options to the scaled pixbuf */
         if (options && scaled->current)
