diff --git a/src/modules/Image/colortable.c b/src/modules/Image/colortable.c
index cf0d976eefdf54fdf8db72b24a35b37ac19b76b6..7faadaaab682447a568ad32ad1fb395cfc28d626 100644
--- a/src/modules/Image/colortable.c
+++ b/src/modules/Image/colortable.c
@@ -1,12 +1,12 @@
 #include "global.h"
 #include <config.h>
 
-/* $Id: colortable.c,v 1.61 1999/04/11 12:55:40 mirar Exp $ */
+/* $Id: colortable.c,v 1.62 1999/04/12 13:43:40 mirar Exp $ */
 
 /*
 **! module Image
 **! note
-**!	$Id: colortable.c,v 1.61 1999/04/11 12:55:40 mirar Exp $
+**!	$Id: colortable.c,v 1.62 1999/04/12 13:43:40 mirar Exp $
 **! class colortable
 **!
 **!	This object keeps colortable information,
@@ -21,7 +21,7 @@
 #undef COLORTABLE_DEBUG
 #undef COLORTABLE_REDUCE_DEBUG
 
-RCSID("$Id: colortable.c,v 1.61 1999/04/11 12:55:40 mirar Exp $");
+RCSID("$Id: colortable.c,v 1.62 1999/04/12 13:43:40 mirar Exp $");
 
 #include <math.h> /* fabs() */
 
@@ -44,8 +44,11 @@ RCSID("$Id: colortable.c,v 1.61 1999/04/11 12:55:40 mirar Exp $");
 #include "colortable.h"
 #include "dmalloc.h"
 
+void f_index(INT32);
+
 struct program *image_colortable_program;
 extern struct program *image_program;
+extern struct program *image_color_program;
 
 #define WEIGHT_NEEDED (nct_weight_t)(0x10000000)
 #define WEIGHT_REMOVE (nct_weight_t)(0x10000001)
@@ -2245,9 +2248,16 @@ void image_colortable_create(INT32 args)
 
 /*
 **! method object reduce(int colors)
+**! method object reduce_fs(int colors)
 **!	reduces the number of colors
 **!
 **!	All needed (see <ref>create</ref>) colors are kept.
+**!
+**!	<ref>reduce_fs</ref> creates and keeps 
+**!	the outmost corners of the color space, to 
+**!	improve floyd-steinberg dithering result.
+**!	(It doesn't work very well, though.)
+**!
 **! returns the new <ref>colortable</ref> object
 **!
 **! arg int colors
@@ -2256,21 +2266,22 @@ void image_colortable_create(INT32 args)
 **! note
 **!	this algorithm assumes all colors are different to 
 **!     begin with (!)
+**!	
+**!	<ref>reduce_fs</ref> keeps the "corners" as
+**!	"needed colors".
+**!
+**! see also: corners
 **/
 
 void image_colortable_reduce(INT32 args)
 {
    struct object *o;
    struct neo_colortable *nct;
-   int numcolors;
+   int numcolors=0;
 
    if (args) 
      if (sp[-args].type!=T_INT) 
-     {
-	 error("Illegal argument to Image.colortable->reduce\n");
-	 /* Not reached, but keeps the compiler happy. */
-	 numcolors = 0;
-     } 
+	SIMPLE_BAD_ARG_ERROR("Image.colortable->reduce",1,"int");
      else
 	 numcolors=sp[-args].u.integer;
    else
@@ -2300,6 +2311,47 @@ void image_colortable_reduce(INT32 args)
    push_object(o);
 }
 
+void image_colortable_corners(INT32 args);
+
+void image_colortable_reduce_fs(INT32 args)
+{
+   int numcolors;
+   int i;
+   struct object *o;
+   struct neo_colortable *nct;
+
+   if (args) 
+     if (sp[-args].type!=T_INT) 
+	SIMPLE_BAD_ARG_ERROR("Image.colortable->reduce",1,"int");
+     else
+	numcolors=sp[-args].u.integer;
+   else
+      numcolors=1293791; /* a lot */
+
+   if (numcolors<2)
+      SIMPLE_BAD_ARG_ERROR("Image.colortable->reduce",1,"int(2..)");
+
+   pop_n_elems(args);
+   image_colortable_corners(0);
+
+   if (numcolors<8)
+   {
+      push_int(0);
+      push_int(1);
+      f_index(3);
+   }
+   push_object(o=clone_object(image_colortable_program,1));
+   nct=(struct neo_colortable*)get_storage(o,image_colortable_program);
+   
+   for (i=0; i<nct->u.flat.numentries; i++)
+      nct->u.flat.entries[i].weight=WEIGHT_NEEDED;
+
+   image_colortable_add(1);
+   pop_stack();
+   push_int(numcolors);
+   image_colortable_reduce(1);
+}
+
 
 /*
 **! method object `+(object with,...)
@@ -3631,7 +3683,7 @@ void image_colortable_spacefactors(INT32 args)
 
 /*
 **! method object floyd_steinberg()
-**! method object floyd_steinberg(int dir,int|float forward,int|float downforward,int|float down,int|float downback,int|float factor)
+**! method object floyd_steinberg(int bidir,int|float forward,int|float downforward,int|float down,int|float downback,int|float factor)
 **!	Set dithering method to floyd_steinberg.
 **!	
 **!	The arguments to this method is for fine-tuning of the 
@@ -4258,6 +4310,62 @@ void image_colortable_image(INT32 args)
       free(flat.entries);
 }
 
+/*
+**! method array(object) corners()
+**!	Gives the eight corners in rgb colorspace as an array.
+**!	The "black" and "white" corners are the first two.
+**/
+
+void image_colortable_corners(INT32 args)
+{
+   struct nct_flat flat;
+   int i;
+   rgb_group min={COLORMAX,COLORMAX,COLORMAX};
+   rgb_group max={0,0,0};
+
+   pop_n_elems(args);
+   
+   if (THIS->type==NCT_NONE)
+   {
+      f_aggregate(0);
+      return;
+   }
+
+   if (THIS->type==NCT_CUBE)
+      flat=_img_nct_cube_to_flat(THIS->u.cube);
+   else
+      flat=THIS->u.flat;
+
+   /* sort in number order? */
+
+   for (i=0; i<flat.numentries; i++)
+      if (flat.entries[i].no!=-1)
+      {
+	 rgb_group rgb=flat.entries[i].color;
+	 if (rgb.r<min.r) min.r=rgb.r;
+	 if (rgb.g<min.g) min.g=rgb.g;
+	 if (rgb.b<min.b) min.b=rgb.b;
+	 if (rgb.r>max.r) max.r=rgb.r;
+	 if (rgb.g>max.g) max.g=rgb.g;
+	 if (rgb.b>max.b) max.b=rgb.b;
+      }
+
+   _image_make_rgb_color(min.r,min.g,min.b);
+   _image_make_rgb_color(max.r,max.g,max.b);
+
+   _image_make_rgb_color(max.r,min.g,min.b);
+   _image_make_rgb_color(min.r,max.g,min.b);
+   _image_make_rgb_color(max.r,max.g,min.b);
+   _image_make_rgb_color(min.r,min.g,max.b);
+   _image_make_rgb_color(max.r,min.g,max.b);
+   _image_make_rgb_color(min.r,max.g,max.b);
+
+   f_aggregate(8);
+
+   if (THIS->type==NCT_CUBE)
+      free(flat.entries);
+}
+
 /***************** global init etc *****************************/
 
 void init_colortable_programs(void)
@@ -4285,6 +4393,7 @@ void init_colortable_programs(void)
 
    /* function(int:object) */
    ADD_FUNCTION("reduce",image_colortable_reduce,tFunc(tInt,tObj),0);
+   ADD_FUNCTION("reduce_fs",image_colortable_reduce_fs,tFunc(tInt,tObj),0);
 
    /* operators */
    ADD_FUNCTION("`+",image_colortable_operator_plus,tFunc(tObj,tObj),0);
@@ -4331,6 +4440,8 @@ void init_colortable_programs(void)
    /* function(int,int,int:object) */
    ADD_FUNCTION("spacefactors",image_colortable_spacefactors,tFunc(tInt tInt tInt,tObj),0);
 
+   ADD_FUNCTION("corners",image_colortable_corners,tFunc(,tArray),0);
+
    set_exit_callback(exit_colortable_struct);
   
    image_colortable_program=end_program();