diff --git a/src/modules/Image/Makefile.in b/src/modules/Image/Makefile.in
index b9645e9fc3612a8dbf756dad43ab542875b86253..4b6060645eeb0d9b0fa6b259a660e95e7d0f8e2d 100644
--- a/src/modules/Image/Makefile.in
+++ b/src/modules/Image/Makefile.in
@@ -1,7 +1,7 @@
 SRCDIR=@srcdir@
 VPATH=@srcdir@:@srcdir@/../..:../..
 OBJS = image.o font.o quant.o lzw.o togif.o matrix.o pnm.o blit.o \
-	pattern.o dct.o operator.o
+	pattern.o dct.o operator.o x.o
 MODNAME=image
 
 @SET_MAKE@
diff --git a/src/modules/Image/image.c b/src/modules/Image/image.c
index 5336ab22a8ddee5cbccddcbc39c2543f7d3701e3..1df8cb65f5daf2bc728ea42070b123e2c6a89e86 100644
--- a/src/modules/Image/image.c
+++ b/src/modules/Image/image.c
@@ -1,4 +1,4 @@
-/* $Id: image.c,v 1.13 1997/03/20 03:26:06 mirar Exp $ */
+/* $Id: image.c,v 1.14 1997/03/20 07:56:56 mirar Exp $ */
 
 #include "global.h"
 
@@ -7,7 +7,7 @@
 
 #include "stralloc.h"
 #include "global.h"
-RCSID("$Id: image.c,v 1.13 1997/03/20 03:26:06 mirar Exp $");
+RCSID("$Id: image.c,v 1.14 1997/03/20 07:56:56 mirar Exp $");
 #include "types.h"
 #include "pike_macros.h"
 #include "object.h"
@@ -1619,251 +1619,6 @@ void image_select_colors(INT32 args)
    colortable_free(ct);
 }
 
-void image_cast(INT32 args)
-{
-  /* CHECK TYPE TO CAST TO HERE! FIXME FIXME FIXME! */
-  pop_n_elems(args);
-  push_string(make_shared_binary_string((char *)THIS->img,
-					THIS->xsize*THIS->ysize
-					*sizeof(rgb_group)));
-}
-
-void image_to8bit_closest(INT32 args)
-{
-  struct colortable *ct;
-  struct pike_string *res = begin_shared_string((THIS->xsize*THIS->ysize));
-  unsigned long i;
-  rgb_group *s;
-  unsigned char *d;
-
-  if(!res) error("Out of memory\n");
-
-  if (args!=1)
-     error("Illegal number of arguments to image->to8bit(COLORTABLE);\n");
-  if(sp[-args].type != T_ARRAY)
-     error("Wrong type to image->to8bit(COLORTABLE);\n");
-
-  ct=colortable_from_array(sp[-args].u.array,"image->to8bit()\n");
-
-  i=THIS->xsize*THIS->ysize;
-  s=THIS->img;
-  d=res->str;
-
-  THREADS_ALLOW();
-  while (i--)
-  {
-    *d=ct->index[colortable_rgb_nearest(ct,*s)];
-    d++; *s++;
-  }
-  THREADS_DISALLOW();
-
-  colortable_free(ct);
-
-  pop_n_elems(args);
-  push_string(end_shared_string(res));
-}
-
-void image_to8bit(INT32 args)
-{
-  struct colortable *ct;
-  struct pike_string *res = begin_shared_string((THIS->xsize*THIS->ysize));
-  unsigned long i;
-  rgb_group *s;
-  unsigned char *d;
-
-  if(!res) error("Out of memory\n");
-
-  if (args!=1)
-     error("Illegal number of arguments to image->to8bit(COLORTABLE);\n");
-  if(sp[-args].type != T_ARRAY)
-     error("Wrong type to image->to8bit(COLORTABLE);\n");
-
-  ct=colortable_from_array(sp[-args].u.array,"image->to8bit()\n");
-
-  i=THIS->xsize*THIS->ysize;
-  s=THIS->img;
-  d=res->str;
-
-  THREADS_ALLOW();
-  while (i--)
-  {
-    *d=ct->index[colortable_rgb(ct,*s)];
-    d++; *s++;
-  }
-  THREADS_DISALLOW();
-
-  colortable_free(ct);
-
-  pop_n_elems(args);
-  push_string(end_shared_string(res));
-}
-
-static void image_to8bit_fs(INT32 args)
-{
-   struct colortable *ct;
-   INT32 i,j,xs;
-   rgb_group *s;
-   struct object *o;
-   int *res,w;
-   unsigned char *d;
-   rgbl_group *errb;
-   struct pike_string *sres = begin_shared_string((THIS->xsize*THIS->ysize));
-   
-   if (!THIS->img) error("no image\n");
-   if (args<1
-       || sp[-args].type!=T_ARRAY)
-      error("illegal argument to image->map_fs()\n");
-
-
-   res=(int*)xalloc(sizeof(int)*THIS->xsize);
-   errb=(rgbl_group*)xalloc(sizeof(rgbl_group)*THIS->xsize);
-      
-   ct=colortable_from_array(sp[-args].u.array,"image->map_closest()\n");
-   pop_n_elems(args);
-
-   for (i=0; i<THIS->xsize; i++)
-      errb[i].r=(rand()%(FS_SCALE*2+1))-FS_SCALE,
-      errb[i].g=(rand()%(FS_SCALE*2+1))-FS_SCALE,
-      errb[i].b=(rand()%(FS_SCALE*2+1))-FS_SCALE;
-
-   i=THIS->ysize;
-   s=THIS->img;
-   d=sres->str;
-   w=0;
-   xs=THIS->xsize;
-   THREADS_ALLOW();
-   while (i--)
-   {
-      image_floyd_steinberg(s,xs,errb,w=!w,res,ct,1);
-      for (j=0; j<THIS->xsize; j++)
-	 *(d++)=ct->index[res[j]];
-      s+=xs;
-   }
-   THREADS_DISALLOW();
-
-   free(errb);
-   free(res);
-   colortable_free(ct);
-   push_string(end_shared_string(sres));
-}
-
-
-static void image_tozbgr(INT32 args)
-{
-   unsigned char *d;
-   rgb_group *s;
-   unsigned long i;
-   struct pike_string *sres = begin_shared_string(THIS->xsize*THIS->ysize*4);
-   
-   if (!THIS->img) error("no image\n");
-   pop_n_elems(args);
-
-   i=THIS->ysize*THIS->xsize;
-   s=THIS->img;
-   d=sres->str;
-
-   THREADS_ALLOW();
-   while (i--)
-   {
-      *(d++)=0;
-      *(d++)=s->b;
-      *(d++)=s->g;
-      *(d++)=s->r;
-      s++;
-   }
-   THREADS_DISALLOW();
-
-   push_string(end_shared_string(sres));
-}
-
-void image_to8bit_rgbcube(INT32 args)
-/*
-
-  ->to8bit_rgbcube(int red,int green,int blue,
-                [string map])
-  
-  gives r+red*g+red*green*b       
- */
-{
-  struct colortable *ct;
-  struct pike_string *res = begin_shared_string((THIS->xsize*THIS->ysize));
-  unsigned long i;
-  rgb_group *s;
-  unsigned char *d;
-  unsigned char *map=NULL;
-
-  int red,green,blue,redgreen,redgreenblue,hred,hgreen,hblue;
-  
-  if(!res) error("Out of memory\n");
-
-  if (!THIS->img) 
-     error("No image\n");
-
-  if (args<3) 
-     error("Too few arguments to image->to8bit_rgbcube()\n");
-  
-  if (sp[-args].type!=T_INT
-      || sp[1-args].type!=T_INT
-      || sp[2-args].type!=T_INT) 
-     error("Illegal argument(s) to image->to8bit_rgbcube()\n");
-
-  red=sp[-args].u.integer; 	hred=red/2;
-  green=sp[1-args].u.integer;	hgreen=green/2;
-  blue=sp[2-args].u.integer; 	hblue=blue/2;
-  redgreen=red*green;
-  redgreenblue=red*green*blue;
-
-  if (args>3)
-     if (sp[3-args].type!=T_STRING)
-	error("Illegal argument 4 to image->to8bit_rgbcube()"
-	      " (expected string or no argument)\n");
-     else if (sp[3-args].u.string->len<red*green*blue)
-	error("map string is not long enough to image->to8bit_rgbcube()\n");
-     else
-	map=sp[3-args].u.string->str;
-
-  i=THIS->xsize*THIS->ysize;
-  s=THIS->img;
-  d=res->str;
-
-  THREADS_ALLOW();
-  if (!map)
-     while (i--)
-     {
-// 	fprintf(stderr,"%02x%02x%02x -> %x,%x,%x -> %d,%d,%d -> %d\n",
-// 		s->r,s->g,s->b,
-// 		s->r*red+hred,
-// 		s->g*green+hgreen,
-// 		s->b*blue+hblue,
-// 		((s->r*red+hred)>>8),
-// 		((s->g*green+hgreen)>>8),
-// 		((s->b*blue+hblue)>>8),
-// 		((s->r*red+hred)>>8)+
-// 		((s->g*green+hgreen)>>8)*red+
-// 		((s->b*blue+hblue)>>8)*redgreen);
-		
-	*(d++)=
-	   (unsigned char)( ((s->r*red+hred)>>8)+
-			    ((s->g*green+hgreen)>>8)*red+
-			    ((s->b*blue+hblue)>>8)*redgreen );
-	s++;
-     }
-  else
-     while (i--)
-     {
-	*(d++)=
-	   map[ ((s->r*red+hred)>>8)+
-	        ((s->g*green+hgreen)>>8)*red+
-	        ((s->b*blue+hblue)>>8)*redgreen ];
-	s++;
-     }
-  THREADS_DISALLOW();
-
-  pop_n_elems(args);
-  push_string(end_shared_string(res));
-}
-
-
 
 /***************** global init etc *****************************/
 
@@ -1949,6 +1704,9 @@ void pike_module_init()
    add_function("paste_alpha_color",image_paste_alpha_color,
 		"function(object,void|int,void|int,void|int,int|void,int|void:object)",0);
 
+   add_function("add_layers",image_add_layers,
+		"function(int|array|void ...:object)",0);
+
    add_function("setcolor",image_setcolor,
 		"function(int,int,int:object)",0);
    add_function("setpixel",image_setpixel,
diff --git a/src/modules/Image/image.h b/src/modules/Image/image.h
index ccedf0df2aa52f6a1353c927943428a81c7043f4..77ba1834b94f483f172568784038430164748b55 100644
--- a/src/modules/Image/image.h
+++ b/src/modules/Image/image.h
@@ -1,4 +1,4 @@
-/* $Id: image.h,v 1.3 1997/03/18 17:23:17 mirar Exp $ */
+/* $Id: image.h,v 1.4 1997/03/20 07:57:00 mirar Exp $ */
 
 #define MAX_NUMCOL 32768
 
@@ -110,6 +110,12 @@ void image_paste_alpha(INT32 args);
 void image_paste_mask(INT32 args);
 void image_paste_alpha_color(INT32 args);
 
+void image_add_layers(INT32 args);
+enum layer_method
+   { LAYER_NOP=0, LAYER_MAX=1, LAYER_MIN=2, 
+     LAYER_MULT=3, LAYER_ADD=4, LAYER_DIFF=5 };
+	 
+
 /* matrix.c */
 
 void image_scale(INT32 args);
@@ -149,3 +155,12 @@ void image_operator_plus(INT32 args);
 void image_operator_multiply(INT32 args);
 void image_operator_maximum(INT32 args);
 void image_operator_minimum(INT32 args);
+void image_cast(INT32 args);
+
+/* x.c */
+
+void image_to8bit_closest(INT32 args);
+void image_to8bit(INT32 args);
+void image_to8bit_fs(INT32 args);
+void image_tozbgr(INT32 args);
+void image_to8bit_rgbcube(INT32 args);