diff --git a/lib/modules/_Image_XCF.pmod b/lib/modules/_Image_XCF.pmod
index 5793b44da767e3a6e55e304faaf038ec515e5355..77bd97047a9c781987386ceaed43c61c74e9fa95 100644
--- a/lib/modules/_Image_XCF.pmod
+++ b/lib/modules/_Image_XCF.pmod
@@ -24,7 +24,7 @@ class Guide
   int vertical;
   void create(string data)
   {
-    sscanf(data, "%4c%c", pos,vertical);
+    sscanf(data, "%4c%c", pos,vertical);vertical--;
   }
 }
 
@@ -77,7 +77,8 @@ class Hierarchy
     height = y;
     bpp = bp;
     img = Image.image( x, y, 0,0,0 );
-    alpha = Image.image( x, y, 255,255,255 );
+    if(!(bp & 1 ))
+      alpha = Image.image( x, y, 255,255,255 );
     switch(compression)
     {
      case COMPRESS_NONE:
@@ -102,17 +103,22 @@ class Hierarchy
 
   Hierarchy copy()
   {
-    return Hierarchy()->qsi( img->copy(),alpha->copy(),width,height,bpp );
+    return Hierarchy()->qsi( img,alpha,width,height,bpp );
   }
 
   Hierarchy get_opaqued( int opaque_value )
   {
     Hierarchy res = copy();
     if(opaque_value != 255)
-      res->alpha *= opaque_value/255.0;
+    {
+      if(res->alpha)
+        res->alpha *= opaque_value/255.0;
+      else
+        res->alpha = Image.image(width,height,
+                                 opaque_value,opaque_value,opaque_value);
+    }
     return res;
   }
-
 }
 
 int iid;
@@ -121,14 +127,6 @@ Hierarchy decode_image_data( mapping what, object i )
   Hierarchy h = 
     Hierarchy( )->set_image(what->width, what->height, what->bpp,
                             what->tiles, i->compression, i->colormap );
-
-
-#if 0
-  object bg = Image.image( what->width, what->height )->test();
-  bg = bg->paste_mask( h->img, h->alpha );
-  rm("/tmp/xcftest_"+iid);
-  Stdio.write_file( "/tmp/xcftest_"+iid++, Image.PNM.encode( bg ));
-#endif
   return h;
 }
 
@@ -255,8 +253,6 @@ class Layer
   }
 }
 
-
-
 class GimpImage
 {
   int width;
@@ -269,8 +265,8 @@ class GimpImage
   int res_unit;
   Image.colortable colormap;
   Image.colortable meta_colormap;
-  array(Layer) layers = ({});
-  array(Channel) channels = ({});
+  array(Layer) layers = ({});            // bottom-to-top
+  array(Channel) channels = ({});       // unspecified order, really
   array(Guide) guides = ({});
   array(Parasite) parasites = ({});
   array(Path) paths = ({});
@@ -356,7 +352,9 @@ class GimpImage
          else
            meta_colormap = Image.colortable( p->data );
          break;
-       case PROP_COMPRESSION: compression = p->data[0];             break;
+       case PROP_COMPRESSION:
+         compression = p->data[0];
+         break;
        case PROP_GUIDES:
          guides = Array.map(p->data/5,Guide);
          break;
@@ -401,65 +399,175 @@ class GimpImage
 
 GimpImage __decode( string|mapping what )
 {
-  if(stringp(what))
-    what = ___decode( what );
+  if(stringp(what)) what = ___decode( what );
   return GimpImage(what);
 }
 
 
+#define PASTE_ALPHA(X,Y)                                                \
+        if(Y)                                                           \
+          img->paste_mask( X, Y, l->xoffset, l->yoffset );              \
+        else                                                            \
+          img->paste( X, l->xoffset, l->yoffset );                      \
+        if(Y&&alpha&&++alpha_used)                                      \
+          alpha->paste_alpha_color(Y,255,255,255,l->xoffset, l->yoffset ); \
+        else if(alpha)                                                 \
+         alpha->box(l->xoffset,l->yoffset,l->xoffset+l->width-1,l->yoffset+l->height-1,255,255,255)
+
+#define IMG_SLICE(l,h) img->copy(l->xoffset,l->yoffset,l->xoffset+h->width-1,l->yoffset+h->height-1)
+
 mapping _decode( string|mapping what, mapping|void opts )
 {
   if(!opts) opts = ([]);
-  mixed e=
-    catch {
+// array e=
+//   catch {
+  int alpha_used;
   GimpImage data = __decode( what );
   object img = Image.image(data->width, data->height, 
-                           @(opts->background||({255,255,255})));
-  object alpha = Image.image(data->width, data->height,
-                             @(opts->background?({255,255,255}):({0,0,0})));
+                           @((opts->background&&(array)opts->background)
+                             ||({255,255,255})));
+  object alpha;
+
+  if( !opts->background )
+    alpha = Image.image(data->width, data->height);
 
-  foreach(reverse(data->layers), object l)
+  foreach(data->layers, object l)
   {
-    if(l->flags->visible)
+    if(l->flags->visible || opts->draw_all_layers)
     {
       Hierarchy h = l->image->get_opaqued( l->opacity );
+      if(l->mask && l->flags->apply_mask)
+      {
+        if(l->image->alpha)
+          l->image->alpha *= l->mask->image;
+        else
+          l->image->alpha = l->mask->image;
+      }
+
+
       switch( l->mode )
       {
       case NORMAL_MODE:
-        img->paste_mask( h->img, h->alpha, l->xoffset, l->yoffset );
-        alpha->paste_alpha_color( h->alpha, 255,255,255, 
-                                  l->xoffset, l->yoffset );
+        PASTE_ALPHA(h->img,h->alpha);
         break;
-      case DISSOLVE_MODE:
-      case BEHIND_MODE:
+
+
       case MULTIPLY_MODE:
+        object oi = IMG_SLICE(l,h);
+        oi *= h->img;
+        PASTE_ALPHA(oi,h->alpha);
+        break;
+
+      case ADDITION_MODE:
+        object oi = IMG_SLICE(l,h);
+        oi += h->img;
+        PASTE_ALPHA(oi,h->alpha);
+        break;
+
+      case SUBTRACT_MODE:
+        object oi = IMG_SLICE(l,h);
+        oi -= h->img;
+        PASTE_ALPHA(oi,h->alpha);
+        break;
+
+      case DIVIDE_MODE:
+      case DISSOLVE_MODE:
       case SCREEN_MODE:
       case OVERLAY_MODE:
       case DIFFERENCE_MODE:
-      case ADDITION_MODE:
-      case SUBTRACT_MODE:
       case DARKEN_ONLY_MODE:
       case LIGHTEN_ONLY_MODE:
       case HUE_MODE:
       case SATURATION_MODE:
       case COLOR_MODE:
       case VALUE_MODE:
-      case DIVIDE_MODE:
-      case ERASE_MODE:
-      case REPLACE_MODE:
-        werror("More "+l->mode+" not yet implemented.\n");
+       default:
+        if(!opts->ignore_unknown_layer_modes)
+        {
+          werror("Layer mode "+l->mode+" not yet implemented,  "
+               " asuming 'normal'\n");
+          PASTE_ALPHA(h->img,h->alpha);
+        }
         break;
       }
     }
   }
 
+  if(opts->draw_guides)
+    foreach( data->guides, Guide g )
+      if(g->vertical)
+        img->line( g->pos, 0, g->pos, img->ysize(), 0,155,0 );
+      else
+        img->line( 0,g->pos,  img->xsize(),g->pos, 0,155,0 );
+
+  if(opts->draw_selection)
+  {
+    if(data->selection)
+      img->paste_alpha_color( data->selection->image_data->img*0.25,
+                              data->selection->r,
+                              data->selection->g,
+                              data->selection->b );
+  }
+
+  if(opts->mark_layers)
+  {
+    foreach(data->layers, Layer l)
+    {
+      if(l->flags->visible || opts->draw_all_layers)
+      {
+        int x1 = l->xoffset;
+        int x2 = l->xoffset+l->width;
+        int y1 = l->yoffset;
+        int y2 = l->yoffset+l->height;
+        img->setcolor(0,0,255,100);
+        img->line( x1,y1,x2,y1 );
+        img->line( x2,y1,x2,y2 );
+        img->line( x2,y2,x1,y2 );
+        img->line( x1,y2,x1,y1 );
+      }
+    }
+  }
+  
+  if(opts->mark_layer_names)
+  {
+    foreach(data->layers, Layer l)
+    {
+      if(l->flags->visible || opts->draw_all_layers)
+      {
+        int x1 = l->xoffset;
+        int y1 = l->yoffset+3;
+        object a = opts->mark_layer_names->write( l->name )->scale(0.5);
+        object i = Image.image( a->xsize(),a->ysize(), 100,0,0 );
+        img->paste_mask( a, i, x1, y1 );
+        if(alpha && ++alpha_used)                                      
+          alpha->paste_alpha_color(a,255,255,255, x1,y1 );
+      }
+    }
+  }
+
+  if(opts->mark_active_layer)
+  {
+    if(data->active_layer)
+    {
+      int x1 = data->active_layer->xoffset;
+      int x2 = data->active_layer->xoffset+data->active_layer->width;
+      int y1 = data->active_layer->yoffset;
+      int y2 = data->active_layer->yoffset+data->active_layer->height;
+      img->setcolor(255,0,0);
+      img->line( x1,y1,x2,y1 );
+      img->line( x2,y1,x2,y2 );
+      img->line( x2,y2,x1,y2 );
+      img->line( x1,y2,x1,y1 );
+    }
+  }
+  if(alpha && !alpha_used)
+    alpha=0;
   return ([
     "image":img,
     "alpha":alpha,
-    "gimpimage":data,
   ]);
-  };
-  werror(describe_backtrace(e));
+//   };
+//  werror(describe_backtrace(e)); 
 }