diff --git a/.gitattributes b/.gitattributes
index fd97dd4fc1c8cbe1c45be4deec5ea71a5e731b79..143260fc7bb54e576018114d16f8d301b8036bfb 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -220,6 +220,7 @@ testfont binary
 /src/modules/Image/encodings/pnm.c foreign_ident
 /src/modules/Image/encodings/psd.c foreign_ident
 /src/modules/Image/encodings/tga.c foreign_ident
+/src/modules/Image/encodings/wbf.c foreign_ident
 /src/modules/Image/encodings/x.c foreign_ident
 /src/modules/Image/encodings/xbm.c foreign_ident
 /src/modules/Image/encodings/xcf.c foreign_ident
diff --git a/src/modules/Image/encodings/Makefile.in b/src/modules/Image/encodings/Makefile.in
index 1d63bf79fe14664603eb0b6c8e7b259e7521b707..cdd40dc2b6e81e693b76d1bfbd1a5054cefaf58d 100644
--- a/src/modules/Image/encodings/Makefile.in
+++ b/src/modules/Image/encodings/Makefile.in
@@ -1,7 +1,7 @@
-# $Id: Makefile.in,v 1.26 1999/05/23 17:46:47 mirar Exp $
+# $Id: Makefile.in,v 1.27 1999/10/21 22:18:44 per Exp $
 SRCDIR=@srcdir@
 VPATH=@srcdir@:@srcdir@/../../..:../../..
-OBJS = gif.o gif_lzw.o pnm.o x.o xwd.o png.o any.o bmp.o tga.o pcx.o xbm.o _xpm.o ilbm.o iff.o xcf.o hrz.o avs.o psd.o gd.o
+OBJS = gif.o gif_lzw.o pnm.o x.o xwd.o png.o any.o bmp.o tga.o pcx.o xbm.o _xpm.o ilbm.o iff.o xcf.o hrz.o avs.o psd.o gd.o wbf.o
 
 @SET_MAKE@
 
diff --git a/src/modules/Image/encodings/wbf.c b/src/modules/Image/encodings/wbf.c
new file mode 100644
index 0000000000000000000000000000000000000000..93c6b6228ffe81f8a2dd9bd26dac8870e74d1ece
--- /dev/null
+++ b/src/modules/Image/encodings/wbf.c
@@ -0,0 +1,390 @@
+#include "global.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "stralloc.h"
+RCSID("$Id: wbf.c,v 1.1 1999/10/21 22:18:44 per Exp $");
+#include "pike_macros.h"
+#include "object.h"
+#include "mapping.h"
+#include "constants.h"
+#include "interpret.h"
+#include "operators.h"
+#include "svalue.h"
+#include "threads.h"
+#include "array.h"
+#include "error.h"
+#include "builtin_functions.h"
+
+
+#include "image.h"
+#include "builtin_functions.h"
+#include "module_support.h"
+
+extern struct program *image_program;
+
+/*
+**! module Image
+**! submodule WBF
+**!   WAP WBF format
+*/
+
+struct buffer
+{
+  unsigned int len;
+  unsigned char *str;
+};
+
+struct ext_header
+{
+  struct ext_header *next;
+  char name[8];
+  char value[16];
+  char name_len;
+  char value_len;
+};
+
+struct wbf_header
+{
+  unsigned int width;
+  unsigned int height;
+  int type;
+  int header;
+  int fix_header_field;
+  int ext_header_field;
+  struct ext_header *first_ext_header;
+};
+
+static void read_string( struct buffer *from, unsigned int len, char *to )
+{
+  if( from->len < len )
+    error("Invalid data format\n");
+  MEMCPY( from->str, to, len );
+  from->str += len;
+  from->len -= len;
+}
+
+static unsigned char read_uchar( struct buffer *from )
+{
+  unsigned char res = 0;
+  if(from->len)
+  {
+    res = from->str[0];
+    from->str++;
+    from->len--;
+  } else
+    error("Invalid data format\n");
+  return res;
+}
+
+static int read_int( struct buffer *from )
+{
+  int res = 0;
+  while( 1 )
+  {
+    int i = read_uchar( from );
+    res <<= 8;
+    res |= i&0x7f;
+    if( !(res & 0x80 ) )
+      break;
+  }
+  return res;
+}
+
+static void push_ext_header( struct ext_header *eh )
+{
+  push_constant_text( "identifier" );
+  push_string( make_shared_binary_string( eh->name, eh->name_len ) );
+  push_constant_text( "value" );
+  push_string( make_shared_binary_string( eh->value, eh->value_len ) );
+  f_aggregate_mapping( 4 );
+}
+
+static struct wbf_header decode_header( struct buffer *data )
+{
+  struct wbf_header res;
+  MEMSET( &res, 0, sizeof(res) );
+  res.type = read_int( data );
+  res.fix_header_field = read_uchar( data );
+  if( res.fix_header_field & 0x80 )
+  {
+    switch( (res.fix_header_field>>5) & 0x3 )
+    {
+     case 0: /* Single varint extra header */
+       res.ext_header_field = read_int( data );
+       break;
+     case 1: /* reserved */
+     case 2: /* reserved */
+     case 3: /* Array of parameter/value */
+       {
+         int q = 0x80;
+         
+         while( q & 0x80 )
+         {
+           struct ext_header *eh;
+           q = read_uchar( data );
+           eh = malloc( sizeof( struct ext_header ) );
+           MEMSET( eh, 0, sizeof( struct ext_header ) );
+           eh->name_len = ((q>>4) & 0x7) + 1;
+           eh->value_len = (q & 0xf) + 1;
+           read_string( data, eh->name_len, eh->name );
+           read_string( data, eh->value_len, eh->value );
+           eh->next = res.first_ext_header;
+           res.first_ext_header = eh->next;
+         }
+       }
+    }
+  }
+  res.width = read_int( data );
+  res.height = read_int( data );
+  return res;
+}
+
+static void free_wbf_header_contents( struct wbf_header *wh )
+{
+  while( wh->first_ext_header )
+  {
+    struct ext_header *eh = wh->first_ext_header;
+    wh->first_ext_header = eh->next;
+    free( eh );
+  }
+}
+
+
+static void low_image_f_wbf_decode_type0( struct wbf_header *wh,
+                                          struct buffer *buff )
+{
+  unsigned int x, y;
+  struct image *i;
+  struct object *io;
+  unsigned int rowsize = (wh->width+7) / 8;
+  rgb_group white;
+  rgb_group *id;
+  push_int( wh->width );
+  push_int( wh->height );
+  io = clone_object( image_program, 2 );
+  i = (struct image*)get_storage(io,image_program);
+  id = i->img;
+
+  white.r = 255;
+  white.g = 255;
+  white.b = 255;
+  
+  for( y = 0; y<wh->height; y++ )
+  {
+    unsigned char q = 0; /* avoid warning */
+    unsigned char *data = buff->str + y * rowsize;
+    if( buff->len < (rowsize+1)*y )
+      break;
+    for( x = 0; x<wh->width; x++ )
+    {
+      if( !(x % 8) )
+        q = data[x/8];
+      else
+        q = (q<<1) | (q>>7);
+      if( q & 128 )
+        *id = white;
+      id++;
+    }
+  }
+  push_object( io );
+}
+
+static void low_image_f_wbf_decode( int args, int mode )
+{
+  struct pike_string *s;
+  struct wbf_header wh;
+  int map_num_elems = 0;
+  struct buffer buff;
+
+  get_all_args( "decode", args, "%S", &s );
+
+  buff.len = s->len;
+  buff.str = s->str;
+  sp--; /* Evil me */
+
+  wh = decode_header( &buff );
+
+  switch( wh.type )
+  {
+   case 0: 
+     /* 
+        The only supported format. B/W uncompressed bitmap 
+      
+         No compresson.
+         Colour: 1 = white, 0 = black.
+         Depth: 1 bit.
+         high bit = rightmost.
+         first byte is upper left corner of image.
+         each row is padded to one byte
+      */
+     switch( mode )
+     {
+      case 2: /* Image only */
+        low_image_f_wbf_decode_type0( &wh, &buff );
+        return;
+
+      case 1: /* Image and header */
+        push_constant_text( "image" );
+        low_image_f_wbf_decode_type0( &wh, &buff );
+        map_num_elems++;
+        
+      case 0: /* Header only */
+        push_constant_text( "format" );
+        push_constant_text( "image/x-wap.wbmp; type=0" );
+        map_num_elems++;
+        
+        push_constant_text( "xsize" );
+        push_int( wh.width );
+        map_num_elems++;
+
+        push_constant_text( "ysize" );
+        push_int( wh.height );
+        map_num_elems++;
+
+        if( wh.fix_header_field )
+        {
+          push_constant_text( "fix_header_field" );
+          push_int( wh.fix_header_field );
+          map_num_elems++;
+        }
+
+        if( wh.ext_header_field )
+        {
+          push_constant_text( "ext_header_field" );
+          push_int( wh.ext_header_field );
+          map_num_elems++;
+        }
+        
+        if( wh.first_ext_header )
+        {
+          int num_headers = 0;
+          struct ext_header *eh = wh.first_ext_header;
+          while( eh )
+          {
+            push_ext_header( eh );
+            eh = eh->next;
+            num_headers++;
+          }
+          f_aggregate( num_headers );
+          f_reverse( 1 );
+          map_num_elems++;
+        }
+        f_aggregate_mapping( map_num_elems * 2 );
+     }
+     free_string( s );
+     free_wbf_header_contents( &wh );
+     break;
+
+   default:
+     free_string( s );
+     free_wbf_header_contents( &wh );
+
+     error("Unsupported wbf image type.\n");
+  }
+}
+
+static void image_f_wbf_decode( int args )
+{
+  low_image_f_wbf_decode( args, 2 );
+}
+
+static void image_f_wbf__decode( int args )
+{
+  low_image_f_wbf_decode( args, 1 );
+}
+
+static void image_f_wbf_decode_header( int args )
+{
+  low_image_f_wbf_decode( args, 0 );
+}
+
+void push_wap_integer( int i )
+{
+  char data[6];
+  int pos = 0;
+  while( i > 0x7f )
+  {
+    data[5-pos] = i&0x7f;
+    i>>=8; pos++;
+  }
+  data[5-pos] = i;
+  push_string( make_shared_binary_string( data+5-pos, pos+1 ) );
+}
+
+static void push_wap_type0_image_data( struct image *i )
+{
+  int x, y;
+  unsigned char *data, *p;
+  rgb_group *is;
+  data = malloc( i->ysize * (i->xsize+7)/8 );
+  MEMSET( data, 0, i->ysize * (i->xsize+7)/8 );
+  is = i->img;
+  for( y = 0; y<i->ysize; y++ )
+  {
+    p = data + (i->xsize+7)/8*y;
+    for( x = 0; x<i->xsize; x++ )
+    {
+      if( is->r || is->g || is->b )
+        p[x/8] |= 128 >> (x%8);
+      is++;
+    }
+    printf("\n");
+  }
+  push_string( make_shared_binary_string( data, i->ysize * (i->xsize+7)/8 ) );
+}
+
+static void image_f_wbf_encode( int args )
+{
+  struct object *o;
+  struct image *i;
+  struct mapping *options = NULL;
+  int num_strings = 0;
+
+  if( !args )
+    error("No image given to encode.\n");
+  if( args > 2 )
+    error("Too many arguments to encode.\n");
+  if( sp[-args].type != T_OBJECT )
+    error("No image given to encode.\n");
+
+  o = sp[-args].u.object;
+  i = (struct image*)get_storage(o,image_program);
+  if(!i)
+    error("Wrong type object argument\n");
+  if( args == 2 )
+  {
+    if( sp[-args+1].type != T_MAPPING )
+      error("Wrong type for argument 2.\n");
+    options = sp[-args+1].u.mapping;
+  }
+  sp-=args;
+
+  num_strings=0;
+  push_wap_integer( 0 ); num_strings++; /* type */
+  push_wap_integer( 0 ); num_strings++; /* extra header */
+  push_wap_integer( i->xsize ); num_strings++; 
+  push_wap_integer( i->ysize ); num_strings++; 
+  push_wap_type0_image_data( i ); num_strings++;
+  f_add( num_strings );
+  if( options ) free_mapping( options );
+  free_object( o );
+}
+
+void init_image_wbf()
+{
+  add_function( "encode", image_f_wbf_encode, 
+                "function(object,void|mapping:string)", 0);
+  add_function( "_encode", image_f_wbf_encode, 
+                "function(object,void|mapping:string)", 0);
+  add_function( "decode", image_f_wbf_decode, "function(string:object)", 0);
+  add_function( "_decode", image_f_wbf__decode, "function(string:mapping)", 0);
+  add_function( "decode_header", image_f_wbf_decode_header, 
+                "function(string:mapping)", 0);
+}
+
+void exit_image_wbf()
+{
+}