diff --git a/src/modules/Image/encodings/ilbm.c b/src/modules/Image/encodings/ilbm.c
index abdfa438cdcfc68084b71403dd2fddcef57f8b76..c53faa0349b5ef9aa0dc521fb78a7febb5e8d230 100644
--- a/src/modules/Image/encodings/ilbm.c
+++ b/src/modules/Image/encodings/ilbm.c
@@ -1,9 +1,9 @@
-/* $Id: ilbm.c,v 1.5 1999/04/07 17:47:12 marcus Exp $ */
+/* $Id: ilbm.c,v 1.6 1999/04/09 17:09:34 marcus Exp $ */
 
 /*
 **! module Image
 **! note
-**!	$Id: ilbm.c,v 1.5 1999/04/07 17:47:12 marcus Exp $
+**!	$Id: ilbm.c,v 1.6 1999/04/09 17:09:34 marcus Exp $
 **! submodule ILBM
 **!
 **!	This submodule keep the ILBM encode/decode capabilities
@@ -14,7 +14,7 @@
 #include "global.h"
 
 #include "stralloc.h"
-RCSID("$Id: ilbm.c,v 1.5 1999/04/07 17:47:12 marcus Exp $");
+RCSID("$Id: ilbm.c,v 1.6 1999/04/09 17:09:34 marcus Exp $");
 #include "pike_macros.h"
 #include "object.h"
 #include "constants.h"
@@ -516,6 +516,197 @@ void img_ilbm_decode(INT32 args)
    pop_stack();
 }
 
+
+
+/** encoding *****************************************/
+
+/*
+**! method string encode(object image)
+**! method string encode(object image, mapping options)
+**! 	Encodes an ILBM image. 
+**!
+**!     The <tt>options</tt> argument may be a mapping
+**!	containing zero or more encoding options:
+**!
+**!	<pre>
+**!	normal options:
+**!	    "alpha":image object
+**!		Use this image as mask
+**!		(Note: ILBM mask is boolean.
+**!		 The values are calculated by (r+2g+b)/4>=128.)
+**!
+**!	    "palette":colortable object
+**!		Use this as palette for pseudocolor encoding
+**!
+**!	</pre>
+*/
+
+static struct pike_string *make_bmhd(struct BMHD *bmhd)
+{
+  unsigned char bdat[20];
+
+  bdat[0] = (bmhd->w>>8); bdat[1] = bmhd->w&0xff;
+  bdat[2] = (bmhd->h>>8); bdat[3] = bmhd->h&0xff;
+  bdat[4] = (bmhd->x>>8); bdat[5] = bmhd->x&0xff;
+  bdat[6] = (bmhd->y>>8); bdat[7] = bmhd->y&0xff;
+  bdat[8] = bmhd->nPlanes;
+  bdat[9] = bmhd->masking;
+  bdat[10] = bmhd->compression;
+  bdat[11] = bmhd->pad1;
+  bdat[12] = (bmhd->transparentColor>>8); bdat[13]=bmhd->transparentColor&0xff;
+  bdat[14] = bmhd->xAspect;
+  bdat[15] = bmhd->yAspect;
+  bdat[16] = (bmhd->pageWidth>>8); bdat[17] = bmhd->pageWidth&0xff;
+  bdat[18] = (bmhd->pageHeight>>8); bdat[19] = bmhd->pageHeight&0xff;
+
+  return make_shared_binary_string(bdat, 20);
+}
+
+static void chunky2planar(INT32 *src, int w,
+			  unsigned char *dest, int destmod, int depth)
+{
+  int x, p, bit=0x80;
+  for(x=0; x<w; x+=8) {
+    INT32 p0, p1, p2, p3, p4, p5, p6, p7;
+    switch(w-x) {
+    default:
+      p0 = *src++; p1 = *src++; p2 = *src++; p3 = *src++;
+      p4 = *src++; p5 = *src++; p6 = *src++; p7 = *src++; break;
+    case 7:
+      p0 = *src++; p1 = *src++; p2 = *src++; p3 = *src++;
+      p4 = *src++; p5 = *src++; p6 = *src++; p7 = 0; break;
+    case 6:
+      p0 = *src++; p1 = *src++; p2 = *src++; p3 = *src++;
+      p4 = *src++; p5 = *src++; p6 = p7 = 0; break;
+    case 5:
+      p0 = *src++; p1 = *src++; p2 = *src++; p3 = *src++;
+      p4 = *src++; p5 = p6 = p7 = 0; break;
+    case 4:
+      p0 = *src++; p1 = *src++; p2 = *src++; p3 = *src++;
+      p4 = p5 = p6 = p7 = 0; break;
+    case 3:
+      p0 = *src++; p1 = *src++; p2 = *src++;
+      p3 = p4 = p5 = p6 = p7 = 0; break;
+    case 2:
+      p0 = *src++; p1 = *src++; p2 = p3 = p4 = p5 = p6 = p7 = 0; break;
+    case 1:
+      p0 = *src; p1 = p2 = p3 = p4 = p5 = p6 = p7 = 0; break;
+    }
+    for(p=0; p<depth; p++) {
+      dest[p*destmod] =
+	((p0&1)<<7)|((p1&1)<<6)|((p2&1)<<5)|((p3&1)<<4)|
+	((p4&1)<<3)|((p5&1)<<2)|((p6&1)<<1)|(p7&1);
+      p0>>=1; p1>>=1; p2>>=1; p3>>=1;
+      p4>>=1; p5>>=1; p6>>=1; p7>>=1;
+    }
+    dest++;
+  }
+}
+
+static struct pike_string *make_body(struct BMHD *bmhd,
+				     struct image *img, struct image *alpha,
+				     struct neo_colortable *ctable)
+{
+  unsigned int x, y;
+  int rbyt = ((bmhd->w+15)&~15)>>3;
+  int eplanes = (bmhd->masking == mskHasMask? bmhd->nPlanes+1:bmhd->nPlanes);
+  unsigned char *line = alloca(rbyt*eplanes);
+  INT32 *cptr, *cline = alloca((rbyt<<3)*sizeof(INT32));
+  rgb_group *src = img->img;
+  struct string_builder bldr;
+
+  memset(line, 0, rbyt*eplanes);
+  init_string_builder(&bldr, 0);
+  for(y=0; y<bmhd->h; y++) {
+    cptr = cline;
+    if(ctable != NULL)
+    {
+      
+    } else {
+      for(x=0; x<bmhd->w; x++) {
+	/* ILBM-24 */
+	*cptr++ = (src->b<<16)|(src->g<<8)|src->r;
+	src++;
+      }
+    }
+    chunky2planar(cline, bmhd->w, line, rbyt, bmhd->nPlanes);
+    /* compress */
+    string_builder_binary_strcat(&bldr, line, rbyt*eplanes);
+  }
+  return finish_string_builder(&bldr);
+}
+
+static void image_ilbm_encode(INT32 args)
+{
+  struct object *imgo;
+  struct mapping *optm = NULL;
+  struct image *alpha = NULL, *img;
+  struct neo_colortable *ct = NULL;
+  struct pike_string *res;
+  struct BMHD bmhd;
+  int bpp, n = 0;
+
+  extern struct pike_string *make_iff(char *id, struct array *chunks);
+
+  get_all_args("encode", args, (args>1 && !IS_ZERO(&sp[1-args])? "%o%m":"%o"),
+	       &imgo, &optm);
+
+  if((img=(struct image*)get_storage(imgo, image_program))==NULL)
+     error("Image.ILBM.encode: illegal argument 1\n");
+
+  if(optm != NULL) {
+    struct svalue *s;
+    if((s = simple_mapping_string_lookup(optm, "alpha"))!=NULL && !IS_ZERO(s))
+      if(s->type != T_OBJECT ||
+	 (alpha=(struct image*)get_storage(s->u.object, image_program))==NULL)
+	error("Image.ILBM.encode: option (arg 2) \"alpha\" has illegal type\n");
+    if((s=simple_mapping_string_lookup(optm, "palette"))!=NULL && !IS_ZERO(s))
+      if(s->type != T_OBJECT ||
+	 (ct=(struct neo_colortable*)
+	  get_storage(s->u.object, image_colortable_program))==NULL)
+	error("Image.ILBM.encode: option (arg 2) \"palette\" has illegal type\n");
+  }
+
+  if (!img->img)
+    error("Image.ILBM.encode: no image\n");
+  if (alpha && !alpha->img)
+    error("Image.ILBM.encode: no alpha image\n");
+
+  if(ct) {
+    int sz = image_colortable_size(ct);
+    for(bpp=1; (1<<bpp)<sz; bpp++);
+  } else
+    bpp = 24;
+
+  bmhd.w = img->xsize;
+  bmhd.h = img->ysize;
+  bmhd.x = bmhd.y = 0;
+  bmhd.nPlanes = bpp;
+  bmhd.masking = mskNone;
+  bmhd.compression = cmpNone;
+  bmhd.pad1 = 0;
+  bmhd.transparentColor = 0;
+  bmhd.xAspect = bmhd.yAspect = 1;
+  bmhd.pageWidth = img->xsize;
+  bmhd.pageHeight = img->ysize;
+
+  push_svalue(&string_[string_BMHD]);
+  push_string(make_bmhd(&bmhd));
+  f_aggregate(2);
+  n++;
+
+  push_svalue(&string_[string_BODY]);
+  push_string(make_body(&bmhd, img, alpha, ct));
+  f_aggregate(2);
+  n++;
+
+  f_aggregate(n);
+  res = make_iff("ILBM", sp[-1].u.array);
+  pop_n_elems(args+1);
+  push_string(res);
+}
+
+
 /** module *******************************************/
 
 struct program *image_encoding_ilbm_program=NULL;
@@ -539,6 +730,8 @@ void init_image_ilbm(void)
 		"function(string|array:mapping)",0);
    add_function("decode",img_ilbm_decode,
 		"function(string|array:object)",0);
+   add_function("encode",image_ilbm_encode,
+		"function(object,void|mapping(string:mixed):string)",0);
 
    image_encoding_ilbm_program=end_program();
    push_object(clone_object(image_encoding_ilbm_program,0));