diff --git a/src/modules/Image/encodings/_xpm.c b/src/modules/Image/encodings/_xpm.c
index 6cf3b77332bd4cc52e59d974de8ec19230b1074c..0ed6a25ca3648de631d130d9b46445e1e3a5969e 100644
--- a/src/modules/Image/encodings/_xpm.c
+++ b/src/modules/Image/encodings/_xpm.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: _xpm.c,v 1.1 1999/04/06 11:37:17 per Exp $");
+RCSID("$Id: _xpm.c,v 1.2 1999/04/09 04:08:06 per Exp $");
 
 #include "config.h"
 
@@ -51,7 +51,13 @@ static int hextoint( int what )
   return 0;
 }
 
-static rgba_group decode_color( struct pike_string *s )
+struct buffer
+{
+  int len;
+  char *str;
+};
+
+static rgba_group decode_color( struct buffer *s )
 {
   static struct svalue _parse_color;
   static struct svalue *parse_color;
@@ -87,19 +93,21 @@ static rgba_group decode_color( struct pike_string *s )
   }
   if(!parse_color)
   {
-    push_text("Colors");
+    push_text("Image");
     push_int(0);
     SAFE_APPLY_MASTER( "resolv", 2 );
-    if(IS_ZERO(sp-1)) error("Internal error: No Colors module!\n");
-    push_text("parse_color");
+    if(IS_ZERO(sp-1)) error("Internal error: No Image module!\n");
+    push_text("`[]");
     f_index(2);
-    if(IS_ZERO(sp-1)) error("Internal error: No Colors.parse_color function!\n");
+    if(IS_ZERO(sp-1)) error("Internal error: No Image[] function!\n");
     _parse_color = sp[-1];
     parse_color = &_parse_color;
     sp--;
   }
-  ref_push_string( s );
+  push_string(make_shared_binary_string(s->str,s->len));
   apply_svalue( parse_color, 1 );
+  push_text( "array" );
+  apply( sp[-2].u.object, "cast", 1 );
   if(sp[-1].type == T_ARRAY && sp[-1].u.array->size == 3)
   {
     res.r = sp[-1].u.array->item[0].u.integer;
@@ -108,12 +116,40 @@ static rgba_group decode_color( struct pike_string *s )
   } else {
     res.r = res.g = res.b = 0;
   }
-  pop_stack();
+  pop_stack(); /* array */
+  pop_stack(); /* object */
+  return res;
+}
+
+
+static rgba_group parse_color_line( struct pike_string *cn, int sl )
+{
+  int toggle = 0;
+  int i;
+  rgba_group res;
+  for(i=sl; i<cn->len; i++)
+  {
+    switch(cn->str[i])
+    {
+     case ' ':
+     case '\t':
+       if(toggle)
+       {
+         struct buffer s;
+         s.str = cn->str+i+1;
+         s.len = cn->len-i-1;
+         return decode_color(&s);
+       }
+     default:
+       toggle=1;
+    }
+  }
+  res.r = res.g = res.b = 0;
+  res.alpha = 255;
   return res;
 }
 
-static rgba_group qsearch( struct pike_string *s,
-                          struct array *c )
+static rgba_group qsearch( char *s,int sl, struct array *c )
 {
   int start = c->size/2;
   int lower = 0;
@@ -123,14 +159,14 @@ static rgba_group qsearch( struct pike_string *s,
   {
     int i, ok=1;
     cn = c->item[start].u.string;
-    for(i=0; i<s->len; i++)
-      if(cn->str[i] < s->str[i])
+    for(i=0; i<sl; i++)
+      if(cn->str[i] < s[i])
       {
         lower = start;
         start += (upper-start)/2;
         ok=0;
         break;
-      } else if(cn->str[i] > s->str[i]) {
+      } else if(cn->str[i] > s[i]) {
         upper = start;
         start -= (start-lower)/2;
         ok=0;
@@ -138,27 +174,7 @@ static rgba_group qsearch( struct pike_string *s,
       }
 
     if(ok)
-    {
-      int toggle = 0;
-      for(i=s->len; i<cn->len; i++)
-      {
-        switch(cn->str[i])
-        {
-         case ' ':
-         case '\t':
-           if(toggle)
-           {
-             rgba_group res;
-             push_string(make_shared_binary_string(cn->str+i+1,cn->len-i-1));
-             res=decode_color(sp[-1].u.string);
-             pop_stack();
-             return res;
-           }
-         default:
-           toggle=1;
-        }
-      }
-    }
+      return parse_color_line( cn,sl );
     if(upper-lower < 2)
     {
       rgba_group res;
@@ -169,82 +185,97 @@ static rgba_group qsearch( struct pike_string *s,
   }
 }
 
-
-
-static rgba_group mapsearch( struct pike_string *s,
-                            struct mapping *in )
-{
-  struct svalue *res;
-  if((res = low_mapping_string_lookup( in, s )))
-  {
-    switch(res->type)
-    {
-     case T_STRING:
-       return decode_color(res->u.string);
-     case T_MAPPING:
-       if((res = simple_mapping_string_lookup( res->u.mapping, "c" ) ))
-         return decode_color(res->u.string);
-       if((res = simple_mapping_string_lookup( res->u.mapping, "g" ) ))
-         return decode_color(res->u.string);
-       if((res = simple_mapping_string_lookup( res->u.mapping, "g4" ) ))
-         return decode_color(res->u.string);
-       if((res = simple_mapping_string_lookup( res->u.mapping, "m" ) ))
-         return decode_color(res->u.string);
-    }
-  }
-  {
-    rgba_group res;
-    res.r=res.g=res.b=0;
-    res.alpha = 255;
-    return res;
-  }
-}
-
-void f__xpm_write_row( INT32 args )
+void f__xpm_write_rows(  INT32 args )
 {
   struct object *img;
   struct object *alpha;
   struct array *pixels;
-  struct svalue *colors;
+  struct array *colors;
   struct image *iimg, *ialpha;
   rgb_group *dst, *adst;
-  int x, row;
-  get_all_args( "_xpm_write_row", args, "%d%o%o%a%*", &row,
-                &img, &alpha, &pixels,&colors);
+  int y,x,  bpc;
+
+  get_all_args("_xpm_write_rows",args,"%o%o%d%a%a",
+               &img,&alpha,&bpc,&colors,&pixels);
 
   iimg = (struct image *)get_storage( img, image_program );
   ialpha = (struct image *)get_storage( alpha, image_program );
   if(!iimg || !ialpha)
     error("Sluta pilla p� interna saker..\n");
-  if(iimg->xsize != pixels->size ||
-     ialpha->xsize != pixels->size)
-    error("Sluta pilla p� interna saker..\n");
 
-  dst = iimg->img + (iimg->xsize * row);
-  adst = ialpha->img + (ialpha->xsize * row);
+  dst = iimg->img;
+  adst = ialpha->img;
+
+
+  if(bpc > 2)
+  {
+    for(y = 0; y<iimg->ysize; y++)
+    {
+      char *ss = (char *)pixels->item[y+colors->size+1].u.string->str;
+      for(x = 0; x<iimg->xsize; x++)
+      {
+        rgba_group color=qsearch(ss,bpc,colors);  ss+=bpc;
+        dst->r = color.r;
+        dst->g = color.g;
+        (dst++)->b = color.b;
+        if(!color.alpha)
+          adst->r = adst->g = adst->b = color.alpha;
+        adst++;
+      }
+    }
+  } else {
+    rgba_group p_colors[65536];
+    int i;
+
+    for(i=0; i<colors->size; i++)
+    {
+      short id = *((short *)colors->item[i].u.string->str);
+      p_colors[id] = parse_color_line( colors->item[i].u.string, bpc );
+    }
+    for(y = 0; y<iimg->ysize; y++)
+    {
+      char *ss = (char *)pixels->item[y+colors->size+1].u.string->str;
+      for(x = 0; x<iimg->xsize; x++)
+      {
+        rgba_group color=p_colors[*((short *)ss)];
+        dst->r = color.r;
+        dst->g = color.g;
+        (dst++)->b = color.b;
+        if(!color.alpha)
+          adst->r = adst->g = adst->b = 0;
+        ss+=bpc;
+        adst++;
+      }
+    }
+  }
+}
 
-  switch(colors->type)
+void f__xpm_trim_rows( INT32 args )
+{
+  struct array *a;
+  int i,j=0;
+  get_all_args("___", args, "%a", &a );
+  for(i=0; i<a->size; i++)
   {
-   case T_ARRAY:
-     for(x = 0; x<pixels->size; x++)
-     {
-       rgba_group color = qsearch(pixels->item[x].u.string, colors->u.array);
-       dst->r = color.r;
-       dst->g = color.g;
-       (dst++)->b = color.b;
-       adst->r = adst->g = (adst++)->b = color.alpha;
-     }
-     break;
-   case T_MAPPING:
-     for(x = 0; x<pixels->size; x++)
-     {
-       rgba_group color = mapsearch(pixels->item[x].u.string, colors->u.mapping);
-       dst->r = color.r;
-       dst->g = color.g;
-       dst->b = color.b;
-       adst->r = adst->g = adst->b = color.alpha;
-     }
-     break;
+    char *ns;
+    int len,start;
+    struct pike_string *s = a->item[i].u.string;
+    if(s->len > 4)
+    {
+      for(start=0; start<s->len; start++)
+        if(s->str[start] == '/' || s->str[start] == '"')
+          break;
+      if(s->str[start] == '/')
+        continue;
+      for(len=start+1; len<s->len; len++)
+        if(s->str[len] == '"')
+          break;
+      if(len>=s->len || s->str[len] != '"')
+        continue;
+      a->item[j].u.string=make_shared_binary_string(s->str+start+1,len-start-1);
+      free_string(s);
+      j++;
+    }
   }
 }
 
@@ -252,7 +283,8 @@ static struct program *image_encoding__xpm_program=NULL;
 void init_image__xpm( )
 {
   start_new_program();
-  add_function( "_xpm_write_row", f__xpm_write_row, "function(mixed...:void)", 0);
+   add_function( "_xpm_write_rows", f__xpm_write_rows, "mixed", 0); 
+  add_function( "_xpm_trim_rows", f__xpm_trim_rows, "mixed", 0);
   image_encoding__xpm_program=end_program();
 
   push_object(clone_object(image_encoding__xpm_program,0));