This Gimp patch of the animationplay.c plugin allows zooming of the
preview bitmap -- ONLY in RGB mode, and not the shaped preview.  It
also adds a `Combine' checkbox, and defaults the clear method to
replace (rather than combine).

TODOs:
  * shape_preview zooming
  * grayscale/indexed bitmap zooming
  * auto-resize window when zoom factor changes
  * From: frame To: frame support

--- animationplay.c.old	Wed Apr 29 20:47:59 1998
+++ animationplay.c	Sat May 13 14:32:22 2000
@@ -124,6 +124,10 @@
 			      gpointer   data);
 static void step_callback  (GtkWidget *widget,
 			    gpointer   data);
+static void zoom_callback  (GtkWidget *widget,
+			    GtkSpinButton *spin);
+static void combine_callback  (GtkWidget *widget,
+			       gpointer   data);
 
 static DisposeType  get_frame_disposal  (guint whichframe);
 static void         render_frame        (gint32 whichframe);
@@ -161,6 +165,8 @@
 GImageType imagetype;
 guchar*    palette;
 gint       ncolours;
+DisposeType dispose = DISPOSE_REPLACE;
+gint	   zoom = 1;
 
 
 
@@ -295,7 +301,7 @@
       offset++;
     }
 
-  return (DISPOSE_UNDEFINED); /* FIXME */
+  return dispose;
 }
 
 
@@ -495,9 +501,12 @@
 
   GtkWidget* dlg;
   GtkWidget* button;
+  GtkAdjustment* adj;
+  GtkWidget* label;
   GtkWidget* frame;
   GtkWidget* frame2;
   GtkWidget* vbox;
+  GtkWidget* vbox2;
   GtkWidget* hbox;
   GtkWidget* hbox2;
   GtkWidget* eventbox;
@@ -574,33 +583,67 @@
 			      TRUE, TRUE, 0);
 	  gtk_widget_show (GTK_WIDGET (progress));
 
-	  hbox2 = gtk_hbox_new (FALSE, 0);
-	  gtk_container_border_width (GTK_CONTAINER (hbox2), 0);
-	  gtk_box_pack_start (GTK_BOX (vbox), hbox2, TRUE, TRUE, 0);
+	  vbox2 = gtk_vbox_new (FALSE, 0);
+	  gtk_container_border_width (GTK_CONTAINER (vbox2), 0);
+	  gtk_box_pack_start (GTK_BOX (vbox), vbox2, TRUE, TRUE, 0);
 	  
 	  {
-	    button = gtk_button_new_with_label ("Play/Stop");
-	    gtk_signal_connect (GTK_OBJECT (button), "clicked",
-				(GtkSignalFunc) playstop_callback, NULL);
-	    gtk_box_pack_start (GTK_BOX (hbox2), button, TRUE, TRUE, 0);
-	    gtk_widget_show (button);
-	    
-	    button = gtk_button_new_with_label ("Rewind");
-	    gtk_signal_connect (GTK_OBJECT (button), "clicked",
-				(GtkSignalFunc) rewind_callback, NULL);
-	    gtk_box_pack_start (GTK_BOX (hbox2), button, TRUE, TRUE, 0);
-	    gtk_widget_show (button);
-	    
-	    button = gtk_button_new_with_label ("Step");
-	    gtk_signal_connect (GTK_OBJECT (button), "clicked",
-				(GtkSignalFunc) step_callback, NULL);
-	    gtk_box_pack_start (GTK_BOX (hbox2), button, TRUE, TRUE, 0);
-	    gtk_widget_show (button);
+	    hbox2 = gtk_hbox_new (FALSE, 0);
+	    gtk_container_border_width (GTK_CONTAINER (hbox2), 0);
+	    gtk_box_pack_start (GTK_BOX (vbox2), hbox2, TRUE, TRUE, 0);
+
+	    {
+	      button = gtk_button_new_with_label ("Play/Stop");
+	      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+				  (GtkSignalFunc) playstop_callback, NULL);
+	      gtk_box_pack_start (GTK_BOX (hbox2), button, TRUE, TRUE, 0);
+	      gtk_widget_show (button);
+	      
+	      button = gtk_button_new_with_label ("Rewind");
+	      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+				  (GtkSignalFunc) rewind_callback, NULL);
+	      gtk_box_pack_start (GTK_BOX (hbox2), button, TRUE, TRUE, 0);
+	      gtk_widget_show (button);
+	      
+	      button = gtk_button_new_with_label ("Step");
+	      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+				  (GtkSignalFunc) step_callback, NULL);
+	      gtk_box_pack_start (GTK_BOX (hbox2), button, TRUE, TRUE, 0);
+	      gtk_widget_show (button);
+	    }
+	    gtk_widget_show (hbox2);
+
+	    hbox2 = gtk_hbox_new (FALSE, 0);
+	    gtk_container_border_width (GTK_CONTAINER (hbox2), 0);
+	    gtk_box_pack_start (GTK_BOX (vbox2), hbox2, TRUE, TRUE, 0);
+
+	    {
+	      label = gtk_label_new ("Zoom: ");
+	      gtk_box_pack_start (GTK_BOX (hbox2), label, TRUE, TRUE, 0);
+	      gtk_widget_show (label);
+	      
+	      adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 16.0, 1.0,
+							  1.0, 0.0);
+
+	      button = gtk_spin_button_new (adj, 0, 0);
+	      gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (button), FALSE);
+	      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+				  (GtkSignalFunc) zoom_callback, GTK_SPIN_BUTTON (button));
+	      gtk_box_pack_start (GTK_BOX (hbox2), button, TRUE, TRUE, 0);
+	      gtk_widget_show (button);
+
+	      button = gtk_check_button_new_with_label ("Combine");
+	      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+				  (GtkSignalFunc) combine_callback, NULL);
+	      gtk_box_pack_start (GTK_BOX (hbox2), button, TRUE, TRUE, 0);
+	      gtk_widget_show (button);
+	    }
+	    gtk_widget_show (hbox2);
 	  }
 	  /* If there aren't multiple frames, playback controls make no
 	     sense */
 	  if (total_frames<=1) gtk_widget_set_sensitive (hbox2, FALSE);
-	  gtk_widget_show(hbox2);
+	  gtk_widget_show(vbox2);
 
 	  hbox2 = gtk_hbox_new (TRUE, 0);
 	  gtk_container_border_width (GTK_CONTAINER (hbox2), 0);
@@ -906,11 +949,26 @@
 	    }
 	  else
 	    {
-	      for (i=0;i<height;i++)
+	      for (i = 0; i < height; i++)
 		{
-		  gtk_preview_draw_row (preview,
-					&preview_data[3*i*width],
-					0, i, width);
+		  guchar row_data[width * 3 * zoom];
+
+		  for (k = 0; k < width; k++) 
+		    {
+		      for (j = k*zoom; j < k*zoom+zoom; j++)
+			{
+			  row_data[j * 3 + 0] = preview_data[3 * (i*width+k) + 0];
+			  row_data[j * 3 + 1] = preview_data[3 * (i*width+k) + 1];
+			  row_data[j * 3 + 2] = preview_data[3 * (i*width+k) + 2];
+			}
+		    }
+
+		  for (j = 0; j < zoom; j++) 
+		    {
+		      gtk_preview_draw_row (preview,
+					    row_data,
+					    0, i*zoom+j, width * zoom);
+		    }
 		}
 	    }
 	}
@@ -1483,3 +1541,20 @@
   show_frame();
 }
 
+static void
+zoom_callback (GtkWidget *widget,
+	       GtkSpinButton *spin)
+{
+  zoom = gtk_spin_button_get_value_as_int (spin);
+  gtk_preview_size (preview, width * zoom, height * zoom);
+}
+
+static void
+combine_callback (GtkWidget *widget,
+		  gpointer   data)
+{
+  if (GTK_TOGGLE_BUTTON (widget)->active)
+    dispose = DISPOSE_COMBINE;
+  else
+    dispose = DISPOSE_REPLACE;
+}

